Changeset 4148
- Timestamp:
- 11/30/06 16:06:08 (2 years ago)
- Files:
-
- django/trunk/django/newforms/widgets.py (modified) (2 diffs)
- django/trunk/tests/regressiontests/forms/tests.py (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/trunk/django/newforms/widgets.py
r4146 r4148 92 92 93 93 class CheckboxInput(Widget): 94 def __init__(self, attrs=None, check_test=bool): 95 # check_test is a callable that takes a value and returns True 96 # if the checkbox should be checked for that value. 97 self.attrs = attrs or {} 98 self.check_test = check_test 99 94 100 def render(self, name, value, attrs=None): 95 101 final_attrs = self.build_attrs(attrs, type='checkbox', name=name) 96 if value: final_attrs['checked'] = 'checked' 102 try: 103 result = self.check_test(value) 104 except: # Silently catch exceptions 105 result = False 106 if result: 107 final_attrs['checked'] = 'checked' 108 if value not in ('', True, False, None): 109 final_attrs['value'] = smart_unicode(value) # Only add the 'value' attribute if a value is non-empty. 97 110 return u'<input%s />' % flatatt(final_attrs) 98 111 … … 194 207 output = [u'<ul>'] 195 208 str_values = set([smart_unicode(v) for v in value]) # Normalize to strings. 196 cb = CheckboxInput(final_attrs )209 cb = CheckboxInput(final_attrs, check_test=lambda value: value in str_values) 197 210 for option_value, option_label in chain(self.choices, choices): 198 211 option_value = smart_unicode(option_value) 199 field_name = name + option_value 200 rendered_cb = cb.render(field_name, (option_value in str_values)) 212 rendered_cb = cb.render(name, option_value) 201 213 output.append(u'<li><label>%s %s</label></li>' % (rendered_cb, escape(smart_unicode(option_label)))) 202 214 output.append(u'</ul>') 203 215 return u'\n'.join(output) 204 205 def value_from_datadict(self, data, name):206 data_list = [k for k, v in self.choices if data.get(name + k)]207 return data_list or None208 216 209 217 def id_for_label(self, id_): django/trunk/tests/regressiontests/forms/tests.py
r4147 r4148 165 165 >>> w.render('is_cool', '') 166 166 u'<input type="checkbox" name="is_cool" />' 167 >>> w.render('is_cool', None) 168 u'<input type="checkbox" name="is_cool" />' 167 169 >>> w.render('is_cool', False) 168 170 u'<input type="checkbox" name="is_cool" />' 169 171 >>> w.render('is_cool', True) 170 172 u'<input checked="checked" type="checkbox" name="is_cool" />' 173 174 Using any value that's not in ('', None, False, True) will check the checkbox 175 and set the 'value' attribute. 176 >>> w.render('is_cool', 'foo') 177 u'<input checked="checked" type="checkbox" name="is_cool" value="foo" />' 178 171 179 >>> w.render('is_cool', False, attrs={'class': 'pretty'}) 172 180 u'<input type="checkbox" name="is_cool" class="pretty" />' … … 181 189 >>> w.render('is_cool', '', attrs={'class': 'special'}) 182 190 u'<input type="checkbox" class="special" name="is_cool" />' 191 192 You can pass 'check_test' to the constructor. This is a callable that takes the 193 value and returns True if the box should be checked. 194 >>> w = CheckboxInput(check_test=lambda value: value.startswith('hello')) 195 >>> w.render('greeting', '') 196 u'<input type="checkbox" name="greeting" />' 197 >>> w.render('greeting', 'hello') 198 u'<input checked="checked" type="checkbox" name="greeting" value="hello" />' 199 >>> w.render('greeting', 'hello there') 200 u'<input checked="checked" type="checkbox" name="greeting" value="hello there" />' 201 >>> w.render('greeting', 'hello & goodbye') 202 u'<input checked="checked" type="checkbox" name="greeting" value="hello & goodbye" />' 203 204 A subtlety: If the 'check_test' argument cannot handle a value and raises any 205 exception during its __call__, then the exception will be swallowed and the box 206 will not be checked. In this example, the 'check_test' assumes the value has a 207 startswith() method, which fails for the values True, False and None. 208 >>> w.render('greeting', True) 209 u'<input type="checkbox" name="greeting" />' 210 >>> w.render('greeting', False) 211 u'<input type="checkbox" name="greeting" />' 212 >>> w.render('greeting', None) 213 u'<input type="checkbox" name="greeting" />' 183 214 184 215 # Select Widget ############################################################### … … 489 520 >>> print w.render('beatles', ['J'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))) 490 521 <ul> 491 <li><label><input checked="checked" type="checkbox" name="beatles J" /> John</label></li>492 <li><label><input type="checkbox" name="beatles P" /> Paul</label></li>493 <li><label><input type="checkbox" name="beatles G" /> George</label></li>494 <li><label><input type="checkbox" name="beatles R" /> Ringo</label></li>522 <li><label><input checked="checked" type="checkbox" name="beatles" value="J" /> John</label></li> 523 <li><label><input type="checkbox" name="beatles" value="P" /> Paul</label></li> 524 <li><label><input type="checkbox" name="beatles" value="G" /> George</label></li> 525 <li><label><input type="checkbox" name="beatles" value="R" /> Ringo</label></li> 495 526 </ul> 496 527 >>> print w.render('beatles', ['J', 'P'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))) 497 528 <ul> 498 <li><label><input checked="checked" type="checkbox" name="beatles J" /> John</label></li>499 <li><label><input checked="checked" type="checkbox" name="beatles P" /> Paul</label></li>500 <li><label><input type="checkbox" name="beatles G" /> George</label></li>501 <li><label><input type="checkbox" name="beatles R" /> Ringo</label></li>529 <li><label><input checked="checked" type="checkbox" name="beatles" value="J" /> John</label></li> 530 <li><label><input checked="checked" type="checkbox" name="beatles" value="P" /> Paul</label></li> 531 <li><label><input type="checkbox" name="beatles" value="G" /> George</label></li> 532 <li><label><input type="checkbox" name="beatles" value="R" /> Ringo</label></li> 502 533 </ul> 503 534 >>> print w.render('beatles', ['J', 'P', 'R'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))) 504 535 <ul> 505 <li><label><input checked="checked" type="checkbox" name="beatles J" /> John</label></li>506 <li><label><input checked="checked" type="checkbox" name="beatles P" /> Paul</label></li>507 <li><label><input type="checkbox" name="beatles G" /> George</label></li>508 <li><label><input checked="checked" type="checkbox" name="beatles R" /> Ringo</label></li>536 <li><label><input checked="checked" type="checkbox" name="beatles" value="J" /> John</label></li> 537 <li><label><input checked="checked" type="checkbox" name="beatles" value="P" /> Paul</label></li> 538 <li><label><input type="checkbox" name="beatles" value="G" /> George</label></li> 539 <li><label><input checked="checked" type="checkbox" name="beatles" value="R" /> Ringo</label></li> 509 540 </ul> 510 541 … … 512 543 >>> print w.render('beatles', None, choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))) 513 544 <ul> 514 <li><label><input type="checkbox" name="beatles J" /> John</label></li>515 <li><label><input type="checkbox" name="beatles P" /> Paul</label></li>516 <li><label><input type="checkbox" name="beatles G" /> George</label></li>517 <li><label><input type="checkbox" name="beatles R" /> Ringo</label></li>545 <li><label><input type="checkbox" name="beatles" value="J" /> John</label></li> 546 <li><label><input type="checkbox" name="beatles" value="P" /> Paul</label></li> 547 <li><label><input type="checkbox" name="beatles" value="G" /> George</label></li> 548 <li><label><input type="checkbox" name="beatles" value="R" /> Ringo</label></li> 518 549 </ul> 519 550 … … 521 552 >>> print w.render('beatles', ['John'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))) 522 553 <ul> 523 <li><label><input type="checkbox" name="beatles J" /> John</label></li>524 <li><label><input type="checkbox" name="beatles P" /> Paul</label></li>525 <li><label><input type="checkbox" name="beatles G" /> George</label></li>526 <li><label><input type="checkbox" name="beatles R" /> Ringo</label></li>554 <li><label><input type="checkbox" name="beatles" value="J" /> John</label></li> 555 <li><label><input type="checkbox" name="beatles" value="P" /> Paul</label></li> 556 <li><label><input type="checkbox" name="beatles" value="G" /> George</label></li> 557 <li><label><input type="checkbox" name="beatles" value="R" /> Ringo</label></li> 527 558 </ul> 528 559 … … 530 561 >>> print w.render('beatles', ['J', 'G', 'foo'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))) 531 562 <ul> 532 <li><label><input checked="checked" type="checkbox" name="beatles J" /> John</label></li>533 <li><label><input type="checkbox" name="beatles P" /> Paul</label></li>534 <li><label><input checked="checked" type="checkbox" name="beatles G" /> George</label></li>535 <li><label><input type="checkbox" name="beatles R" /> Ringo</label></li>563 <li><label><input checked="checked" type="checkbox" name="beatles" value="J" /> John</label></li> 564 <li><label><input type="checkbox" name="beatles" value="P" /> Paul</label></li> 565 <li><label><input checked="checked" type="checkbox" name="beatles" value="G" /> George</label></li> 566 <li><label><input type="checkbox" name="beatles" value="R" /> Ringo</label></li> 536 567 </ul> 537 568 … … 539 570 >>> print w.render('nums', [2], choices=[('1', '1'), ('2', '2'), ('3', '3')]) 540 571 <ul> 541 <li><label><input type="checkbox" name="nums 1" /> 1</label></li>542 <li><label><input checked="checked" type="checkbox" name="nums 2" /> 2</label></li>543 <li><label><input type="checkbox" name="nums 3" /> 3</label></li>572 <li><label><input type="checkbox" name="nums" value="1" /> 1</label></li> 573 <li><label><input checked="checked" type="checkbox" name="nums" value="2" /> 2</label></li> 574 <li><label><input type="checkbox" name="nums" value="3" /> 3</label></li> 544 575 </ul> 545 576 >>> print w.render('nums', ['2'], choices=[(1, 1), (2, 2), (3, 3)]) 546 577 <ul> 547 <li><label><input type="checkbox" name="nums 1" /> 1</label></li>548 <li><label><input checked="checked" type="checkbox" name="nums 2" /> 2</label></li>549 <li><label><input type="checkbox" name="nums 3" /> 3</label></li>578 <li><label><input type="checkbox" name="nums" value="1" /> 1</label></li> 579 <li><label><input checked="checked" type="checkbox" name="nums" value="2" /> 2</label></li> 580 <li><label><input type="checkbox" name="nums" value="3" /> 3</label></li> 550 581 </ul> 551 582 >>> print w.render('nums', [2], choices=[(1, 1), (2, 2), (3, 3)]) 552 583 <ul> 553 <li><label><input type="checkbox" name="nums 1" /> 1</label></li>554 <li><label><input checked="checked" type="checkbox" name="nums 2" /> 2</label></li>555 <li><label><input type="checkbox" name="nums 3" /> 3</label></li>584 <li><label><input type="checkbox" name="nums" value="1" /> 1</label></li> 585 <li><label><input checked="checked" type="checkbox" name="nums" value="2" /> 2</label></li> 586 <li><label><input type="checkbox" name="nums" value="3" /> 3</label></li> 556 587 </ul> 557 588 … … 562 593 >>> print w.render('nums', [2], choices=get_choices()) 563 594 <ul> 564 <li><label><input type="checkbox" name="nums 0" /> 0</label></li>565 <li><label><input type="checkbox" name="nums 1" /> 1</label></li>566 <li><label><input checked="checked" type="checkbox" name="nums 2" /> 2</label></li>567 <li><label><input type="checkbox" name="nums 3" /> 3</label></li>568 <li><label><input type="checkbox" name="nums 4" /> 4</label></li>595 <li><label><input type="checkbox" name="nums" value="0" /> 0</label></li> 596 <li><label><input type="checkbox" name="nums" value="1" /> 1</label></li> 597 <li><label><input checked="checked" type="checkbox" name="nums" value="2" /> 2</label></li> 598 <li><label><input type="checkbox" name="nums" value="3" /> 3</label></li> 599 <li><label><input type="checkbox" name="nums" value="4" /> 4</label></li> 569 600 </ul> 570 601 … … 573 604 >>> print w.render('nums', [2]) 574 605 <ul> 575 <li><label><input type="checkbox" name="nums 1" /> 1</label></li>576 <li><label><input checked="checked" type="checkbox" name="nums 2" /> 2</label></li>577 <li><label><input type="checkbox" name="nums 3" /> 3</label></li>606 <li><label><input type="checkbox" name="nums" value="1" /> 1</label></li> 607 <li><label><input checked="checked" type="checkbox" name="nums" value="2" /> 2</label></li> 608 <li><label><input type="checkbox" name="nums" value="3" /> 3</label></li> 578 609 </ul> 579 610 … … 581 612 >>> print w.render('nums', [2], choices=[(4, 4), (5, 5)]) 582 613 <ul> 583 <li><label><input type="checkbox" name="nums 1" /> 1</label></li>584 <li><label><input checked="checked" type="checkbox" name="nums 2" /> 2</label></li>585 <li><label><input type="checkbox" name="nums 3" /> 3</label></li>586 <li><label><input type="checkbox" name="nums 4" /> 4</label></li>587 <li><label><input type="checkbox" name="nums 5" /> 5</label></li>614 <li><label><input type="checkbox" name="nums" value="1" /> 1</label></li> 615 <li><label><input checked="checked" type="checkbox" name="nums" value="2" /> 2</label></li> 616 <li><label><input type="checkbox" name="nums" value="3" /> 3</label></li> 617 <li><label><input type="checkbox" name="nums" value="4" /> 4</label></li> 618 <li><label><input type="checkbox" name="nums" value="5" /> 5</label></li> 588 619 </ul> 589 620 590 621 >>> w.render('nums', ['ŠĐĆŽćžšđ'], choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')]) 591 u'<ul>\n<li><label><input type="checkbox" name="nums 1" /> 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>'622 u'<ul>\n<li><label><input type="checkbox" name="nums" value="1" /> 1</label></li>\n<li><label><input type="checkbox" name="nums" value="2" /> 2</label></li>\n<li><label><input type="checkbox" name="nums" value="3" /> 3</label></li>\n<li><label><input checked="checked" type="checkbox" name="nums" value="\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" value="\u0107\u017e\u0161\u0111" /> abc\u0107\u017e\u0161\u0111</label></li>\n</ul>' 592 623 593 624 ########## … … 1600 1631 >>> print f['composers'] 1601 1632 <ul> 1602 <li><label><input type="checkbox" name="composers J" /> John Lennon</label></li>1603 <li><label><input type="checkbox" name="composers P" /> Paul McCartney</label></li>1633 <li><label><input type="checkbox" name="composers" value="J" /> John Lennon</label></li> 1634 <li><label><input type="checkbox" name="composers" value="P" /> Paul McCartney</label></li> 1604 1635 </ul> 1605 1636 >>> f = SongForm({'composers': ['J']}) 1606 1637 >>> print f['composers'] 1607 1638 <ul> 1608 <li><label><input checked="checked" type="checkbox" name="composers J" /> John Lennon</label></li>1609 <li><label><input type="checkbox" name="composers P" /> Paul McCartney</label></li>1639 <li><label><input checked="checked" type="checkbox" name="composers" value="J" /> John Lennon</label></li> 1640 <li><label><input type="checkbox" name="composers" value="P" /> Paul McCartney</label></li> 1610 1641 </ul> 1611 1642 >>> f = SongForm({'composers': ['J', 'P']}) 1612 1643 >>> print f['composers'] 1613 1644 <ul> 1614 <li><label><input checked="checked" type="checkbox" name="composersJ" /> John Lennon</label></li> 1615 <li><label><input checked="checked" type="checkbox" name="composersP" /> Paul McCartney</label></li> 1616 </ul> 1617 1618 When using CheckboxSelectMultiple, the framework automatically converts the 1619 data in clean_data to a list of values, rather than the underlying HTML form 1620 field name. 1645 <li><label><input checked="checked" type="checkbox" name="composers" value="J" /> John Lennon</label></li> 1646 <li><label><input checked="checked" type="checkbox" name="composers" value="P" /> Paul McCartney</label></li> 1647 </ul> 1648 1649 When using CheckboxSelectMultiple, the framework expects a list of input and 1650 returns a list of input. 1621 1651 >>> f = SongForm({'name': 'Yesterday'}) 1622 1652 >>> f.errors 1623 1653 {'composers': [u'This field is required.']} 1624 >>> f = SongForm({'name': 'Yesterday', 'composers J': 'on'})1654 >>> f = SongForm({'name': 'Yesterday', 'composers': ['J']}) 1625 1655 >>> f.errors 1626 1656 {} 1627 1657 >>> f.clean_data 1628 1658 {'composers': [u'J'], 'name': u'Yesterday'} 1629 >>> f = SongForm({'name': 'Yesterday', 'composers J': 'on', 'composersP': 'on'})1659 >>> f = SongForm({'name': 'Yesterday', 'composers': ['J', 'P']}) 1630 1660 >>> f.errors 1631 1661 {}
