Ticket #3442: widgets.diff

File widgets.diff, 2.2 KB (added by tbarta@…, 18 years ago)

patch to add groupedSelect widget that works with existing ChoiceField class

  • widgets.py

     
    22Extra HTML Widget classes
    33"""
    44
     5from django.utils.html import escape
     6from itertools import chain
     7from django.newforms.util import flatatt, smart_unicode
    58from django.newforms.widgets import Widget, Select
    69from django.utils.dates import MONTHS
    710import datetime
    811
    9 __all__ = ('SelectDateWidget',)
     12__all__ = ('SelectDateWidget', 'GroupedSelect')
    1013
    1114class SelectDateWidget(Widget):
    1215    """
     
    5760        if y and m and d:
    5861            return '%s-%s-%s' % (y, m, d)
    5962        return None
     63 
     64class GroupedSelect(Select):
     65    def __init__(self, attrs=None, groups=(), choices=()):
     66        super(GroupedSelect, self).__init__(attrs, choices)
     67        # groups maps from 'group name' to a list of values in that group
     68        # to preserve ordering, it's a list-of-tuples instead of a dict
     69        self.groups = groups
     70
     71    def render(self, name, value, attrs=None, choices=()):
     72        if value is None: value = ''
     73        final_attrs = self.build_attrs(attrs, name=name)
     74        output = [u'<select%s>' % flatatt(final_attrs)]
     75        str_value = smart_unicode(value) # Normalize to string.
     76        allchoices = dict([(smart_unicode(k), smart_unicode(v))
     77            for k, v in chain(self.choices, choices)])
     78        for group_label, members in self.groups:
     79            group_label = smart_unicode(group_label)
     80            output.append(u'<optgroup label="%s">' % escape(group_label))
     81            for option_value in members:
     82                option_value = smart_unicode(option_value)
     83                try:
     84                    option_label = allchoices[option_value]
     85                except KeyError:
     86                    continue # silently ignore missing elements from the group
     87                selected_html = (option_value == str_value) and u' selected="selected"' or ''
     88                output.append(u'<option value="%s"%s>%s</option>' % (escape(option_value), selected_html, escape(option_label)))
     89            output.append(u'</optgroup>')
     90        output.append(u'</select>')
     91        return u'\n'.join(output)
     92
Back to Top