Pattern: multi-step wizard
Who uses it: whoever is creating something too long for
one screen, guided rather than dropped into a form — most often a
first-time or occasional flow. What "done" looks like:
every step completed or explicitly skippable, submitted once, and
resumable if abandoned partway. A real multi-step flow — one
panel visible at a time, Back/Next move
between them — as opposed to detail form's
multi-section single screen. Composed from the existing
.bo-stepper progress indicator plus a new opt-in behavior,
initWizard(), that keeps the stepper and the visible panel in sync
and moves focus to each new panel — the panels themselves are plain
.bo-form-section fieldsets, nothing new to learn there.
Not for a routine single-step task — if there is nothing
to walk someone through, a wizard's Back/Next scaffolding is friction with
no payoff; use a plain detail
form instead. Its Next/Submit pair is the one legitimate
two-primary-action layout in this system precisely because it exists to
gate a guided multi-step flow, not a single screen.
- 1 Vendor
- 2 Line items
- 3 Review
Wizards require initWizard() —
wired below. Panels 2+ carry a static hidden attribute, so
without it they stay hidden rather than all rendering at once — but
Back/Next never fire and Submit never un-hides, so the wizard cannot be
completed. See the States table's "No JS" row.
Anatomy
- Stepper — where you are, what is done, what is left. Not in this demo: clicking a completed step to jump back. `initWizard()` only wires Back/Next today; the markers here are plain, not buttons.
- Step panel — one form per step, each independently valid.
- Footer navigation — Back / Next, with Next as the form’s submit so Enter works.
- Resume affordance — a wizard nobody can resume is a wizard people abandon.
Data contract
| Request | Returns / on failure |
|---|---|
| POST /wizard/:id/step/:n | the NEXT step fragment on success; 422 → this step re-rendered with errors and values |
| GET /wizard/:id | resume at the furthest completed step |
| POST /wizard/:id/finish | the created record; wizard state is discarded server-side only after this succeeds |
States
| State | What ships |
|---|---|
| Step invalid | stay on the step; focus the first invalid field — never advance and report later |
| Partial persistence | each step posts as it completes, so a closed tab loses at most one step |
| Back navigation | values preserved; going back must never clear later steps silently |
| Abandoned / resumed | reopening lands on the furthest completed step with a note of what remains |
| Final submit | disable the whole footer while posting — a double-submitted wizard creates two records |
| Cross-step validation | if step 3 invalidates step 1, say WHICH step and link back to it |
| No JS | panels 2+ stay hidden (native hidden, not a JS toggle), so the form reads correctly, but Back/Next never fire and Submit never un-hides — the wizard cannot be completed |
Components used
complexity 3 of 4