custom widget - why is value empty even though it was set with form.vars.fieldname = something?

29 views
Skip to first unread message

Toby

unread,
Nov 22, 2016, 4:52:14 PM11/22/16
to web2py-users
I'm having an issue where "value" is empty inside my custom widget. I have a field in my database that uses a custom dropdown widget:

Field('color_scheme', 'string', requires=IS_IN_SET(color_schemes.COLOR_SCHEME_NAMES),
          widget=color_choice_widget),

I create a form using form=SQLFORM(...) and then I set the default value of the color_scheme with:
form.vars.color_scheme = DEFAULT_COLOR_SCHEME

In my custom widget, I want to read the current value so that I can apply certain styling to the selected value in the dropdown. But value=None inside my widget. Any idea what's going on?

The custom dropdown widget is something like this:
def color_choice_widget(field, value):
    """
    Widget for the color scheme dropdown menu
    """
    print value # Why does this print "None"?
    return \
        DIV(
            # This DL is what the user sees
            TAG['dl'](
                <more stuff here>,
                _class="dropdown", _id="color_dropdown",
            ),
            # This hidden INPUT is what actually gets submitted, and has value set by javascript
            INPUT(_name=field.name,
                  _class=field.type,
                  _id="%s_%s" % (field._tablename, field.name),
                  _value=value,
                  requires=field.requires)
        )

Thanks in advance for any advice on what I'm missing

Toby

Leonel Câmara

unread,
Nov 22, 2016, 4:59:49 PM11/22/16
to web2py-users
That should work, it's probably a bug with the javascript code you're using to set the hidden input which isn't doing its job.

Toby

unread,
Nov 23, 2016, 4:35:22 AM11/23/16
to web2py-users
It's more than just the javascript, because even printing value from within my widget prints None, and that's before the form is rendered on the page. 

I think I figured out what's going on. There are two ways of setting a default on the fly (https://groups.google.com/d/msg/web2py/Bri0SBe9_pg/ErQrPSIc2LMJ)

1. Before creating the FORM object you can do
db.table.my_field.default = "my_default"
In this case, the value passed to a widget is "my_default"

2. After creating the FORM but before it form.accepts, you can do
form.vars.my_field = "my_default"
In this case, "my_default" doesn't get passed into the widget as value. 

In the 2nd way, I don't fully understand what's going on behind the scenes. Somehow the act of calling form.accepts populates the default into the form, but without calling the widget again. I'm guessing that it looks at the FORM object, finds the element with the id matching my_field, and inserts "my_field" as the value in that element.

Anyway, I guess the take-home message is that if I want my widget to apply custom styling based on a default set on the fly, I should use method 1 above, i.e. db.table.my_field.default = "my_default" 

Reply all
Reply to author
Forward
0 new messages