|
|
|
|
@ -27,8 +27,36 @@ from events.common import MEMBERS, VISITORS, PRICE |
|
|
|
|
from events.common import members_mapping, visitors_mapping, price_mapping |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class FilterCheckboxSelectMultiple(forms.CheckboxSelectMultiple): |
|
|
|
|
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) |
|
|
|
|
output = ['<ul>'] |
|
|
|
|
# Normalize to strings |
|
|
|
|
str_values = set([force_text(v) for v in value]) |
|
|
|
|
for i, (option_value, option_label) in enumerate(chain(self.choices, choices)): |
|
|
|
|
# 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 = format_html(u' for="{0}"', final_attrs['id']) |
|
|
|
|
else: |
|
|
|
|
label_for = '' |
|
|
|
|
|
|
|
|
|
cb = forms.CheckboxInput(final_attrs, check_test=lambda value: value in str_values) |
|
|
|
|
option_value = force_text(option_value) |
|
|
|
|
rendered_cb = cb.render(name, option_value) |
|
|
|
|
option_label = force_text(option_label) |
|
|
|
|
output.append(format_html(u'<li>{1}<label{0}>{2}</label></li>', |
|
|
|
|
label_for, rendered_cb, option_label)) |
|
|
|
|
output.append(u'</ul>') |
|
|
|
|
return mark_safe('\n'.join(output)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CountModelMultipleChoiceField(forms.ModelMultipleChoiceField): |
|
|
|
|
widget = forms.CheckboxSelectMultiple |
|
|
|
|
# widget = forms.CheckboxSelectMultiple |
|
|
|
|
widget = FilterCheckboxSelectMultiple |
|
|
|
|
def label_from_instance(self, obj): |
|
|
|
|
if obj.get('count', None) is None: |
|
|
|
|
return smart_text(obj.get('name')) |
|
|
|
|
@ -62,6 +90,14 @@ class CountModelMultipleChoiceField(forms.ModelMultipleChoiceField): |
|
|
|
|
self.run_validators(value) |
|
|
|
|
return pks |
|
|
|
|
|
|
|
|
|
def widget_attrs(self, widget): |
|
|
|
|
""" |
|
|
|
|
Given a Widget instance (*not* a Widget class), returns a dictionary of |
|
|
|
|
any HTML attributes that should be added to the Widget, based on this |
|
|
|
|
Field. |
|
|
|
|
""" |
|
|
|
|
return {'class': 'default'} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fields_mapping = { |
|
|
|
|
'members': 'members_choice', |
|
|
|
|
@ -87,7 +123,7 @@ class FilterForm(forms.Form): |
|
|
|
|
# PRICE = PRICE |
|
|
|
|
model = forms.TypedMultipleChoiceField( |
|
|
|
|
label=_(u'Тип события'), coerce=int, |
|
|
|
|
choices=TYPES, required=False, widget=forms.CheckboxSelectMultiple()) |
|
|
|
|
choices=TYPES, required=False, widget=FilterCheckboxSelectMultiple()) |
|
|
|
|
theme = CountModelMultipleChoiceField( |
|
|
|
|
label=_(u'Тематики'), required=False, |
|
|
|
|
queryset=Theme.objects.language().values('pk', 'name')) |
|
|
|
|
@ -103,16 +139,16 @@ class FilterForm(forms.Form): |
|
|
|
|
price = forms.TypedMultipleChoiceField( |
|
|
|
|
label=_(u'Стоимость'), coerce=int, |
|
|
|
|
choices=PRICE, |
|
|
|
|
required=False, widget=forms.CheckboxSelectMultiple(), |
|
|
|
|
required=False, widget=FilterCheckboxSelectMultiple(), |
|
|
|
|
help_text=_(u'За 1 м<sub>2</sub> необорудованной площади')) |
|
|
|
|
members = forms.TypedMultipleChoiceField( |
|
|
|
|
label=_(u'Участники'), coerce=int, |
|
|
|
|
choices=MEMBERS, |
|
|
|
|
required=False, widget=forms.CheckboxSelectMultiple()) |
|
|
|
|
required=False, widget=FilterCheckboxSelectMultiple()) |
|
|
|
|
visitors = forms.TypedMultipleChoiceField( |
|
|
|
|
label=_(u'Посетители'), coerce=int, |
|
|
|
|
choices=VISITORS, |
|
|
|
|
required=False, widget=forms.CheckboxSelectMultiple()) |
|
|
|
|
required=False, widget=FilterCheckboxSelectMultiple()) |
|
|
|
|
|
|
|
|
|
def __init__(self, *args, **kwargs): |
|
|
|
|
super(FilterForm, self).__init__(*args, **kwargs) |
|
|
|
|
|