Add render method to ThemableCheckboxSelectMultiple
Django 1.11+ doesn't have RenderMixin class for widgets, so we have to
implement render method for ThemableCheckboxSelectMultiple to get it
rendered in a correct way with all supported Django versions until we
find a better solution for our widgets implementation.
Change-Id: I656afb162e130f2b77853368945b74330bedf747
Closes-Bug: #1715066
(cherry picked from commit c13d6da80e
)
This commit is contained in:
parent
39d863ec23
commit
2ab0ea8c6a
|
@ -527,10 +527,14 @@ class ThemableCheckboxChoiceInput(ChoiceInput):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(ThemableCheckboxChoiceInput, self).__init__(*args, **kwargs)
|
super(ThemableCheckboxChoiceInput, self).__init__(*args, **kwargs)
|
||||||
self.value = set(force_text(v) for v in self.value)
|
# NOTE(e0ne): Django sets default value to None
|
||||||
|
if self.value:
|
||||||
|
self.value = set(force_text(v) for v in self.value)
|
||||||
|
|
||||||
def is_checked(self):
|
def is_checked(self):
|
||||||
return self.choice_value in self.value
|
if self.value:
|
||||||
|
return self.choice_value in self.value
|
||||||
|
return False
|
||||||
|
|
||||||
def render(self, name=None, value=None, attrs=None, choices=()):
|
def render(self, name=None, value=None, attrs=None, choices=()):
|
||||||
if self.id_for_label:
|
if self.id_for_label:
|
||||||
|
@ -545,43 +549,23 @@ class ThemableCheckboxChoiceInput(ChoiceInput):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# NOTE(adriant): CheckboxFieldRenderer was removed in Django 1.11 so
|
class ThemableCheckboxSelectMultiple(widgets.CheckboxSelectMultiple):
|
||||||
# has been moved here until we redo how we handle widgets.
|
choice_input_class = ThemableCheckboxChoiceInput
|
||||||
@html.html_safe
|
_empty_value = []
|
||||||
@python_2_unicode_compatible
|
|
||||||
class CheckboxFieldRenderer(object):
|
|
||||||
"""CheckboxFieldRenderer class from django 1.10.7 codebase
|
|
||||||
|
|
||||||
An object used by RadioSelect to enable customization of radio widgets.
|
|
||||||
"""
|
|
||||||
|
|
||||||
choice_input_class = None
|
|
||||||
outer_html = '<ul{id_attr}>{content}</ul>'
|
outer_html = '<ul{id_attr}>{content}</ul>'
|
||||||
inner_html = '<li>{choice_value}{sub_widgets}</li>'
|
inner_html = '<li>{choice_value}{sub_widgets}</li>'
|
||||||
|
|
||||||
def __init__(self, name, value, attrs, choices):
|
def render(self, name=None, value=None, attrs=None):
|
||||||
self.name = name
|
|
||||||
self.value = value
|
|
||||||
self.attrs = attrs
|
|
||||||
self.choices = choices
|
|
||||||
|
|
||||||
def __getitem__(self, idx):
|
|
||||||
return list(self)[idx]
|
|
||||||
|
|
||||||
def __iter__(self):
|
|
||||||
for idx, choice in enumerate(self.choices):
|
|
||||||
yield self.choice_input_class(
|
|
||||||
self.name, self.value, self.attrs.copy(), choice, idx)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.render()
|
|
||||||
|
|
||||||
def render(self):
|
|
||||||
"""Outputs a <ul> for this set of choice fields.
|
"""Outputs a <ul> for this set of choice fields.
|
||||||
|
|
||||||
If an id was given to the field, it is applied to the <ul> (each
|
If an id was given to the field, it is applied to the <ul> (each
|
||||||
item in the list will get an id of `$id_$i`).
|
item in the list will get an id of `$id_$i`).
|
||||||
"""
|
"""
|
||||||
|
attrs = {} or attrs
|
||||||
|
self.attrs = attrs
|
||||||
|
self.name = name
|
||||||
|
self.value = value
|
||||||
|
|
||||||
id_ = self.attrs.get('id')
|
id_ = self.attrs.get('id')
|
||||||
output = []
|
output = []
|
||||||
for i, choice in enumerate(self.choices):
|
for i, choice in enumerate(self.choices):
|
||||||
|
@ -615,15 +599,6 @@ class CheckboxFieldRenderer(object):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class ThemableCheckboxFieldRenderer(CheckboxFieldRenderer):
|
|
||||||
choice_input_class = ThemableCheckboxChoiceInput
|
|
||||||
|
|
||||||
|
|
||||||
class ThemableCheckboxSelectMultiple(widgets.CheckboxSelectMultiple):
|
|
||||||
renderer = ThemableCheckboxFieldRenderer
|
|
||||||
_empty_value = []
|
|
||||||
|
|
||||||
|
|
||||||
class ExternalFileField(fields.FileField):
|
class ExternalFileField(fields.FileField):
|
||||||
"""Special FileField to upload file to some external location.
|
"""Special FileField to upload file to some external location.
|
||||||
|
|
||||||
|
|
|
@ -715,6 +715,13 @@ class SetNetworkAction(workflows.Action):
|
||||||
|
|
||||||
def __init__(self, request, *args, **kwargs):
|
def __init__(self, request, *args, **kwargs):
|
||||||
super(SetNetworkAction, self).__init__(request, *args, **kwargs)
|
super(SetNetworkAction, self).__init__(request, *args, **kwargs)
|
||||||
|
|
||||||
|
# NOTE(e0ne): we don't need 'required attribute for networks
|
||||||
|
# checkboxes to be able to select only one network
|
||||||
|
# NOTE(e0ne): we need it for compatibility with different
|
||||||
|
# Django versions (prior to 1.11)
|
||||||
|
self.use_required_attribute = False
|
||||||
|
|
||||||
network_list = self.fields["network"].choices
|
network_list = self.fields["network"].choices
|
||||||
if len(network_list) == 1:
|
if len(network_list) == 1:
|
||||||
self.fields['network'].initial = [network_list[0][0]]
|
self.fields['network'].initial = [network_list[0][0]]
|
||||||
|
|
Loading…
Reference in New Issue