diff options
| author | Robin Munn <robin.munn@gmail.com> | 2006-11-08 04:50:01 +0000 |
|---|---|---|
| committer | Robin Munn <robin.munn@gmail.com> | 2006-11-08 04:50:01 +0000 |
| commit | dadfca08c0db567ce33284aaa8eb388cf667a836 (patch) | |
| tree | ab7255eeee1bbe03d95652cc74a3843fa052d8ac /django/newforms/widgets.py | |
| parent | 0b059aa4eadc1d95ceca3a32821b65a9fb2a53e8 (diff) | |
sqlalchemy: Merged revisions 3918 to 4053 from trunk.
git-svn-id: http://code.djangoproject.com/svn/django/branches/sqlalchemy@4054 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django/newforms/widgets.py')
| -rw-r--r-- | django/newforms/widgets.py | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/django/newforms/widgets.py b/django/newforms/widgets.py new file mode 100644 index 0000000000..5ec27653cf --- /dev/null +++ b/django/newforms/widgets.py @@ -0,0 +1,113 @@ +""" +HTML Widget classes +""" + +__all__ = ( + 'Widget', 'TextInput', 'PasswordInput', 'HiddenInput', 'FileInput', + 'Textarea', 'CheckboxInput', + 'Select', 'SelectMultiple', +) + +from django.utils.html import escape +from itertools import chain + +try: + set # Only available in Python 2.4+ +except NameError: + from sets import Set as set # Python 2.3 fallback + +# Converts a dictionary to a single string with key="value", XML-style. +# Assumes keys do not need to be XML-escaped. +flatatt = lambda attrs: ' '.join(['%s="%s"' % (k, escape(v)) for k, v in attrs.items()]) + +class Widget(object): + requires_data_list = False # Determines whether render()'s 'value' argument should be a list. + def __init__(self, attrs=None): + self.attrs = attrs or {} + + def render(self, name, value): + raise NotImplementedError + +class Input(Widget): + "Base class for all <input> widgets (except type='checkbox', which is special)" + input_type = None # Subclasses must define this. + def render(self, name, value, attrs=None): + if value is None: value = '' + final_attrs = dict(self.attrs, type=self.input_type, name=name) + if attrs: + final_attrs.update(attrs) + if value != '': final_attrs['value'] = value # Only add the 'value' attribute if a value is non-empty. + return u'<input %s />' % flatatt(final_attrs) + +class TextInput(Input): + input_type = 'text' + +class PasswordInput(Input): + input_type = 'password' + +class HiddenInput(Input): + input_type = 'hidden' + +class FileInput(Input): + input_type = 'file' + +class Textarea(Widget): + def render(self, name, value, attrs=None): + if value is None: value = '' + final_attrs = dict(self.attrs, name=name) + if attrs: + final_attrs.update(attrs) + return u'<textarea %s>%s</textarea>' % (flatatt(final_attrs), escape(value)) + +class CheckboxInput(Widget): + def render(self, name, value, attrs=None): + final_attrs = dict(self.attrs, type='checkbox', name=name) + if attrs: + final_attrs.update(attrs) + if value: final_attrs['checked'] = 'checked' + return u'<input %s />' % flatatt(final_attrs) + +class Select(Widget): + def __init__(self, attrs=None, choices=()): + # choices can be any iterable + self.attrs = attrs or {} + self.choices = choices + + def render(self, name, value, attrs=None, choices=()): + if value is None: value = '' + final_attrs = dict(self.attrs, name=name) + if attrs: + final_attrs.update(attrs) + output = [u'<select %s>' % flatatt(final_attrs)] + str_value = str(value) # Normalize to string. + for option_value, option_label in chain(self.choices, choices): + selected_html = (str(option_value) == str_value) and ' selected="selected"' or '' + output.append(u'<option value="%s"%s>%s</option>' % (escape(option_value), selected_html, escape(option_label))) + output.append(u'</select>') + return u'\n'.join(output) + +class SelectMultiple(Widget): + requires_data_list = True + def __init__(self, attrs=None, choices=()): + # choices can be any iterable + self.attrs = attrs or {} + self.choices = choices + + def render(self, name, value, attrs=None, choices=()): + if value is None: value = [] + final_attrs = dict(self.attrs, name=name) + if attrs: + final_attrs.update(attrs) + output = [u'<select multiple="multiple" %s>' % flatatt(final_attrs)] + str_values = set([str(v) for v in value]) # Normalize to strings. + for option_value, option_label in chain(self.choices, choices): + selected_html = (str(option_value) in str_values) and ' selected="selected"' or '' + output.append(u'<option value="%s"%s>%s</option>' % (escape(option_value), selected_html, escape(option_label))) + output.append(u'</select>') + return u'\n'.join(output) + +class RadioSelect(Widget): + pass + +class CheckboxSelectMultiple(Widget): + pass |
