Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

newforms: Implemented CheckboxSelectMultiple

git-svn-id: http://code.djangoproject.com/svn/django/trunk@4132 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 8aae90c0e5ff45fbcb6c380f8d952e87e7506ab8 1 parent fe4af48
Adrian Holovaty authored November 29, 2006
25  django/newforms/widgets.py
@@ -5,7 +5,7 @@
5 5
 __all__ = (
6 6
     'Widget', 'TextInput', 'PasswordInput', 'HiddenInput', 'FileInput',
7 7
     'Textarea', 'CheckboxInput',
8  
-    'Select', 'SelectMultiple', 'RadioSelect',
  8
+    'Select', 'SelectMultiple', 'RadioSelect', 'CheckboxSelectMultiple',
9 9
 )
10 10
 
11 11
 from util import smart_unicode
@@ -176,5 +176,24 @@ def id_for_label(self, id_):
176 176
         return id_
177 177
     id_for_label = classmethod(id_for_label)
178 178
 
179  
-class CheckboxSelectMultiple(Widget):
180  
-    pass
  179
+class CheckboxSelectMultiple(SelectMultiple):
  180
+    def render(self, name, value, attrs=None, choices=()):
  181
+        if value is None: value = []
  182
+        final_attrs = self.build_attrs(attrs, name=name)
  183
+        output = [u'<ul>']
  184
+        str_values = set([smart_unicode(v) for v in value]) # Normalize to strings.
  185
+        cb = CheckboxInput(final_attrs)
  186
+        for option_value, option_label in chain(self.choices, choices):
  187
+            option_value = smart_unicode(option_value)
  188
+            field_name = unicode(name + option_value)
  189
+            rendered_cb = cb.render(field_name, (option_value in str_values))
  190
+            output.append(u'<li><label>%s %s</label></li>' % (rendered_cb, escape(smart_unicode(option_label))))
  191
+        output.append(u'</ul>')
  192
+        return u'\n'.join(output)
  193
+
  194
+    def id_for_label(self, id_):
  195
+        # See the comment for RadioSelect.id_for_label()
  196
+        if id_:
  197
+            id_ += '_0'
  198
+        return id_
  199
+    id_for_label = classmethod(id_for_label)
107  tests/regressiontests/forms/tests.py
@@ -475,6 +475,113 @@
475 475
 beatle J G George False
476 476
 beatle J R Ringo False
477 477
 
  478
+# CheckboxSelectMultiple Widget ###############################################
  479
+
  480
+>>> w = CheckboxSelectMultiple()
  481
+>>> print w.render('beatles', ['J'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
  482
+<ul>
  483
+<li><label><input checked="checked" type="checkbox" name="beatlesJ" /> John</label></li>
  484
+<li><label><input type="checkbox" name="beatlesP" /> Paul</label></li>
  485
+<li><label><input type="checkbox" name="beatlesG" /> George</label></li>
  486
+<li><label><input type="checkbox" name="beatlesR" /> Ringo</label></li>
  487
+</ul>
  488
+>>> print w.render('beatles', ['J', 'P'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
  489
+<ul>
  490
+<li><label><input checked="checked" type="checkbox" name="beatlesJ" /> John</label></li>
  491
+<li><label><input checked="checked" type="checkbox" name="beatlesP" /> Paul</label></li>
  492
+<li><label><input type="checkbox" name="beatlesG" /> George</label></li>
  493
+<li><label><input type="checkbox" name="beatlesR" /> Ringo</label></li>
  494
+</ul>
  495
+>>> print w.render('beatles', ['J', 'P', 'R'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
  496
+<ul>
  497
+<li><label><input checked="checked" type="checkbox" name="beatlesJ" /> John</label></li>
  498
+<li><label><input checked="checked" type="checkbox" name="beatlesP" /> Paul</label></li>
  499
+<li><label><input type="checkbox" name="beatlesG" /> George</label></li>
  500
+<li><label><input checked="checked" type="checkbox" name="beatlesR" /> Ringo</label></li>
  501
+</ul>
  502
+
  503
+If the value is None, none of the options are selected:
  504
+>>> print w.render('beatles', None, choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
  505
+<ul>
  506
+<li><label><input type="checkbox" name="beatlesJ" /> John</label></li>
  507
+<li><label><input type="checkbox" name="beatlesP" /> Paul</label></li>
  508
+<li><label><input type="checkbox" name="beatlesG" /> George</label></li>
  509
+<li><label><input type="checkbox" name="beatlesR" /> Ringo</label></li>
  510
+</ul>
  511
+
  512
+If the value corresponds to a label (but not to an option value), none of the options are selected:
  513
+>>> print w.render('beatles', ['John'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
  514
+<ul>
  515
+<li><label><input type="checkbox" name="beatlesJ" /> John</label></li>
  516
+<li><label><input type="checkbox" name="beatlesP" /> Paul</label></li>
  517
+<li><label><input type="checkbox" name="beatlesG" /> George</label></li>
  518
+<li><label><input type="checkbox" name="beatlesR" /> Ringo</label></li>
  519
+</ul>
  520
+
  521
+If multiple values are given, but some of them are not valid, the valid ones are selected:
  522
+>>> print w.render('beatles', ['J', 'G', 'foo'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
  523
+<ul>
  524
+<li><label><input checked="checked" type="checkbox" name="beatlesJ" /> John</label></li>
  525
+<li><label><input type="checkbox" name="beatlesP" /> Paul</label></li>
  526
+<li><label><input checked="checked" type="checkbox" name="beatlesG" /> George</label></li>
  527
+<li><label><input type="checkbox" name="beatlesR" /> Ringo</label></li>
  528
+</ul>
  529
+
  530
+The value is compared to its str():
  531
+>>> print w.render('nums', [2], choices=[('1', '1'), ('2', '2'), ('3', '3')])
  532
+<ul>
  533
+<li><label><input type="checkbox" name="nums1" /> 1</label></li>
  534
+<li><label><input checked="checked" type="checkbox" name="nums2" /> 2</label></li>
  535
+<li><label><input type="checkbox" name="nums3" /> 3</label></li>
  536
+</ul>
  537
+>>> print w.render('nums', ['2'], choices=[(1, 1), (2, 2), (3, 3)])
  538
+<ul>
  539
+<li><label><input type="checkbox" name="nums1" /> 1</label></li>
  540
+<li><label><input checked="checked" type="checkbox" name="nums2" /> 2</label></li>
  541
+<li><label><input type="checkbox" name="nums3" /> 3</label></li>
  542
+</ul>
  543
+>>> print w.render('nums', [2], choices=[(1, 1), (2, 2), (3, 3)])
  544
+<ul>
  545
+<li><label><input type="checkbox" name="nums1" /> 1</label></li>
  546
+<li><label><input checked="checked" type="checkbox" name="nums2" /> 2</label></li>
  547
+<li><label><input type="checkbox" name="nums3" /> 3</label></li>
  548
+</ul>
  549
+
  550
+The 'choices' argument can be any iterable:
  551
+>>> def get_choices():
  552
+...     for i in range(5):
  553
+...         yield (i, i)
  554
+>>> print w.render('nums', [2], choices=get_choices())
  555
+<ul>
  556
+<li><label><input type="checkbox" name="nums0" /> 0</label></li>
  557
+<li><label><input type="checkbox" name="nums1" /> 1</label></li>
  558
+<li><label><input checked="checked" type="checkbox" name="nums2" /> 2</label></li>
  559
+<li><label><input type="checkbox" name="nums3" /> 3</label></li>
  560
+<li><label><input type="checkbox" name="nums4" /> 4</label></li>
  561
+</ul>
  562
+
  563
+You can also pass 'choices' to the constructor:
  564
+>>> w = CheckboxSelectMultiple(choices=[(1, 1), (2, 2), (3, 3)])
  565
+>>> print w.render('nums', [2])
  566
+<ul>
  567
+<li><label><input type="checkbox" name="nums1" /> 1</label></li>
  568
+<li><label><input checked="checked" type="checkbox" name="nums2" /> 2</label></li>
  569
+<li><label><input type="checkbox" name="nums3" /> 3</label></li>
  570
+</ul>
  571
+
  572
+If 'choices' is passed to both the constructor and render(), then they'll both be in the output:
  573
+>>> print w.render('nums', [2], choices=[(4, 4), (5, 5)])
  574
+<ul>
  575
+<li><label><input type="checkbox" name="nums1" /> 1</label></li>
  576
+<li><label><input checked="checked" type="checkbox" name="nums2" /> 2</label></li>
  577
+<li><label><input type="checkbox" name="nums3" /> 3</label></li>
  578
+<li><label><input type="checkbox" name="nums4" /> 4</label></li>
  579
+<li><label><input type="checkbox" name="nums5" /> 5</label></li>
  580
+</ul>
  581
+
  582
+>>> w.render('nums', ['ŠĐĆŽćžšđ'], choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')])
  583
+u'<ul>\n<li><label><input type="checkbox" name="nums1" /> 1</label></li>\n<li><label><input type="checkbox" name="nums2" /> 2</label></li>\n<li><label><input type="checkbox" name="nums3" /> 3</label></li>\n<li><label><input checked="checked" type="checkbox" name="nums\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" /> \u0160\u0110abc\u0106\u017d\u0107\u017e\u0161\u0111</label></li>\n<li><label><input type="checkbox" name="nums\u0107\u017e\u0161\u0111" /> abc\u0107\u017e\u0161\u0111</label></li>\n</ul>'
  584
+
478 585
 # CharField ###################################################################
479 586
 
480 587
 >>> f = CharField()

0 notes on commit 8aae90c

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