A lightweight wizard UI component that supports accessibility and HTML5 in Vanilla JavaScript.
data-require-if
attribute.on-active-required
class.You can install the package via npm:
npm install @adrii_/wizard-js
For CDN usage:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/AdrianVillamayor/Wizard-JS@2.0.3/dist/main.min.css">
<script src="https://cdn.jsdelivr.net/gh/AdrianVillamayor/Wizard-JS@2.0.3/dist/index.js"></script>
const Wizard = require('@adrii_/wizard-js');
const myWizard = new Wizard({
/* your configuration here */
});
myWizard.init();
import Wizard from '@adrii_/wizard-js';
const myWizard = new Wizard({
/* your configuration here */
});
myWizard.init();
For content-only wizards:
<div class="wizard">
<aside class="wizard-content container">
<div class="wizard-step">
<!-- Step content -->
</div>
<!-- More steps -->
</aside>
</div>
For wizards with form purpose, it manages the required fields and validates them:
<form class="wizard" method="POST">
<aside class="wizard-content container">
<div class="wizard-step">
<input type="text" name="name" class="required" placeholder="Enter a short campaign name">
</div>
<!-- More steps -->
</aside>
</form>
To launch the wizard:
let args = {
"wz_class": ".wizard",
"wz_nav_style": "dots",
"wz_button_style": ".btn .btn-sm .mx-3",
"wz_ori": "vertical",
"buttons": true,
"navigation": 'buttons',
"finish": "Save!"
};
const wizard = new Wizard(args);
wizard.init();
To restart the wizard:
wizard.reset();
To update the wizard, deleting or adding steps:
wizard.update();
To lock the wizard at a specific step:
wizard.lock();
To unlock the wizard:
wizard.unlock();
Wizard-JS includes built-in form validation for required fields.
To mark an input as required, add the required
attribute or the required
class:
<input type="text" name="email" required>
<!-- or -->
<input type="text" name="email" class="required">
You can make fields conditionally required based on the value of another field using the data-require-if
attribute.
The format is data-require-if="fieldID:requiredValue"
.
<input type="checkbox" id="subscribe" name="subscribe">
<input type="email" name="email" data-require-if="subscribe:true" placeholder="Enter your email">
In this example, the email field becomes required if the checkbox with id subscribe
is checked (true
).
Use the on-active-required
class to mark fields that become required only when the step is active.
<input type="text" name="username" class="on-active-required" placeholder="Enter your username">
You can customize the validation highlighting behavior:
highlight
: Set to true
to enable highlighting invalid fields.highlight_time
: Duration (in milliseconds) to display the highlight. Default is 1000
.highlight_type
: An object to define the classes for different highlight types.Example:
let args = {
/* Other configurations */
"highlight": true,
"highlight_time": 1500,
"highlight_type": { error: "error", warning: "warning", success: "success", info: "info" }
};
[data-wz-title]
Set the step title for the navigation. If left blank, the system will automatically add Step + step number
as the title.
<div class="wizard-step" data-wz-title="Configuration">
<!-- Step content -->
</div>
[data-require-if]
Define conditional required fields based on another field’s value.
<input type="email" name="email" data-require-if="subscribe:true" placeholder="Enter your email">
Options allowing you to modify the behavior and actions:
Parameter | Type | Default | Definition / Value |
---|---|---|---|
wz_class |
String | .wizard |
Wizard main container target |
wz_ori |
String | .horizontal |
Wizard orientation (.horizontal , .vertical ) |
wz_nav |
String | .wizard-nav |
Navigation container class |
wz_nav_style |
String | dots |
Style of navigation steps (dots , tabs , progress ) |
wz_content |
String | .wizard-content |
Body container class |
wz_buttons |
String | .wizard-buttons |
Action button container class |
wz_button |
String | .wizard-btn |
Class of Previous, Next, and Finish action buttons |
wz_button_style |
String | .btn |
Basic button style |
wz_step |
String | .wizard-step |
Class for both nav and body steps |
wz_form |
String | .wizard-form |
Class of the form that contains the wizard |
wz_next |
String | .next |
Class of Next action button |
wz_prev |
String | .prev |
Class of Prev action button |
wz_finish |
String | .finish |
Class of Finish action button |
wz_highlight |
String | .highlight-error |
Class for highlights when validation errors occur |
current_step |
Number | 0 |
Active wizard step |
steps |
Number | 0 |
Number of wizard steps |
highlight_time |
Number | 1000 |
Display time for validation highlight (in milliseconds) |
navigation |
String | all |
Navigation mode (buttons , nav , all ) |
buttons |
Boolean | true |
Show or hide the action buttons |
nav |
Boolean | true |
Show or hide the header navigation |
highlight |
Boolean | true |
Enable or disable field highlighting on validation errors |
next |
String | Next |
Text for the Next button |
prev |
String | Prev |
Text for the Prev button |
finish |
String | Submit |
Text for the Finish button |
bubbles |
Boolean | false |
Enable or disable event bubbling for custom events |
highlight_type |
Object | { error: "error", warning: "warning", success: "success", info: "info" } |
Classes for different validation highlight effects |
i18n |
Object | Various | Internationalization messages for errors, titles, and warnings |
The i18n
object allows you to define custom error messages for different wizard actions:
empty_wz
: “No item has been found with which to generate the Wizard.”empty_nav
: “Nav does not exist or is empty.”empty_content
: “Content does not exist or is empty.”empty_html
: “Undefined or null content cannot be added.”empty_update
: “Nothing to update.”no_nav
: “Both the nav and the buttons are disabled, there is no navigation system.”form_validation
: “One or more of the form fields are invalid.”diff_steps
: “Discordance between the steps of nav and content.”random
: “There has been a problem, check the configuration and use of the wizard.”already_defined
: “This item is already defined.”title
: “Step” (used for default step titles if not specified in the HTML).Wizard-JS provides several events to help you manage and respond to user interactions.
To identify when the wizard is fully generated and loaded.
document.addEventListener("wz.ready", function (e) {
console.log(`Target:`, e.detail.target); // .wizard
console.log(`DOM Element:`, e.detail.elem); // DOM element
});
Triggered when the wizard is updated.
let wz_class = ".wizard";
let $wz_doc = document.querySelector(wz_class)
$wz_doc.addEventListener("wz.update", function (e) {
console.log(`Target:`, e.detail.target);
console.log(`DOM Element:`, e.detail.elem);
});
When the wizard is locked:
$wz_doc.addEventListener("wz.lock", function (e) {
alert("Wizard is locked");
});
When the wizard is unlocked:
$wz_doc.addEventListener("wz.unlock", function (e) {
alert("Wizard is unlocked");
});
Moving to the previous step:
$wz_doc.addEventListener("wz.btn.prev", function (e) {
alert("Previous Step");
});
Moving to the next step:
$wz_doc.addEventListener("wz.btn.next", function (e) {
alert("Next Step");
});
Navigating forward with the navbar:
$wz_doc.addEventListener("wz.nav.forward", function (e) {
alert("Forward Navigation");
});
Navigating backward with the navbar:
$wz_doc.addEventListener("wz.nav.backward", function (e) {
alert("Backward Navigation");
});
Triggered when there is an error validating the data of the active form step.
$wz_doc.addEventListener("wz.error", function (e) {
console.log(`ID:`, e.detail.id); // form_validation
console.log(`Message:`, e.detail.msg); // Form validation message
console.log(`Target:`, e.detail.target); // Array of invalid elements
});
If it is a form, at the end it will fire the following event:
$wz_doc.addEventListener("wz.form.submit", function (e) {
alert("Form Submitted");
});
If it is not a form, at the end it will fire the following event:
$wz_doc.addEventListener("wz.end", function (e) {
alert("Wizard is finished");
});
When the wizard is restarted:
$wz_doc.addEventListener("wz.reset", function (e) {
alert("Wizard has restarted");
});
Try it on CodePen:
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Please make sure to update tests as appropriate.