Weird SQLFORM form.errors "no data"

33 views
Skip to first unread message

Leonel Câmara

unread,
Apr 5, 2016, 6:26:12 PM4/5/16
to web2py-users
So I'm trying to use SQLFORM with a custom widget I made to pick icons for categories. I'm getting this weird error I can't understand, where the form always says it has errors:

print request.post_vars # before form.process().accepted

<Storage {'category_name_en': 'test', 'category_name_pt': 'teste', '_formkey': '8c8e2501-d5d5-458e-aed6-0f775076061a', 'icon': 'fa-adjust', '_formname': 'category/create', 'name': '{"en":"test","pt":"teste"}'}>

Then if form.errors (which always happens right now) I print form.vars

<Storage {'published': None, 'category_name_en': 'test', 'category_name_pt': 'teste', 'name': {u'en': u'test', u'pt': u'teste'}}>

and form.errors:

<Storage {'icon': 'no data'}>


What's weird about this, to me, is that 'icon' is clearly there in request.post_vars but it's somehow being eliminated during process. Anyone have any ideas?

Dave S

unread,
Apr 5, 2016, 6:34:31 PM4/5/16
to web2py-users
Maybe when _formkey and _formname are removed?

/dps
 

Leonel Câmara

unread,
Apr 5, 2016, 6:45:10 PM4/5/16
to web2py-users
formkey and formname are just not placed in form.vars, what I can't understand is why 'icon' is not being placed there too, and then I get that annoying "no data" error when I clearly provided the data. 

Dave S

unread,
Apr 5, 2016, 7:11:02 PM4/5/16
to web2py-users
On Tuesday, April 5, 2016 at 3:45:10 PM UTC-7, Leonel Câmara wrote:
formkey and formname are just not placed in form.vars, what I can't understand is why 'icon' is not being placed there too, and then I get that annoying "no data" error when I clearly provided the data. 
 
Does the copy from post.vars to form.vars involve knowing what fields are expected?  Is the icon field included in what's expected?

/dps

Leonel Câmara

unread,
Apr 5, 2016, 7:36:36 PM4/5/16
to web...@googlegroups.com
Yes the table has an icon field, to make sure that's not the problem I tried calling SQLFORM specifying the fields parameter ['name', 'icon'] and I had exactly the same error.

Frankly it's hard to trace how FORM instances fill self.vars but I think I'm finally understanding my problem after a long time looking at html.py code as this wasn't intuitive at all. 

My input which generates the icon was created using javascript, so there's no INPUT helper in the form to _validate. Yes that's right, apparently form.vars is filled by the INPUTs in the FORM, not by the FORM itself.

Meh, this is highly annoying... I can actually make it work by simply doing this before processing

form.components.append(INPUT(_type='hidden', _name='icon'))

Which looks totally horrible and nonsensical to any programmer reading the code. This is bullshit...


[edit] Dave thanks for trying, this back and forth actually helped.

Leonel Câmara

unread,
Apr 5, 2016, 7:52:56 PM4/5/16
to web2py-users
If anyone is interested in the widget that was causing this problem and how it looks with the fix here you go. All those imports it's because I have it in a module called plugin_iconpicker.py

# -*- coding: utf-8 -*-
"""
Iconpicker using:
http://victor-valencia.github.io/bootstrap-iconpicker/

Requires bootstrap-iconpicker.css bootstrap-iconpicker.js and the CSS, fonts
and js iconset files for whatever icons you want to have available as they 
aren't packaged with the plugin. 
"""
from gluon.html import CAT, TAG, SCRIPT, INPUT
from gluon.sqlhtml import FormWidget
from gluon import current

ICONSETS = ['fontawesome']

class IconPickerWidget(FormWidget):
    _class = 'string'

    @classmethod
    def widget(cls, field, value, **attributes):
        """
        Generates an icon picker widget.
        """

        default = dict(
            value=(value is not None and str(value)) or '',
        )
        attr = cls._attributes(field, default, **attributes)

        _id = attr['_id']
        _name = attr['_name']

        button = TAG.button(_name=attr['_name'], _id=_id, _type='button', _class='btn btn-default') 

        script = SCRIPT("""
                        $(document).ready(function(){$('#%(_id)s').iconpicker({icon:'%(icon)s', iconset: '%(iconset)s'});});
                        """ % { '_id': _id, 'icon': value or '', 'iconset': '|'.join(ICONSETS)})

        # The next 3 lines are here to deal with the idiotic way form.vars is filled in web2py
        result = CAT(button, script)
        if current.request.post_vars:
            result.components.append(INPUT(_type='hidden', _name='icon', _value=value))

        return result
Reply all
Reply to author
Forward
0 new messages