{% comment %} A single, presentational form field: one control plus an optional label, help text, and errors. It renders entirely from explicit attributes — to render a whole Django form use instead. type — any text-like input (text, email, tel, password, number, date, …) plus textarea, select, file, checkbox, radio and toggle. label, help-text and errors accept an attribute or a named slot of the same name (a slot allows rich content, e.g. badges inside the label). errors also accepts a list (e.g. :errors="form.email.errors") and switches the control to its error style. The default slot fills the textarea value, the select options, or extra content inside a text input (e.g. a hint). Everything else (name, id, value, placeholder, required, disabled, checked, rows, …) passes straight through to the control element. {% endcomment %} {% comment %} The fieldset wrapper only renders when there is something to put in it, so a bare field stays a single control that composes inside joins and toolbars. Check-style controls carry their label inline, so they never need a legend. {% endcomment %} {% if type == "checkbox" or type == "radio" or type == "toggle" %} {% firstof help_text errors as wrapped %} {% firstof "" as legend %} {% else %} {% firstof label help_text errors as wrapped %} {% firstof label as legend %} {% endif %} {# djlint:off #} {% if wrapped %}
{% if legend %} {% endif %} {% endif %} {% if type == "textarea" %} {% elif type == "select" %} {% elif type == "file" %} {% elif type == "checkbox" or type == "radio" or type == "toggle" %} {% else %} {% endif %} {% if wrapped %} {% if help_text %}

{{ help_text }}

{% endif %} {% if errors %}

{% if errors == errors|stringformat:"s" %} {{ errors }} {% else %} {% for error in errors %}{{ error }}{% if not forloop.last %}
{% endif %}{% endfor %} {% endif %}

{% endif %}
{% endif %} {# djlint:on #}