Add NamedMultiWidget class
Works as Django's MultiWidget but instead of a list of subwidgets, uses a dictionary of subwidgets with names as the keys. The named nature is less error prone than Django's index numbered subwidgets. Signed-off-by: Roberto Rosario <Roberto.Rosario@mayan-edms.com>
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from collections import OrderedDict
|
||||
|
||||
from django import forms
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
@@ -20,6 +22,86 @@ class DisableableSelectWidget(forms.widgets.SelectMultiple):
|
||||
return result
|
||||
|
||||
|
||||
class NamedMultiWidget(forms.widgets.Widget):
|
||||
template_name = 'django/forms/widgets/multiwidget.html'
|
||||
|
||||
def __init__(self, widgets, attrs=None):
|
||||
self.widgets = OrderedDict()
|
||||
for name, widget in widgets.items():
|
||||
self.widgets[name] = widget() if isinstance(widget, type) else widget
|
||||
|
||||
super(NamedMultiWidget, self).__init__(attrs)
|
||||
|
||||
def _get_media(self):
|
||||
"Media for a multiwidget is the combination of all media of the subwidgets"
|
||||
media = forms.widgets.Media()
|
||||
for name, widget in self.widgets.items():
|
||||
media = media + widget.media
|
||||
return media
|
||||
media = property(_get_media)
|
||||
|
||||
@property
|
||||
def is_hidden(self):
|
||||
return all(widget.is_hidden for name, widget in self.widgets.items())
|
||||
|
||||
def get_context(self, name, value, attrs):
|
||||
context = super(NamedMultiWidget, self).get_context(name, value, attrs)
|
||||
if self.is_localized:
|
||||
for widget in self.widgets:
|
||||
widget.is_localized = self.is_localized
|
||||
|
||||
value = self.decompress(value)
|
||||
|
||||
final_attrs = context['widget']['attrs']
|
||||
input_type = final_attrs.pop('type', None)
|
||||
id_ = final_attrs.get('id')
|
||||
subwidgets = []
|
||||
for widget_name, widget in self.widgets.items():
|
||||
if input_type is not None:
|
||||
widget.input_type = input_type
|
||||
full_widget_name = '%s_%s' % (name, widget_name)
|
||||
try:
|
||||
widget_value = value[widget_name]
|
||||
except IndexError:
|
||||
widget_value = None
|
||||
if id_:
|
||||
widget_attrs = final_attrs.copy()
|
||||
widget_attrs['id'] = '%s_%s' % (id_, widget_name)
|
||||
else:
|
||||
widget_attrs = final_attrs
|
||||
subwidgets.append(
|
||||
widget.get_context(
|
||||
full_widget_name, widget_value, widget_attrs
|
||||
)['widget']
|
||||
)
|
||||
context['widget']['subwidgets'] = subwidgets
|
||||
return context
|
||||
|
||||
def id_for_label(self, id_):
|
||||
if id_:
|
||||
id_ += '_{}'.format(self.widgets.keys()[0])
|
||||
return id_
|
||||
|
||||
def value_from_datadict(self, data, files, name):
|
||||
return {
|
||||
name: widget.value_from_datadict(
|
||||
data, files, name + '_%s' % name
|
||||
) for name, widget in self.widgets.items()
|
||||
}
|
||||
|
||||
def value_omitted_from_data(self, data, files, name):
|
||||
return all(
|
||||
widget.value_omitted_from_data(data, files, name + '_%s' % name)
|
||||
for name, widget in self.widgets.items()
|
||||
)
|
||||
|
||||
@property
|
||||
def needs_multipart_form(self):
|
||||
return any(
|
||||
widget.needs_multipart_form for name, widget in self.widgets.items()
|
||||
)
|
||||
|
||||
|
||||
class PlainWidget(forms.widgets.Widget):
|
||||
"""
|
||||
Class to define a form widget that effectively nulls the htmls of a
|
||||
|
||||
Reference in New Issue
Block a user