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'&nbsp;')
>
> > > 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

Reply via email to