Browse files

Fixed #3870, Refs #3787 -- Fixed handling of widget attributes on Rad…

…ioSelect and MultiWidget. In particular, handling of the id attribute has been fixed. Thanks to Gary Wilson and Max Derkachev.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@5065 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
1 parent 39aa40d commit 56b8914eb968ad49d3a15a98cec65fec849e1227 @freakboy3742 freakboy3742 committed Apr 24, 2007
Showing with 41 additions and 4 deletions.
  1. +15 −4 django/newforms/widgets.py
  2. +26 −0 tests/regressiontests/forms/tests.py
View
19 django/newforms/widgets.py
@@ -260,8 +260,8 @@ def render(self, name, value, attrs=None, choices=()):
"Returns a RadioFieldRenderer instance rather than a Unicode string."
if value is None: value = ''
str_value = smart_unicode(value) # Normalize to string.
- attrs = attrs or {}
- return RadioFieldRenderer(name, str_value, attrs, list(chain(self.choices, choices)))
+ final_attrs = self.build_attrs(attrs)
+ return RadioFieldRenderer(name, str_value, final_attrs, list(chain(self.choices, choices)))
def id_for_label(self, id_):
# RadioSelect is represented by multiple <input type="radio"> fields,
@@ -327,14 +327,25 @@ def render(self, name, value, attrs=None):
if not isinstance(value, list):
value = self.decompress(value)
output = []
+ final_attrs = self.build_attrs(attrs)
+ id_ = final_attrs.get('id', None)
for i, widget in enumerate(self.widgets):
try:
widget_value = value[i]
- except KeyError:
+ except IndexError:
widget_value = None
- output.append(widget.render(name + '_%s' % i, widget_value, attrs))
+ if id_:
+ final_attrs = dict(final_attrs, id='%s_%s' % (id_, i))

@freakboy3742 I know this commit is way old. However wonder about this line:

final_attrs = dict(final_attrs, id='%s_%s' % (id_, i))

Any reason to make a copy of the dict, instead of just update it?

final_attrs['id'] = '%s_%s' % (id_, i)

My guess is that final_attrs might be kind of an immutable dictionnary somehow, but I can't see how. Do you remember, by chance, why you did so and thus fulfill my curiosity?

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ output.append(widget.render(name + '_%s' % i, widget_value, final_attrs))
return self.format_output(output)
+ def id_for_label(self, id_):
+ # See the comment for RadioSelect.id_for_label()
+ if id_:
+ id_ += '_0'
+ return id_
+ id_for_label = classmethod(id_for_label)
+
def value_from_datadict(self, data, name):
return [data.get(name + '_%s' % i) for i in range(len(self.widgets))]
View
26 tests/regressiontests/forms/tests.py
@@ -658,10 +658,31 @@
...
IndexError: list index out of range
+# Unicode choices are correctly rendered as HTML
>>> w = RadioSelect()
>>> unicode(w.render('email', 'ŠĐĆŽćžšđ', choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')]))
u'<ul>\n<li><label><input checked="checked" type="radio" name="email" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" /> \u0160\u0110abc\u0106\u017d\u0107\u017e\u0161\u0111</label></li>\n<li><label><input type="radio" name="email" value="\u0107\u017e\u0161\u0111" /> abc\u0107\u017e\u0161\u0111</label></li>\n</ul>'
+# Attributes provided at instantiation are passed to the constituent inputs
+>>> w = RadioSelect(attrs={'id':'foo'})
+>>> print w.render('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
+<ul>
+<li><label><input checked="checked" type="radio" id="foo_0" value="J" name="beatle" /> John</label></li>
+<li><label><input type="radio" id="foo_1" value="P" name="beatle" /> Paul</label></li>
+<li><label><input type="radio" id="foo_2" value="G" name="beatle" /> George</label></li>
+<li><label><input type="radio" id="foo_3" value="R" name="beatle" /> Ringo</label></li>
+</ul>
+
+# Attributes provided at render-time are passed to the constituent inputs
+>>> w = RadioSelect()
+>>> print w.render('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')), attrs={'id':'bar'})
+<ul>
+<li><label><input checked="checked" type="radio" id="bar_0" value="J" name="beatle" /> John</label></li>
+<li><label><input type="radio" id="bar_1" value="P" name="beatle" /> Paul</label></li>
+<li><label><input type="radio" id="bar_2" value="G" name="beatle" /> George</label></li>
+<li><label><input type="radio" id="bar_3" value="R" name="beatle" /> Ringo</label></li>
+</ul>
+
# CheckboxSelectMultiple Widget ###############################################
>>> w = CheckboxSelectMultiple()
@@ -783,6 +804,11 @@
u'<input type="text" class="big" value="john" name="name_0" /><br /><input type="text" class="small" value="lennon" name="name_1" />'
>>> w.render('name', 'john__lennon')
u'<input type="text" class="big" value="john" name="name_0" /><br /><input type="text" class="small" value="lennon" name="name_1" />'
+>>> w.render('name', 'john__lennon', attrs={'id':'foo'})
+u'<input id="foo_0" type="text" class="big" value="john" name="name_0" /><br /><input id="foo_1" type="text" class="small" value="lennon" name="name_1" />'
+>>> w = MyMultiWidget(widgets=(TextInput(attrs={'class': 'big'}), TextInput(attrs={'class': 'small'})), attrs={'id': 'bar'})
+>>> w.render('name', ['john', 'lennon'])
+u'<input id="bar_0" type="text" class="big" value="john" name="name_0" /><br /><input id="bar_1" type="text" class="small" value="lennon" name="name_1" />'
# SplitDateTimeWidget #########################################################

0 comments on commit 56b8914

Please sign in to comment.