When you set the "value" attribute of a SELECT, it then sets the
"_selected" attribute of the associated OPTION to "selected" (and the
"_selected" attribute of all other OPTIONs to None). In this case, you have
passed the same list of OPTIONs to each SELECT. The list of OPTIONs is
mutable, and the attributes of each OPTION are mutable as well, so each
call to SELECT iterates over the same three OPTION objects and mutates
their attributes (changing the values of the "_selected" attributes each
time). So, all three SELECTs end up with the same selected option as the
third (and final) SELECT.
To get this to work, you need to deepcopy the list of OPTIONs (so it copies
not only the OPTION objects, but also the attributes within each OPTION):
from copy import deepcopy
form = FORM(
SELECT(_name='first', *deepcopy(items), value=request.vars[
'first'] or None),
SELECT(_name='second', *deepcopy(items), value=request.vars[
'second'] or None),
SELECT(_name='third', *deepcopy(items), value=request.vars[
'third'] or None),
INPUT(_type='submit')
)
Or you can use some other means to generate separate lists of items, such
as writing a function that returns a new list each time it is called.
In general, you have to be careful when you re-use mutable objects. In this
case, the problem is that the mutation (i.e., setting the "_selected"
attribute of each OPTION) happens for all three SELECTs before each SELECT
is serialized into HTML -- so when the form is serialized, all three
SELECTS are serialized with the final set of mutations.
Anthony
On Tuesday, June 4, 2013 1:33:36 AM UTC-4, rppowell wrote:
>
> Hello;
>
> I am using SELECT in a FORM and I noticed this behavior.
>
> Using the following in a controller, such as default.py:
>
> def selector_test():
> items = [
> OPTION('One', _value=1),
> OPTION('Two', _value=2),
> OPTION('Three', _value=3),
> ]
>
> form = FORM(
> SELECT(_name='first', *items, value=request.vars['first'] or
> None),
> SELECT(_name='second', *items, value=request.vars['second'] or
> None),
> SELECT(_name='third', *items, value=request.vars['third'] or
> None),
> INPUT(_type='submit')
> )
> if form.accepts(request, session):
> response.flash = 'form processed'
> elif form.errors:
> response.flash = 'error!'
> else:
> response.flash = 'enter form'
>
> return dict(form=form, vars=form.vars)
>
>
> When I go to that page, I see the following selectors:
> [ One ] [ One ] [ One ]
>
> When I set the value to so:
> [ One ] [ Two ] [ Three ]
>
> And click submit, I observe the following:
>
> The vars in the request is:
> vars:first:1second:2third:3
> But, the SELECT display:
> [ Three ] [ Three ] [ Three ]
>
>
> I observe the same behavior is I use value or _value, on Chrome 26 and
> Firefox 19 / Mac OSX.
> What can I do to have the SELECT display the value from the form.vars?
>
> Thank you for your time;
>
> -Rob Powell
>
--
---
You received this message because you are subscribed to the Google Groups
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.