Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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...
commit 56b8914eb968ad49d3a15a98cec65fec849e1227 1 parent 39aa40d
Russell Keith-Magee authored April 24, 2007
19  django/newforms/widgets.py
@@ -260,8 +260,8 @@ def render(self, name, value, attrs=None, choices=()):
260 260
         "Returns a RadioFieldRenderer instance rather than a Unicode string."
261 261
         if value is None: value = ''
262 262
         str_value = smart_unicode(value) # Normalize to string.
263  
-        attrs = attrs or {}
264  
-        return RadioFieldRenderer(name, str_value, attrs, list(chain(self.choices, choices)))
  263
+        final_attrs = self.build_attrs(attrs)
  264
+        return RadioFieldRenderer(name, str_value, final_attrs, list(chain(self.choices, choices)))
265 265
 
266 266
     def id_for_label(self, id_):
267 267
         # RadioSelect is represented by multiple <input type="radio"> fields,
@@ -327,14 +327,25 @@ def render(self, name, value, attrs=None):
327 327
         if not isinstance(value, list):
328 328
             value = self.decompress(value)
329 329
         output = []
  330
+        final_attrs = self.build_attrs(attrs)
  331
+        id_ = final_attrs.get('id', None)
330 332
         for i, widget in enumerate(self.widgets):
331 333
             try:
332 334
                 widget_value = value[i]
333  
-            except KeyError:
  335
+            except IndexError:
334 336
                 widget_value = None
335  
-            output.append(widget.render(name + '_%s' % i, widget_value, attrs))
  337
+            if id_:
  338
+                final_attrs = dict(final_attrs, id='%s_%s' % (id_, i))
  339
+            output.append(widget.render(name + '_%s' % i, widget_value, final_attrs))
336 340
         return self.format_output(output)
337 341
 
  342
+    def id_for_label(self, id_):
  343
+        # See the comment for RadioSelect.id_for_label()
  344
+        if id_:
  345
+            id_ += '_0'
  346
+        return id_
  347
+    id_for_label = classmethod(id_for_label)
  348
+
338 349
     def value_from_datadict(self, data, name):
339 350
         return [data.get(name + '_%s' % i) for i in range(len(self.widgets))]
340 351
 
26  tests/regressiontests/forms/tests.py
@@ -658,10 +658,31 @@
658 658
 ...
659 659
 IndexError: list index out of range
660 660
 
  661
+# Unicode choices are correctly rendered as HTML
661 662
 >>> w = RadioSelect()
662 663
 >>> unicode(w.render('email', 'ŠĐĆŽćžšđ', choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')]))
663 664
 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>'
664 665
 
  666
+# Attributes provided at instantiation are passed to the constituent inputs
  667
+>>> w = RadioSelect(attrs={'id':'foo'})
  668
+>>> print w.render('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
  669
+<ul>
  670
+<li><label><input checked="checked" type="radio" id="foo_0" value="J" name="beatle" /> John</label></li>
  671
+<li><label><input type="radio" id="foo_1" value="P" name="beatle" /> Paul</label></li>
  672
+<li><label><input type="radio" id="foo_2" value="G" name="beatle" /> George</label></li>
  673
+<li><label><input type="radio" id="foo_3" value="R" name="beatle" /> Ringo</label></li>
  674
+</ul>
  675
+
  676
+# Attributes provided at render-time are passed to the constituent inputs
  677
+>>> w = RadioSelect()
  678
+>>> print w.render('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')), attrs={'id':'bar'})
  679
+<ul>
  680
+<li><label><input checked="checked" type="radio" id="bar_0" value="J" name="beatle" /> John</label></li>
  681
+<li><label><input type="radio" id="bar_1" value="P" name="beatle" /> Paul</label></li>
  682
+<li><label><input type="radio" id="bar_2" value="G" name="beatle" /> George</label></li>
  683
+<li><label><input type="radio" id="bar_3" value="R" name="beatle" /> Ringo</label></li>
  684
+</ul>
  685
+
665 686
 # CheckboxSelectMultiple Widget ###############################################
666 687
 
667 688
 >>> w = CheckboxSelectMultiple()
@@ -783,6 +804,11 @@
783 804
 u'<input type="text" class="big" value="john" name="name_0" /><br /><input type="text" class="small" value="lennon" name="name_1" />'
784 805
 >>> w.render('name', 'john__lennon')
785 806
 u'<input type="text" class="big" value="john" name="name_0" /><br /><input type="text" class="small" value="lennon" name="name_1" />'
  807
+>>> w.render('name', 'john__lennon', attrs={'id':'foo'})
  808
+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" />'
  809
+>>> w = MyMultiWidget(widgets=(TextInput(attrs={'class': 'big'}), TextInput(attrs={'class': 'small'})), attrs={'id': 'bar'})
  810
+>>> w.render('name', ['john', 'lennon'])
  811
+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" />'
786 812
 
787 813
 # SplitDateTimeWidget #########################################################
788 814
 

0 notes on commit 56b8914

Please sign in to comment.
Something went wrong with that request. Please try again.