Skip to main content
brickwork
GitHub Log in Get started
Display
Theme
Density
Direction
Brand

Documentation

Components / Foundations

Forms

Accessible Django field chrome and whole-form layout, with a real HTMX 422 validation loop.

Live demonstration

Use it

Read the pinned package source

  1. Wrap the tag in a consumer-owned form with CSRF protection and a submit control.
  2. For HTMX, target the form itself and re-render this same fragment on invalid input with HTTP 422.
  3. On valid input redirect or return a deterministic success response. Do not return a partial into a full-page non-HTMX request.
{% load i18n brickwork_forms %}
<form id="foundation-form" method="post" action="{% url 'components:foundation_form_submit' %}" hx-post="{% url 'components:foundation_form_submit' %}" hx-target="this" hx-swap="outerHTML">
  {% csrf_token %}
  {% bw_form form layout="grid" grid_columns=2 rows=rows density="comfortable" %}
  <button class="bw-btn bw-btn--primary" type="submit">{% translate "Validate example" %}</button>
</form>

Python context

from django import forms

class ContactForm(forms.Form):
    name = forms.CharField(label="Name", max_length=80)
    email = forms.EmailField(label="Work email")
    updates = forms.BooleanField(required=False, widget=forms.CheckboxInput(attrs={"class": "bw-toggle"}))

form = ContactForm()
rows = [["name", "email"], ["updates"]]

Public API

NameSignature or valuesContract
bw_field_widgetBoundField, readonly=FalseRenders one widget with input-level error and description wiring.
bw_formform, layout='stacked', grid_columns=2, rows=None, density='', readonly=FalseRenders visible fields only. It never emits a form element.
layoutstacked | gridGrid preserves source and tab order.
density'' | compact | comfortable | spaciousA scoped form density override.
rowssequence[str | sequence[str]]Groups named fields without dropping unmentioned fields.

Accessibility and no-JavaScript behaviour

The tag associates help and error regions with the actual input. The toggle widget keeps native checkbox semantics and adds switch role only when opted in.

The form submits normally and receives a full-page response. HTMX only replaces the same form region when available.

Troubleshooting

Errors are not announced.
Render the same bound form fragment after validation. Do not replace only an error summary.
An invalid HTMX response disappears.
Keep the application's HTMX 422 responseHandling entry and return status 422.
Documentation