Widget for editing CommaSeparatedIntegerField with a set of checkboxes. Each checkbox corresponds to single integer value. So, choices should be pre-defined for widget.
Example
Assume, we need a registration form for some event with time frame for 3 days, starting at Monday. User can select any of 3 days, so we need to show 3 checkboxes.
Here's the basic example for such form:
class EventRegistrationForm(forms.Form):
days = forms.CharField(widget=NumbersSelectionWidget(
['Mon', 'Tue', 'Wed'], range(1, 4)))
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | from django.forms.widgets import Widget
from django.forms.util import flatatt
from django.utils.encoding import force_unicode
from django.utils.safestring import mark_safe
class CheckboxesForCommaSeparated(Widget):
def __init__(self, choices, attrs=None, renderer=lambda x: mark_safe(u'\n'.join(x))):
super(CheckboxesForCommaSeparated, self).__init__(attrs)
self.choices = choices
self.renderer = renderer
def decompress(self, value):
return value.split(',')
def render(self, name, value, attrs=None):
if value is None:
value = ''
output = []
selected = self.decompress(value)
has_id = attrs and 'id' in attrs
for i, v in enumerate(self.choices):
final_attrs = self.build_attrs(attrs, type='checkbox', name=name)
final_attrs['value'] = force_unicode(v)
if str(v) in selected:
final_attrs['checked'] = 'checked'
if has_id:
final_attrs['id'] = '%s_%s' % (attrs['id'], i)
output.append(u'<input%s />' % flatatt(final_attrs))
return self.renderer(output)
def value_from_datadict(self, data, files, name):
values = data.getlist(name)
return ','.join(values) if values else ''
class NumbersSelectionWidget(CheckboxesForCommaSeparated):
def __init__(self, labels, *args, **kwargs):
self.labels = labels
kwargs['renderer'] = self.render_with_labels
super(NumbersSelectionWidget, self).__init__(*args, **kwargs)
def render_with_labels(self, checkboxes):
output = []
output.append('<table>')
output.append('<tr>')
for i, c in enumerate(checkboxes):
output.append('<td>%s</td>' % self.labels[i % len(self.labels)])
output.append('</tr>')
output.append('<tr>')
for i, c in enumerate(checkboxes):
output.append('<td>%s</td>' % c)
output.append('</tr>')
output.append('</table>')
return mark_safe(u'\n'.join(output))
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 11 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 6 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 7 months ago
- Help text hyperlinks by sa2812 1 year, 8 months ago
Comments
Please login first before commenting.