Very interesting explanation, but it still seems obscure and not the kind
of thing the average user would consider. Isn't there an easier way to
make this work as expected?
For example, shouldn't differently named SELECTs be parsed independently
from each other?
On Tuesday, 4 June 2013 14:19:28 UTC+1, Anthony wrote:
>
> 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.