Ticket #5116: newforms_select_disable-2.diff

File newforms_select_disable-2.diff, 5.3 KB (added by Thomas Güttler <hv@…>, 8 years ago)
  • tests/regressiontests/forms/widgets.py

     
    419419<option value="4">4</option>
    420420</select>
    421421
     422You can disable some choices by passing a subset of choices:
     423>>> w = Select(choices=get_choices(), disable=[0])
     424>>> print w.render('num', 2)
     425<select name="num">
     426<option value="0" disabled="disabled">0</option>
     427<option value="1">1</option>
     428<option value="2" selected="selected">2</option>
     429<option value="3">3</option>
     430<option value="4">4</option>
     431</select>
     432
    422433# NullBooleanSelect Widget ####################################################
    423434
    424435>>> w = NullBooleanSelect()
     
    549560<option value="3">3</option>
    550561</select>
    551562
     563You can disable a subset of choices:
     564>>> w = SelectMultiple(choices=[(1, 1), (2, 2), (3, 3)], disable=[1])
     565>>> print w.render('nums', None)
     566<select multiple="multiple" name="nums">
     567<option value="1" disabled="disabled">1</option>
     568<option value="2">2</option>
     569<option value="3">3</option>
     570</select>
     571
     572
    552573If 'choices' is passed to both the constructor and render(), then they'll both be in the output:
     574>>> w = SelectMultiple(choices=[(1, 1), (2, 2), (3, 3)])
    553575>>> print w.render('nums', [2], choices=[(4, 4), (5, 5)])
    554576<select multiple="multiple" name="nums">
    555577<option value="1">1</option>
  • django/newforms/widgets.py

     
    201201        return super(CheckboxInput, self).value_from_datadict(data, files, name)
    202202
    203203class Select(Widget):
    204     def __init__(self, attrs=None, choices=()):
     204    def __init__(self, attrs=None, choices=(), disable=()):
    205205        super(Select, self).__init__(attrs)
    206206        # choices can be any iterable, but we may need to render this widget
    207207        # multiple times. Thus, collapse it into a list so it can be consumed
    208208        # more than once.
    209209        self.choices = list(choices)
    210 
     210        self.disable = set(disable)
     211       
    211212    def render(self, name, value, attrs=None, choices=()):
    212213        if value is None: value = ''
    213214        final_attrs = self.build_attrs(attrs, name=name)
     
    215216        # Normalize to string.
    216217        str_value = force_unicode(value)
    217218        for option_value, option_label in chain(self.choices, choices):
     219            disable_html = (option_value in self.disable) and ' disabled="disabled"' or ''
    218220            option_value = force_unicode(option_value)
    219221            selected_html = (option_value == str_value) and u' selected="selected"' or ''
    220             output.append(u'<option value="%s"%s>%s</option>' % (
    221                     escape(option_value), selected_html,
     222            output.append(u'<option value="%s"%s%s>%s</option>' % (
     223                    escape(option_value), selected_html, disable_html,
    222224                    conditional_escape(force_unicode(option_label))))
    223225        output.append(u'</select>')
    224226        return mark_safe(u'\n'.join(output))
     
    243245        return {u'2': True, u'3': False, True: True, False: False}.get(value, None)
    244246
    245247class SelectMultiple(Widget):
    246     def __init__(self, attrs=None, choices=()):
     248    def __init__(self, attrs=None, choices=(), disable=()):
    247249        super(SelectMultiple, self).__init__(attrs)
    248250        # choices can be any iterable
    249251        self.choices = choices
    250 
     252        self.disable = set(disable)
     253       
    251254    def render(self, name, value, attrs=None, choices=()):
    252255        if value is None: value = []
    253256        final_attrs = self.build_attrs(attrs, name=name)
    254257        output = [u'<select multiple="multiple"%s>' % flatatt(final_attrs)]
    255258        str_values = set([force_unicode(v) for v in value]) # Normalize to strings.
    256259        for option_value, option_label in chain(self.choices, choices):
     260            disable_html = (option_value in self.disable) and ' disabled="disabled"' or ''
    257261            option_value = force_unicode(option_value)
    258262            selected_html = (option_value in str_values) and ' selected="selected"' or ''
    259             output.append(u'<option value="%s"%s>%s</option>' % (
    260                     escape(option_value), selected_html,
     263            output.append(u'<option value="%s"%s%s>%s</option>' % (
     264                    escape(option_value), selected_html, disable_html,
    261265                    conditional_escape(force_unicode(option_label))))
    262266        output.append(u'</select>')
    263267        return mark_safe(u'\n'.join(output))
  • docs/newforms.txt

     
    17671767        url = forms.URLField()
    17681768        comment = CommentInput()
    17691769
     1770Select Widgets
     1771--------------
     1772
     1773The constructor of ``Select`` and the ``SelectMultiple`` widgets can
     1774be given a subset of choices which should be disabled.
     1775
     1776Example::
     1777
     1778    >>> w = SelectMultiple(choices=[(1, 1), (2, 2), (3, 3)], disable=[1])
     1779    >>> print w.render('nums', None)
     1780    <select multiple="multiple" name="nums">
     1781     <option value="1" disabled="disabled">1</option>
     1782     <option value="2">2</option>
     1783     <option value="3">3</option>
     1784    </select>
     1785
     1786
    17701787Generating forms for models
    17711788===========================
    17721789
Back to Top