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.


Reply via email to