This is a CheckboxSelectMultiple widget that will render its choices divided evenly into multiple ul elements that can be styled nicely into columns. Pass in a css class to the constructor to be assigned to the ul's.
See also: http://code.djangoproject.com/ticket/9230
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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | import math
from itertools import chain
from django import forms
from django.utils.encoding import force_unicode
from django.utils.html import conditional_escape
from django.utils.safestring import mark_safe
class ColumnCheckboxSelectMultiple(forms.CheckboxSelectMultiple):
"""
Widget that renders multiple-select checkboxes in columns.
Constructor takes number of columns and css class to apply
to the <ul> elements that make up the columns.
"""
def __init__(self, columns=2, css_class=None, **kwargs):
super(self.__class__, self).__init__(**kwargs)
self.columns = columns
self.css_class = css_class
def render(self, name, value, attrs=None, choices=()):
if value is None: value = []
has_id = attrs and 'id' in attrs
final_attrs = self.build_attrs(attrs, name=name)
choices_enum = list(enumerate(chain(self.choices, choices)))
# This is the part that splits the choices into columns.
# Slices vertically. Could be changed to slice horizontally, etc.
column_sizes = columnize(len(choices_enum), self.columns)
columns = []
for column_size in column_sizes:
columns.append(choices_enum[:column_size])
choices_enum = choices_enum[column_size:]
output = []
for column in columns:
if self.css_class:
output.append(u'<ul class="%s"' % self.css_class)
else:
output.append(u'<ul>')
# Normalize to strings
str_values = set([force_unicode(v) for v in value])
for i, (option_value, option_label) in column:
# If an ID attribute was given, add a numeric index as a suffix,
# so that the checkboxes don't all have the same ID attribute.
if has_id:
final_attrs = dict(final_attrs, id='%s_%s' % (
attrs['id'], i))
label_for = u' for="%s"' % final_attrs['id']
else:
label_for = ''
cb = forms.CheckboxInput(
final_attrs, check_test=lambda value: value in str_values)
option_value = force_unicode(option_value)
rendered_cb = cb.render(name, option_value)
option_label = conditional_escape(force_unicode(option_label))
output.append(u'<li><label%s>%s %s</label></li>' % (
label_for, rendered_cb, option_label))
output.append(u'</ul>')
return mark_safe(u'\n'.join(output))
def columnize(items, columns):
"""
Return a list containing numbers of elements per column if `items` items
are to be divided into `columns` columns.
>>> columnize(10, 1)
[10]
>>> columnize(10, 2)
[5, 5]
>>> columnize(10, 3)
[4, 3, 3]
>>> columnize(3, 4)
[1, 1, 1, 0]
"""
elts_per_column = []
for col in range(columns):
col_size = int(math.ceil(float(items) / columns))
elts_per_column.append(col_size)
items -= col_size
columns -= 1
return elts_per_column
|
More like this
- Browser-native date input field by kytta 4 weeks ago
- Generate and render HTML Table by LLyaudet 1 month, 1 week ago
- My firs Snippets by GutemaG 1 month, 1 week ago
- FileField having auto upload_to path by junaidmgithub 2 months, 2 weeks ago
- LazyPrimaryKeyRelatedField by LLyaudet 2 months, 3 weeks ago
Comments
Line 36 is missing the closing > on the ul
#
popup window is not closing after i add value using add(plus) button..and value is not updating on page, reloading page is required , help please
#
Please login first before commenting.