mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-08-18 21:49:37 -04:00
Make radio form components reusable for nested checkboxes
For the template folders permission editing we need a nested checkboxes form that is similar to "move folder" input, except it's using checkboxes instead of radio buttons. This moves most of the macros into a shared "select-input" components file, which are wrapped by the existing radios.html by setting the required input type.
This commit is contained in:
@@ -837,10 +837,7 @@ class RadioFieldWithNoneOption(FieldWithNoneOption, RadioField):
|
||||
pass
|
||||
|
||||
|
||||
class NestedRadioField(RadioFieldWithNoneOption):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
class NestedFieldMixin:
|
||||
def children(self):
|
||||
# start map with root option as a single child entry
|
||||
child_map = {None: [option for option in self
|
||||
@@ -864,6 +861,14 @@ class NestedRadioField(RadioFieldWithNoneOption):
|
||||
return child_map
|
||||
|
||||
|
||||
class NestedRadioField(RadioFieldWithNoneOption, NestedFieldMixin):
|
||||
pass
|
||||
|
||||
|
||||
class NestedCheckboxesField(SelectMultipleField, NestedFieldMixin):
|
||||
pass
|
||||
|
||||
|
||||
class HiddenFieldWithNoneOption(FieldWithNoneOption, HiddenField):
|
||||
pass
|
||||
|
||||
|
||||
@@ -1,111 +1,27 @@
|
||||
{% macro radios(
|
||||
field,
|
||||
hint=None,
|
||||
disable=[],
|
||||
option_hints={},
|
||||
hide_legend=False
|
||||
) %}
|
||||
{% call radios_wrapper(
|
||||
field, hint, disable, option_hints, hide_legend
|
||||
) %}
|
||||
{% for option in field %}
|
||||
{{ radio(option, disable, option_hints) }}
|
||||
{% endfor %}
|
||||
{% endcall %}
|
||||
{% from "components/select-input.html" import select, select_list, select_nested, select_wrapper %}
|
||||
|
||||
{% macro radios(field, hint=None, disable=[], option_hints={}, hide_legend=False) %}
|
||||
{{ select(field, hint=None, disable=[], option_hints={}, hide_legend=False, input="radio") }}
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
{% macro radio_list(
|
||||
options,
|
||||
child_map,
|
||||
disable=[],
|
||||
option_hints={}
|
||||
) %}
|
||||
<ul>
|
||||
{% for option in options %}
|
||||
{% if child_map[option.data] %}
|
||||
{% call radio(option, disable, option_hints, as_list_item=True) %}
|
||||
{{ radio_list(child_map[option.data], child_map, disable, option_hints) }}
|
||||
{% endcall %}
|
||||
{% else %}
|
||||
{{ radio(option, disable, option_hints, as_list_item=True) }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% macro radio_list(options, child_map, disable=[], option_hints={}) %}
|
||||
{{ select_list(options, child_map, disable=[], option_hints={}, input="radio") }}
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
{% macro radios_nested(
|
||||
field,
|
||||
child_map,
|
||||
hint=None,
|
||||
disable=[],
|
||||
option_hints={},
|
||||
hide_legend=False
|
||||
) %}
|
||||
{% call radios_wrapper(
|
||||
field, hint, disable, option_hints, hide_legend
|
||||
) %}
|
||||
<div class="radios-nested">
|
||||
{{ radio_list(child_map[None], child_map, disable, option_hints) }}
|
||||
</div>
|
||||
{% endcall %}
|
||||
{% macro radios_nested(field, child_map, hint=None, disable=[], option_hints={}, hide_legend=False) %}
|
||||
{{ select_nested(field, child_map, hint=None, disable=[], option_hints={}, hide_legend=False, input="radio") }}
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
{% macro radios_wrapper(field, hint=None, disable=[], option_hints={}, hide_legend=False) %}
|
||||
<div class="form-group {% if field.errors %} form-group-error{% endif %}">
|
||||
<fieldset>
|
||||
<legend class="{{ 'form-label' if not hide_legend else '' }}">
|
||||
{% if hide_legend %}<span class="visually-hidden">{% endif %}
|
||||
{{ field.label.text|safe }}
|
||||
{% if hide_legend %}</span>{% endif %}
|
||||
{% if hint %}
|
||||
<span class="form-hint">
|
||||
{{ hint }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if field.errors %}
|
||||
<span class="error-message" data-module="track-error" data-error-type="{{ field.errors[0] }}" data-error-label="{{ field.name }}">
|
||||
{{ field.errors[0] }}
|
||||
</span>
|
||||
{% endif %}
|
||||
</legend>
|
||||
{{ caller() }}
|
||||
</fieldset>
|
||||
</div>
|
||||
{{ select_wrapper(field, hint=None, disable=[], option_hints={}, hide_legend=False, input="radio") }}
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
{% macro radio(option, disable=[], option_hints={}, data_target=None, as_list_item=False) %}
|
||||
{% if as_list_item %}
|
||||
<li class="multiple-choice" {% if data_target %}data-target="{{ data_target }}"{% endif %}>
|
||||
{% else %}
|
||||
<div class="multiple-choice" {% if data_target %}data-target="{{ data_target }}"{% endif %}>
|
||||
{% endif %}
|
||||
<input
|
||||
id="{{ option.id }}" name="{{ option.name }}" type="radio" value="{{ option.data }}"
|
||||
{% if option.data in disable %}
|
||||
disabled
|
||||
{% endif %}
|
||||
{% if option.checked %}
|
||||
checked
|
||||
{% endif %}
|
||||
>
|
||||
<label class="block-label" for="{{ option.id }}">
|
||||
{{ option.label.text }}
|
||||
{% if option_hints[option.data] %}
|
||||
<div class="block-label-hint">
|
||||
{{ option_hints[option.data] }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</label>
|
||||
{% if caller %}
|
||||
{{ caller() }}
|
||||
{% endif %}
|
||||
{% if as_list_item %}
|
||||
</li>
|
||||
{% else %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{{ select_input(option, disable=[], option_hints={}, data_target=None, as_list_item=False, input="radio") }}
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
|
||||
92
app/templates/components/select-input.html
Normal file
92
app/templates/components/select-input.html
Normal file
@@ -0,0 +1,92 @@
|
||||
{% macro select(field, hint=None, disable=[], option_hints={}, hide_legend=False, input="radio") %}
|
||||
{% call select_wrapper(
|
||||
field, hint, disable, option_hints, hide_legend
|
||||
) %}
|
||||
{% for option in field %}
|
||||
{{ select_input(option, disable, option_hints, input=input) }}
|
||||
{% endfor %}
|
||||
{% endcall %}
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
{% macro select_list(options, child_map, disable=[], option_hints={}, input="radio") %}
|
||||
<ul>
|
||||
{% for option in options %}
|
||||
{% if child_map[option.data] %}
|
||||
{% call select_input(option, disable, option_hints, as_list_item=True, input=input) %}
|
||||
{{ select_list(child_map[option.data], child_map, disable, option_hints, input=input) }}
|
||||
{% endcall %}
|
||||
{% else %}
|
||||
{{ select_input(option, disable, option_hints, as_list_item=True, input=input) }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
{% macro select_nested(field, child_map, hint=None, disable=[], option_hints={}, hide_legend=False, input="radio") %}
|
||||
{% call select_wrapper(
|
||||
field, hint, disable, option_hints, hide_legend
|
||||
) %}
|
||||
<div class="{{ "radios" if input == "radio" else "checkboxes" }}-nested">
|
||||
{{ select_list(child_map[None], child_map, disable, option_hints, input=input) }}
|
||||
</div>
|
||||
{% endcall %}
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
{% macro select_wrapper(field, hint=None, disable=[], option_hints={}, hide_legend=False) %}
|
||||
<div class="form-group {% if field.errors %} form-group-error{% endif %}">
|
||||
<fieldset>
|
||||
<legend class="{{ 'form-label' if not hide_legend else '' }}">
|
||||
{% if hide_legend %}<span class="visually-hidden">{% endif %}
|
||||
{{ field.label.text|safe }}
|
||||
{% if hide_legend %}</span>{% endif %}
|
||||
{% if hint %}
|
||||
<span class="form-hint">
|
||||
{{ hint }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if field.errors %}
|
||||
<span class="error-message" data-module="track-error" data-error-type="{{ field.errors[0] }}" data-error-label="{{ field.name }}">
|
||||
{{ field.errors[0] }}
|
||||
</span>
|
||||
{% endif %}
|
||||
</legend>
|
||||
{{ caller() }}
|
||||
</fieldset>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro select_input(option, disable=[], option_hints={}, data_target=None, as_list_item=False, input="radio") %}
|
||||
{% if as_list_item %}
|
||||
<li class="multiple-choice" {% if data_target %}data-target="{{ data_target }}"{% endif %}>
|
||||
{% else %}
|
||||
<div class="multiple-choice" {% if data_target %}data-target="{{ data_target }}"{% endif %}>
|
||||
{% endif %}
|
||||
<input
|
||||
id="{{ option.id }}" name="{{ option.name }}" type="{{ input }}" value="{{ option.data }}"
|
||||
{% if option.data in disable %}
|
||||
disabled
|
||||
{% endif %}
|
||||
{% if option.checked %}
|
||||
checked
|
||||
{% endif %}
|
||||
>
|
||||
<label class="block-label" for="{{ option.id }}">
|
||||
{{ option.label.text }}
|
||||
{% if option_hints[option.data] %}
|
||||
<div class="block-label-hint">
|
||||
{{ option_hints[option.data] }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</label>
|
||||
{% if caller %}
|
||||
{{ caller() }}
|
||||
{% endif %}
|
||||
{% if as_list_item %}
|
||||
</li>
|
||||
{% else %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
Reference in New Issue
Block a user