from itertools import groupby, chain from django import forms from django.forms import Widget from django.forms.widgets import SubWidget, SelectMultiple from django.forms.util import flatatt from django.utils.html import conditional_escape from django.utils.encoding import StrAndUnicode, force_unicode from django.utils.safestring import mark_safe class CheckboxInput(SubWidget): """ An object used by CheckboxRenderer that represents a single . """ def __init__(self, name, value, attrs, choice, index): self.name, self.value = name, value self.attrs = attrs self.choice_value = force_unicode(choice[0]) self.choice_label = force_unicode(choice[1]) self.index = index def __unicode__(self): return self.render() def render(self, name=None, value=None, attrs=None, choices=()): name = name or self.name value = value or self.value attrs = attrs or self.attrs if 'id' in self.attrs: label_for = ' for="%s_%s"' % (self.attrs['id'], self.index) else: label_for = '' choice_label = conditional_escape(force_unicode(self.choice_label)) return mark_safe(u'' % (label_for, self.tag(), choice_label)) def is_checked(self): return self.choice_value in self.value def tag(self): if 'id' in self.attrs: self.attrs['id'] = '%s_%s' % (self.attrs['id'], self.index) final_attrs = dict(self.attrs, type='checkbox', name=self.name, value=self.choice_value) if self.is_checked(): final_attrs['checked'] = 'checked' return mark_safe(u'' % flatatt(final_attrs)) class CheckboxRenderer(StrAndUnicode): def __init__(self, name, value, attrs, choices): self.name, self.value, self.attrs = name, value, attrs self.choices = choices def __iter__(self): for i, choice in enumerate(self.choices): yield CheckboxInput(self.name, self.value, self.attrs.copy(), choice, i) def __getitem__(self, idx): choice = self.choices[idx] # Let the IndexError propogate return CheckboxInput(self.name, self.value, self.attrs.copy(), choice, idx) def __unicode__(self): return self.render() def render(self): """Outputs a