{% macro render_hidden_errors(form) %} {%- if form.errors %} {%- for fieldname, errors in form.errors.items() %} {%- if bootstrap_is_hidden_field(form[fieldname]) %} {%- for error in errors %}
{{ error }}
{%- endfor %} {%- endif %} {%- endfor %} {%- endif %} {%- endmacro %} {% macro _hz_form_wrap(horizontal_columns, form_type, add_group=False, required=False) -%} {% if form_type == "horizontal" -%} {% if add_group %}
{% endif %}
{%- endif %} {{ caller() }} {%- if form_type == "horizontal" -%} {% if add_group %}
{% endif %}
{%- endif %} {%- endmacro %} {% macro render_field(field, form_type="basic", horizontal_columns=('lg', 2, 10), button_map={}, button_style='', button_size='', form_group_classes='') -%} {% if field.flags.required and not required in kwargs -%} {% set kwargs = dict(required=True, **kwargs) %} {%- endif %} {%- set form_group_classes = form_group_classes or config.BOOTSTRAP_FORM_GROUP_CLASSES -%} {# combine render_kw class or class/class_ argument with Bootstrap classes #} {%- set render_kw_class = ' ' + field.render_kw.class if field.render_kw.class else '' %} {%- set class = kwargs.pop('class', '') or kwargs.pop('class_', '') %} {%- if class %} {# override render_kw class when class/class_ presents as keyword argument #} {%- set render_kw_class = '' %} {%- set render_kw_class_ = '' %} {%- set class = ' ' + class %} {%- endif %} {%- set extra_classes = render_kw_class + class %} {%- if field.widget.input_type == 'checkbox' %} {% set field_kwargs = kwargs %} {% call _hz_form_wrap(horizontal_columns, form_type, True, required=required) %} {% if field.type == 'SwitchField' %} {% set _ = field_kwargs.update({'role': 'switch'}) %} {% endif %}
{%- if field.errors %} {{ field(class="form-check-input is-invalid%s" % extra_classes, **field_kwargs)|safe }} {%- else -%} {{ field(class="form-check-input%s" % extra_classes, **field_kwargs)|safe }} {%- endif %} {{ field.label(class="form-check-label", for=field.id)|safe }} {%- if field.errors %} {%- for error in field.errors %}
{{ error }}
{%- endfor %} {%- elif field.description -%} {% call _hz_form_wrap(horizontal_columns, form_type, required=required) %} {{ field.description|safe }} {% endcall %} {%- endif %}
{% endcall %} {%- elif field.type == 'RadioField' -%} {# note: A cleaner solution would be rendering depending on the widget, this is just a hack for now, until I can think of something better #}
{%- if form_type == "inline" %} {{ field.label(class="visually-hidden")|safe }} {% elif form_type == "horizontal" %} {{ field.label(class="col-form-label" + ( " col-%s-%s" % horizontal_columns[0:2]))|safe }} {%- else -%} {{ field.label(class="form-label")|safe }} {% endif %} {% if form_type == 'horizontal' %}
{% endif %} {#% call _hz_form_wrap(horizontal_columns, form_type, True, required=required) %#} {% for item in field -%}
{{ item(class="form-check-input")|safe }} {{ item.label(class="form-check-label", for=item.id)|safe }}
{% endfor %} {#% endcall %#} {% if form_type == 'horizontal' %}
{% endif %} {%- if field.errors %} {%- for error in field.errors %}
{{ error }}
{%- endfor %} {%- elif field.description -%} {{ field.description|safe }} {%- endif %}
{%- elif field.type == 'SubmitField' -%} {# deal with jinja scoping issues? #} {% set field_kwargs = kwargs %} {# note: same issue as above - should check widget, not field type #} {% call _hz_form_wrap(horizontal_columns, form_type, True, required=required) %} {% set default_button_style = button_style or config.BOOTSTRAP_BTN_STYLE %} {% set default_button_size = button_size or config.BOOTSTRAP_BTN_SIZE %} {{ field(class='btn btn-%s btn-%s%s' % (button_map.get(field.name, default_button_style), default_button_size, extra_classes), **field_kwargs) }} {% endcall %} {%- elif field.type in ['CSRFTokenField', 'HiddenField'] -%} {{ field()|safe }} {%- elif field.type in ['FormField', 'FieldList'] -%}
{{ field.label }} {%- for subfield in field %} {% if not bootstrap_is_hidden_field(subfield) -%} {{ render_field(subfield, form_type=form_type, horizontal_columns=horizontal_columns, button_map=button_map) }} {%- endif %} {%- endfor %}
{% else -%}
{%- if form_type == "inline" %} {{ field.label(class="visually-hidden")|safe }} {%- if field.type in ['DecimalRangeField', 'IntegerRangeField'] %} {% if field.errors %} {{ field(class="form-range is-invalid%s" % extra_classes, **kwargs)|safe }} {% else %} {{ field(class="form-range%s" % extra_classes, **kwargs)|safe }} {% endif %} {%- elif field.type == 'SelectField' -%} {% if field.errors %} {{ field(class="form-select mb-2 mr-sm-2 mb-sm-0 is-invalid%s" % extra_classes, **kwargs)|safe }} {% else %} {{ field(class="form-select mb-2 mr-sm-2 mb-sm-0%s" % extra_classes, **kwargs)|safe }} {% endif %} {%- else -%} {% if field.errors %} {{ field(class="form-control mb-2 mr-sm-2 mb-sm-0 is-invalid%s" % extra_classes, **kwargs)|safe }} {% else %} {{ field(class="form-control mb-2 mr-sm-2 mb-sm-0%s" % extra_classes, **kwargs)|safe }} {% endif %} {%- endif %} {% elif form_type == "horizontal" %} {{ field.label(class="col-form-label" + (" col-%s-%s" % horizontal_columns[0:2]))|safe }}
{%- if field.type in ['DecimalRangeField', 'IntegerRangeField'] %} {% if field.errors %} {{ field(class="form-range is-invalid%s" % extra_classes, **kwargs)|safe }} {% else %} {{ field(class="form-range%s" % extra_classes, **kwargs)|safe }} {% endif %} {%- elif field.type == 'SelectField' -%} {% if field.errors %} {{ field(class="form-select is-invalid%s" % extra_classes, **kwargs)|safe }} {% else %} {{ field(class="form-select%s" % extra_classes, **kwargs)|safe }} {% endif %} {%- else -%} {% if field.errors %} {{ field(class="form-control is-invalid%s" % extra_classes, **kwargs)|safe }} {% else %} {{ field(class="form-control%s" % extra_classes, **kwargs)|safe }} {% endif %} {%- endif %}
{%- if field.errors %} {%- for error in field.errors %} {% call _hz_form_wrap(horizontal_columns, form_type, required=required) %}
{{ error }}
{% endcall %} {%- endfor %} {%- elif field.description -%} {% call _hz_form_wrap(horizontal_columns, form_type, required=required) %} {{ field.description|safe }} {% endcall %} {%- endif %} {%- else -%} {{ field.label(class="form-label")|safe }} {%- if field.type in ['DecimalRangeField', 'IntegerRangeField'] %} {% if field.errors %} {{ field(class="form-range is-invalid%s" % extra_classes, **kwargs)|safe }} {% else %} {{ field(class="form-range%s" % extra_classes, **kwargs)|safe }} {% endif %} {%- elif field.type == 'SelectField' -%} {% if field.errors %} {{ field(class="form-select is-invalid%s" % extra_classes, **kwargs)|safe }} {% else %} {{ field(class="form-select%s" % extra_classes, **kwargs)|safe }} {% endif %} {%- else -%} {% if field.errors %} {{ field(class="form-control is-invalid%s" % extra_classes, **kwargs)|safe }} {% else %} {{ field(class="form-control%s" % extra_classes, **kwargs)|safe }} {% endif %} {%- endif %} {%- if field.errors %} {%- for error in field.errors %}
{{ error }}
{%- endfor %} {%- elif field.description -%} {{ field.description|safe }} {%- endif %} {%- endif %}
{% endif %} {%- endmacro %} {# valid form types are "basic", "inline" and "horizontal" #} {% macro render_form(form, action="", method="post", extra_classes=None, role="form", form_type="basic", horizontal_columns=('lg', 2, 10), enctype=None, button_map={}, button_style="", button_size="", id="", novalidate=False, render_kw={}, form_group_classes='', form_inline_classes='') -%} {%- set form_inline_classes = form_inline_classes or config.BOOTSTRAP_FORM_INLINE_CLASSES %} {%- set _enctype = [] %} {%- if enctype is none %} {%- for field in form %} {%- if field.type in ['FileField', 'MultipleFileField'] %} {#- for loops come with a fairly watertight scope, so this list-hack is used to be able to set values outside of it #} {%- set _ = _enctype.append('multipart/form-data') %} {%- endif %} {%- endfor %} {%- else %} {%- set _ = _enctype.append(enctype) %} {%- endif %} {%- if form_type == "inline" %}{% set form_group_classes = 'col-12' %}{% endif %}
{{ render_hidden_errors(form) }} {%- for field in form %} {{ render_field(field, form_type=form_type, horizontal_columns=horizontal_columns, button_map=button_map, button_style=button_style, button_size=button_size, form_group_classes=form_group_classes) }} {%- endfor %}
{%- endmacro %} {% macro render_form_row(fields, row_class='row', col_class_default='col', col_map={}, button_map={}, button_style='', button_size='', form_group_classes='', form_type='basic', horizontal_columns=('lg', 2, 10)) %}
{% for field in fields %} {% if field.name in col_map %} {% set col_class = col_map[field.name] %} {% else %} {% set col_class = col_class_default %} {% endif %}
{{ render_field(field, button_map=button_map, button_style=button_style, button_size=button_size, form_group_classes=form_group_classes, form_type=form_type, horizontal_columns=horizontal_columns) }}
{% endfor %}
{% endmacro %}