data-wizard

Multi-step form wizard with per-step validation, conditional steps, and progress tracking. Add data-wizard to a form to split fieldsets into navigable steps.

Overview

The data-wizard attribute transforms a standard form with multiple fieldsets into a multi-step wizard. Each <fieldset data-wizard-step> becomes a navigable step with per-step validation, conditional visibility, and progress tracking. This page is an attribute-focused API reference.

For full walkthroughs and pattern examples, see the Wizard Pattern page.

<form data-wizard> <fieldset data-wizard-step> <legend>Account</legend> <input name="email" type="email" required> </fieldset> <fieldset data-wizard-step> <legend>Profile</legend> <input name="name" required> </fieldset> <nav data-wizard-nav> <button type="button" data-wizard-prev>Back</button> <button type="button" data-wizard-next>Next</button> <button type="submit">Submit</button> </nav> </form>

How It Works

Add data-wizard to a <form> containing multiple <fieldset data-wizard-step> elements. The init script:

  1. Discovers all [data-wizard-step] fieldsets within the form
  2. Shows the first step and hides the rest with data-wizard-active / data-wizard-hidden
  3. Wires up data-wizard-prev and data-wizard-next buttons for navigation
  4. Validates the current step's fields before advancing (native constraint validation)
  5. Evaluates data-wizard-if conditions to skip inapplicable steps
  6. Updates <progress> and external nav.steps if connected
  7. Sets data-wizard-enhanced on the form to prevent double-binding

The submit button is only enabled on the final step. On earlier steps, clicking Next validates the current step before proceeding.

Attributes

Attribute Element Description
data-wizard <form> Enables wizard behavior on the form.
data-wizard-step <fieldset> Marks a fieldset as a wizard step.
data-wizard-progress <progress> Auto-updated progress bar. Value reflects current step / total steps.
data-wizard-nav <nav> Container for navigation buttons. The wizard manages button visibility.
data-wizard-prev <button> Go to previous step. Hidden on the first step.
data-wizard-next <button> Go to next step (validates current step first). Hidden on the last step.
data-wizard-if <fieldset> Conditional step. Formats: "name:value", "name:!value", "name", "!name".
data-wizard-optional <fieldset> Step can be skipped without validation.
data-wizard-steps <form> CSS selector for an external nav.steps element to sync as progress nav.
data-wizard-enhanced <form> Auto-set after init. Do not set manually.
data-wizard-active / data-wizard-hidden <fieldset> Auto-set to mark the visible step and hide inactive steps.
data-wizard-current / data-wizard-total <form> Auto-set with current step index (1-based) and total visible steps.
data-wizard-last <form> Auto-set when on the final step.

Progress Bar

Add a <progress data-wizard-progress> element inside the form. The wizard sets its value and max attributes automatically as the user navigates.

<form data-wizard> <progress data-wizard-progress></progress> <!-- steps... --> </form>

Conditional Steps

Use data-wizard-if on a fieldset to make it conditional. The step is only included in the wizard flow when the condition matches. Skipped steps do not count toward the total and their validation is bypassed. Four condition formats are supported:

  • name:value — show when field equals value
  • name:!value — show when field does not equal value
  • name — show when field has any truthy value
  • !name — show when field is empty or unchecked
<fieldset data-wizard-step data-wizard-if="account-type:business"> <legend>Business Details</legend> <!-- Only shown when account-type field = business --> </fieldset>

External Steps Navigation

Use data-wizard-steps on the form with a CSS selector pointing to an external nav.steps element. The wizard synchronizes the nav's list items with the current step, applying aria-current="step" to the active item. The nav can be placed anywhere on the page.

<form data-wizard data-wizard-steps="#progress-nav"> <!-- steps... --> </form> <nav class="steps" id="progress-nav" aria-label="Progress"> <ol> <li>Account</li> <li>Profile</li> <li>Review</li> </ol> </nav>

Events

Event Detail Description
wizard:stepchange { from, to } Fired on step navigation. Indices are 0-based.
wizard:complete Fired when the form is submitted from the final step.
wizard:reset Fired when the wizard is reset to the first step.
const form = document.querySelector('[data-wizard]'); form.addEventListener('wizard:stepchange', (e) => { console.log('Moved from step', e.detail.from, 'to', e.detail.to); }); form.addEventListener('wizard:complete', () => { console.log('Wizard submitted'); });

JavaScript API

The wizard adds navigation methods directly to the form element:

  • form.wizardNext() — advance to next step (validates current step first)
  • form.wizardPrev() — go back to previous step (no validation)
  • form.wizardGoTo(index) — jump to step by 0-based index
  • form.wizardReset() — reset to first step and clear progress
const form = document.querySelector('[data-wizard]'); form.wizardNext(); // Go to next step (validates first) form.wizardPrev(); // Go to previous step form.wizardGoTo(2); // Jump to step index 2 form.wizardReset(); // Reset to first step

Styling

Step visibility is controlled via data-wizard-active and data-wizard-hidden attributes. Nav buttons are automatically shown or hidden based on step position.

/* Active step */ [data-wizard-step][data-wizard-active] { display: block; } /* Hidden steps */ [data-wizard-step][data-wizard-hidden] { display: none; } /* Progress bar */ [data-wizard] progress[data-wizard-progress] { width: 100%; }

All behavior is gated on data-wizard-enhanced. Without JavaScript, all fieldsets are visible and the form submits normally — progressive enhancement.

Accessibility

  • A live region announces the current step (e.g., "Step 2 of 3") when navigating
  • External nav.steps uses aria-current="step" on the active step
  • Hidden steps are removed from tab order so keyboard users only interact with the active step
  • Per-step validation prevents advancing past incomplete steps with immediate feedback
  • The <progress> element provides a native accessible progress indicator
  • Back is hidden on the first step; Submit is only visible on the final step
  • Without JavaScript, all fieldsets are visible and the form submits as one page

See Also

Wizard Pattern — full walkthroughs, layout examples, and step-by-step tutorials.