Skip to content

Commit

Permalink
Refactor selection [ticket:19]
Browse files Browse the repository at this point in the history
  • Loading branch information
paj committed Jul 1, 2010
1 parent 6c83fa0 commit 5c7e4de
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 19 deletions.
6 changes: 3 additions & 3 deletions tests/test_widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,15 +114,15 @@ class TestSingleSelectField(WidgetTest):
widget = SingleSelectField
attrs = {'css_class':'something',
'options':((1, 'a'), (2, 'b'), (3, 'c')), 'id':'hid',
'item_validator':IntValidator(),
'validator':IntValidator(),
}
expected = """<select class="something" id="hid" name="hid">
<option></option>
<option value="1">a</option>
<option value="2">b</option>
<option value="3">c</option>
</select>"""
validate_params = [[None, {'hid':'b'}, None],[None, {'hid':'1'}, 1]]
validate_params = [[None, {'hid':''}, None],[None, {'hid':'1'}, 1]]

def test_option_group(self):
expected = """<select class="something">
Expand Down Expand Up @@ -688,4 +688,4 @@ def test_request_post_valid(self):

self.mw.config.debug = True
r = self.widget().request(req)
assert r.body == """Form posted successfully {'field2': 'b', 'field3': 'c', 'field1': 'a'}""", r.body
assert r.body == """Form posted successfully {'field2': u'b', 'field3': u'c', 'field1': u'a'}""", r.body
34 changes: 18 additions & 16 deletions tw2/forms/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,15 @@ class SelectionField(FormField):
"""
Base class for single and multiple selection fields.
The `options` parameter must be an interable; it can take several formats:
The `options` parameter must be a list; it can take several formats:
* A list of values, e.g. ['', 'Red', 'Blue']
* A list of (code, value) tuples, e.g.
[(0, ''), (1, 'Red'), (2, 'Blue')]
* A mixed list of values and tuples. If the code is not specified, it
defaults to the value. e.g. ['', (1, 'Red'), (2, 'Blue')]
* Attributes can be passed to individual items, e.g.
[(0, ''), (1, 'Red', {'style':'background-color:red'})]
* A list of groups, e.g.
[('group', ['', (1, 'Red'), (2, 'Blue')]),
('group2', ['', 'Pink', 'Yellow'])]
Expand All @@ -193,6 +195,11 @@ def prepare(self):
value = []
if self.multiple and not isinstance(value, (list, tuple)):
value = [value,]
if not hasattr(self, '_validated'):
if self.multiple:
value = [unicode(self.item_validator.from_python(v)) for v in value]
else:
value = unicode(value)
for optgroup in self._iterate_options(self.options):
xxx = []
if isinstance(optgroup[1], (list,tuple)):
Expand All @@ -204,9 +211,8 @@ def prepare(self):
for option in self._iterate_options(optlist):
if len(option) is 2:
option_attrs = {}
# when is the option length going to be 3 according to the spec?
#elif len(option) is 3:
# option_attrs = dict(option[2])
elif len(option) is 3:
option_attrs = dict(option[2])
option_attrs['value'] = option[0]
if self.field_type:
option_attrs['type'] = isinstance(self.field_type, basestring) and self.field_type or None
Expand All @@ -215,15 +221,15 @@ def prepare(self):
option_attrs['id'] = self.compound_id + ':' + str(counter.next())

#handle default_selected value
if ((self.multiple and self.default_selected and option[0] in self.default_selected) or
(not self.multiple and self.default_selected and option[0] == self.default_selected)):
optv = unicode(option[0])
if ((self.multiple and self.default_selected and optv in self.default_selected) or
(not self.multiple and self.default_selected and optv == self.default_selected)):
option_attrs[self.selected_verb] = self.selected_verb

#override if the widget was given an actual value
if ((self.multiple and option[0] in value) or
(not self.multiple and option[0] == value)):
#override if the widget was given an actual value
if ((self.multiple and optv in value) or
(not self.multiple and optv == value)):
option_attrs[self.selected_verb] = self.selected_verb

xxx.append((option_attrs, unicode(option[1])))
options.extend(xxx)
if group:
Expand All @@ -241,17 +247,13 @@ def _validate(self, value):
in a way that will never raise an exception, before calling the main
validator.
"""
value = super(SelectionField, self)._validate(value)
if self.multiple:
if isinstance(value, basestring):
value = [value,]
value = [twc.safe_validate(self.item_validator, v) for v in (value or [])]
value = [v for v in value if v is not twc.Invalid]
else:
value = twc.safe_validate(self.item_validator, value)
self.value = value
if value is twc.Invalid:
value = None
return super(SelectionField, self)._validate(value)
return value

def _iterate_options(self, optlist):
for option in optlist:
Expand Down

0 comments on commit 5c7e4de

Please sign in to comment.