Ticket #5116: newforms_select_disable.diff

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

     
    392392<option value="4">4</option>
    393393</select>
    394394
     395You can disable some choices by passing a subset of choices:
     396>>> w = Select(choices=get_choices(), disable=[0])
     397>>> print w.render('num', 2)
     398<select name="num">
     399<option value="0" disabled="disabled">0</option>
     400<option value="1">1</option>
     401<option value="2" selected="selected">2</option>
     402<option value="3">3</option>
     403<option value="4">4</option>
     404</select>
     405
    395406# NullBooleanSelect Widget ####################################################
    396407
    397408>>> w = NullBooleanSelect()
     
    522533<option value="3">3</option>
    523534</select>
    524535
     536You can disable a subset of choices:
     537>>> w = SelectMultiple(choices=[(1, 1), (2, 2), (3, 3)], disable=[1])
     538>>> print w.render('nums', None)
     539<select multiple="multiple" name="nums">
     540<option value="1" disabled="disabled">1</option>
     541<option value="2">2</option>
     542<option value="3">3</option>
     543</select>
     544
     545
    525546If 'choices' is passed to both the constructor and render(), then they'll both be in the output:
     547>>> w = SelectMultiple(choices=[(1, 1), (2, 2), (3, 3)])
    526548>>> print w.render('nums', [2], choices=[(4, 4), (5, 5)])
    527549<select multiple="multiple" name="nums">
    528550<option value="1">1</option>
  • django/newforms/widgets.py

     
    171171        return u'<input%s />' % flatatt(final_attrs)
    172172
    173173class Select(Widget):
    174     def __init__(self, attrs=None, choices=()):
     174    def __init__(self, attrs=None, choices=(), disable=()):
    175175        super(Select, self).__init__(attrs)
    176176        # choices can be any iterable, but we may need to render this widget
    177177        # multiple times. Thus, collapse it into a list so it can be consumed
    178178        # more than once.
    179179        self.choices = list(choices)
    180 
     180        self.disable = set(disable)
     181       
    181182    def render(self, name, value, attrs=None, choices=()):
    182183        if value is None: value = ''
    183184        final_attrs = self.build_attrs(attrs, name=name)
    184185        output = [u'<select%s>' % flatatt(final_attrs)]
    185186        str_value = force_unicode(value) # Normalize to string.
    186187        for option_value, option_label in chain(self.choices, choices):
     188            disable_html = (option_value in self.disable) and ' disabled="disabled"' or ''
    187189            option_value = force_unicode(option_value)
    188190            selected_html = (option_value == str_value) and u' selected="selected"' or ''
    189             output.append(u'<option value="%s"%s>%s</option>' % (escape(option_value), selected_html, escape(force_unicode(option_label))))
     191            output.append(u'<option value="%s"%s%s>%s</option>' % (
     192                escape(option_value), selected_html, disable_html, escape(force_unicode(option_label))))
    190193        output.append(u'</select>')
    191194        return u'\n'.join(output)
    192195
     
    210213        return {u'2': True, u'3': False, True: True, False: False}.get(value, None)
    211214
    212215class SelectMultiple(Widget):
    213     def __init__(self, attrs=None, choices=()):
     216    def __init__(self, attrs=None, choices=(), disable=()):
    214217        super(SelectMultiple, self).__init__(attrs)
    215218        # choices can be any iterable
    216219        self.choices = choices
    217 
     220        self.disable = set(disable)
     221       
    218222    def render(self, name, value, attrs=None, choices=()):
    219223        if value is None: value = []
    220224        final_attrs = self.build_attrs(attrs, name=name)
    221225        output = [u'<select multiple="multiple"%s>' % flatatt(final_attrs)]
    222226        str_values = set([force_unicode(v) for v in value]) # Normalize to strings.
    223227        for option_value, option_label in chain(self.choices, choices):
     228            disable_html = (option_value in self.disable) and ' disabled="disabled"' or ''
    224229            option_value = force_unicode(option_value)
    225230            selected_html = (option_value in str_values) and ' selected="selected"' or ''
    226             output.append(u'<option value="%s"%s>%s</option>' % (escape(option_value), selected_html, escape(force_unicode(option_label))))
     231            output.append(u'<option value="%s"%s%s>%s</option>' % (
     232                escape(option_value), selected_html, disable_html, escape(force_unicode(option_label))))
    227233        output.append(u'</select>')
    228234        return u'\n'.join(output)
    229235
  • docs/newforms.txt

     
    16601660        url = forms.URLField()
    16611661        comment = CommentInput()
    16621662
     1663Select Widgets
     1664--------------
     1665
     1666The constructor of ``Select`` and the ``SelectMultiple`` widgets can
     1667be given a subset of choices which should be disabled.
     1668
     1669Example::
     1670
     1671    >>> w = SelectMultiple(choices=[(1, 1), (2, 2), (3, 3)], disable=[1])
     1672    >>> print w.render('nums', None)
     1673    <select multiple="multiple" name="nums">
     1674     <option value="1" disabled="disabled">1</option>
     1675     <option value="2">2</option>
     1676     <option value="3">3</option>
     1677    </select>
     1678
     1679
    16631680Generating forms for models
    16641681===========================
    16651682
Back to Top