Last active
October 1, 2015 23:05
-
-
Save MasterAlish/1729941a0b1b69ff5a54 to your computer and use it in GitHub Desktop.
Django Forms Filed for Multiple choice with number field for each choice
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class CheckboxChoiceWithNumberInput(forms.widgets.CheckboxChoiceInput): | |
def render(self, name=None, value=None, attrs=None, choices=()): | |
if self.id_for_label: | |
label_for = format_html(u' for="{0}"', self.id_for_label) | |
else: | |
label_for = u'' | |
return format_html(u'{1}<label{0}> {2}</label> <input type="number" value="0" name="{3}_number[{4}]"/>', label_for, self.tag(), self.choice_label, self.name, self.choice_value) | |
class CheckboxWithNumberFieldRenderer(forms.widgets.CheckboxFieldRenderer): | |
choice_input_class = CheckboxChoiceWithNumberInput | |
class CheckboxSelectMultipleWithNumber(forms.widgets.CheckboxSelectMultiple): | |
renderer = CheckboxWithNumberFieldRenderer | |
_empty_value = [] | |
def get_html_input_dict(self, query_dict, param): | |
import re | |
dictionary = {} | |
regex = re.compile('%s\[([\w\d_]+)\]' % param) | |
for key, value in query_dict.items(): | |
match = regex.match(key) | |
if match: | |
inner_key = match.group(1) | |
dictionary[inner_key] = value | |
return dictionary | |
def value_from_datadict(self, data, files, name): | |
values = super(CheckboxSelectMultipleWithNumber, self).value_from_datadict(data, files, name) | |
numbers = self.get_html_input_dict(data, u"%s_number" % name) | |
values_with_numbers = {} | |
for value in values: | |
values_with_numbers[value] = int(numbers[value]) | |
return values_with_numbers | |
class MultipleChoiceWithNumberField(forms.MultipleChoiceField): | |
widget = CheckboxSelectMultipleWithNumber | |
def to_python(self, value): | |
if not value: | |
return {} | |
elif not isinstance(value, dict): | |
raise forms.ValidationError("Enter a valid dict", code='invalid_dict') | |
return value | |
#------------------------------------------------------ | |
# Usage: | |
options = ( | |
('22', 'IBM22'), | |
('1', 'IBM2'), | |
('2', 'IBM3'), | |
('3', 'IBM4'), | |
('4', 'IBM5'), | |
('5', 'IBM6'), | |
) | |
class MyForm(forms.Form): | |
models = MultipleChoiceWithNumberField(choices=options) | |
#------------------------------------------------------ | |
# After validating form: | |
if form.is_valid(): | |
models = form.cleaned_data["models"] | |
# you will get dict with selected values and numbers for each them | |
{u'22': 100, u'4': 120, u'5': 222} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment