After some more poking around with winpdb (a marvelously useful tool, IMO), it looks like the cleanest way to get the web2py mangled id of a form.custom.widget named 'foo' is:
id = form.custom.widget.foo.['_id'] or equivalently, id = form.custom.widget['foo']['_id'] The following do *not* work: id = form.custom.widget.foo.id id = form.custom.widget._id So my final version of the view code to install a ckeditor instance now looks like {{ textarea = form.custom.widget.edited textarea_id = textarea['_id'] }} <li class=edititem>{{=textarea}}</li> <script type="text/javascript"> CKEDITOR.replace('{{=textarea_id}}', { toolbar : 'Basic', }); </script> which is slightly more verbose but feels more satisfying since it only requires me to know that I named my field 'edited' when I created the form. On Jul 16, 10:50 pm, MikeEllis <michael.f.el...@gmail.com> wrote: > Solved the problem, though I'm still not quite sure what was wrong to > begin with. I did away with using a custom widget to install the > ckeditor and handled it in the view instead: > > <li>{{=form.custom.widget.edited}}</li> > <script type="text/javascript"> > CKEDITOR.replace("no_table_edited", { > toolbar : 'Basic', > }); > </script> > > It feels icky to have to know about web2py's element naming > conventions. I suspect there must be a way to get the id > programmatically but the obvious things like form.custom.widget.id > didn't work. > > I did have to make one change to my Field declaration; it wouldn't > work while the type was 'string'. Changing it to 'text' did the > trick. That may have been part of the original problem. > > Many thanks to Mr. Freeze for an email exchange that helped in > diagnosing the problem -- on a Friday evening no less! > > On Jul 16, 6:26 pm, "mr.freeze" <nat...@freezable.com> wrote: > > > > > Do you get the same behavior when removing the ckeditor widget from > > the field? Your validator worked for me and the __call__ method was > > hit. > > > On Jul 16, 5:07 pm, MikeEllis <michael.f.el...@gmail.com> wrote: > > > > I've got a controller that presents the user with a ckeditor field > > > that lets them use a limited set of html markup. The editor returns > > > an empty paragraph if they press Submit without typing anything, ie, > > > '<p></p>' , and my app needs to reject that. So I wrote a custom > > > validator as follows: > > > > _striptags = re.compile(r'<[^<]*?/?>') > > > _nbsp = re.compile(r' ') > > > > def isEmptyHtml(text): > > > """ Checks to see if text is empty after removing > > > HTML tags and leading/trailing whitespace incl. newlines. > > > """ > > > t = _striptags.sub('',text) > > > return 0 == len(_nbsp.sub('',t).strip()) > > > > class IS_NOT_EMPTY_HTML(Validator): > > > def __init__(self, error_message='Enter some text'): > > > debug('in __init__') > > > self.error_message = error_message > > > > def __call__(self, value): > > > debug('value=%s'%value) > > > if isEmptyHtml(value): > > > debug('empty!') > > > return (value, self.error_message) > > > else: > > > debug('not empty') > > > return (value, None) > > > > It's a little ugly, but it seems to do what I need and appears to work > > > correctly when I test it on the command line. > > > > Now here's the problem. When I try to use it in a form, an instance > > > gets assigned to the field but the instance never gets called. I see > > > the log message from the __init__() method, but never the one from the > > > __call__() method. My controller is shown below. > > > > def edititem(): > > > ---- <snip> ------ > > > fields = [Field("edited", 'string', default=itemtext, > > > requires=IS_NOT_EMPTY_HTML(), > > > widget=ckeditor_basic, > > > ) > > > ] > > > form = SQLFORM.factory(*fields) > > > if form.accepts(request.vars, session): > > > session.flash = 'Edit accepted.' > > > ----- etc ---- > > > > This one's really got me stumped. That usually means I've done > > > something brain dead and just can't see it. > > > > I've spent over an hour carefully stepping into the calls with winpdb > > > and inspecting the variables along the way. > > > > I've verified that > > > - field.requires ends up containing an <IS_NOT_EMPTY_HTML object > > > > - the object is valid. I'm able to eval it in winpdb command line > > > with empty and non-empty strings. > > > > I got kind of lost stepping through form.accepts and FORM.accepts in > > > sqlhtml.py but so far haven't spotted the place where it decides not > > > to call the requires method. What am I doing wrong? FWIW I'm > > > running web2py 1.92. > > > > Thanks, > > > Mike