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" <[email protected]> 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 <[email protected]> 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