Skip to content

Instantly share code, notes, and snippets.

@MasterAlish
Last active October 1, 2015 23:05
Show Gist options
  • Save MasterAlish/1729941a0b1b69ff5a54 to your computer and use it in GitHub Desktop.
Save MasterAlish/1729941a0b1b69ff5a54 to your computer and use it in GitHub Desktop.
Django Forms Filed for Multiple choice with number field for each choice
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