(default: "mb-3")
----------------------------------------------------------------------- #}
{% macro render_field(field, label_class="form-label", input_class="form-control", wrapper_class="mb-3") %}
{% if field.name.startswith('_') %}
{# Hidden sentinel fields — render silently so their validators still fire #}
{{ field(type="hidden") }}
{% else %}
{% set is_checkbox = field.type == "BooleanField" %}
{% set is_hidden = field.type == "HiddenField" %}
{% set has_errors = field.errors | length > 0 %}
{% if is_hidden %}
{{ field() }}
{% elif is_checkbox %}
{% else %}
{{ field.label(class=label_class) }}
{# Linked-file lookup: wrap the input in an input-group with a 🔍 button #}
{% set is_lookup = field.render_kw and field.render_kw.get('data-lookup-file') %}
{% if field.type == "TextAreaField" or field.type == "MVTextAreaField" %}
{{ field(class=input_class + (" is-invalid" if has_errors else ""), rows=4) }}
{% elif field.type == "SelectField" %}
{{ field(class="form-select" + (" is-invalid" if has_errors else "")) }}
{% elif is_lookup %}
{{ field(class=input_class + (" is-invalid" if has_errors else "")) }}
🔍
{% else %}
{{ field(class=input_class + (" is-invalid" if has_errors else "")) }}
{% endif %}
{% if field.description %}
{{ field.description }}
{% endif %}
{% for error in field.errors %}
{{ error }}
{% endfor %}
{% endif %}
{% endif %}
{% endmacro %}
{# -----------------------------------------------------------------------
render_mv_fieldlist(field, add_label, input_class, wrapper_class)
Renders an MVFieldList as a dynamic add/remove repeater.
Requires the companion JavaScript (uofast_forms.js) for add/remove
to work client-side.
Args:
field An MVFieldList WTForms field
add_label Label for the "Add row" button (default: "+ Add")
input_class CSS class for each row input (default: "form-control")
wrapper_class CSS class for the outer container (default: "mb-3")
----------------------------------------------------------------------- #}
{% macro render_mv_fieldlist(field, add_label="+ Add", input_class="form-control", wrapper_class="mb-3") %}
{% set has_errors = field.errors | length > 0 %}
{{ field.label.text }}
{% if field.description %}
{{ field.description }}
{% endif %}
{% for entry in field.entries %}
{% if entry.value.type == "SelectField" %}
{{ entry.value(class="form-select") }}
{% else %}
{{ entry.value(class=input_class) }}
{% endif %}
×
{% for error in entry.value.errors %}
{{ error }}
{% endfor %}
{% endfor %}
{{ add_label }}
{% for error in field.errors %}
{{ error }}
{% endfor %}
{% endmacro %}
{# -----------------------------------------------------------------------
render_form(form, action, method, submit_label, css_class, enctype)
Renders the full
{% endmacro %}