A class for managing steps in a wizard, and their responses.
Install this package:
npm install --save liamfiddler/friendly-wizard
Then import the Wizard class and start using it:
import Wizard from 'friendly-wizard/Wizard.js';
const wizard = new Wizard({
steps: [
{
id: 'step-1',
type: 'text',
data: {
title: 'Step 1',
body: 'Welcome to the first step',
},
},
{
id: 'step-2',
type: 'text',
data: {
title: 'Step 2',
body: 'This is the second step',
},
},
],
});
// output the first step title
console.log(wizard.activeStep.data.title);
// navigate to the next step
wizard.next();
// output the second step title
console.log(wizard.activeStep.data.title);
The Wizard class constructor takes an object for configuration:
Param | Type | Description |
---|---|---|
steps | Step[] |
An array of Step objects, representing the screens in the wizard flow |
startAtId | string |
The ID of the step which should initially be active (defaults to the first step if not supplied) |
responses | Map.<string, any> | Record.<string, any> |
The initial set of answers/responses to the wizard (defaults to an empty object if not supplied) |
The steps
value passed the Wizard class constructor is an array of Step objects.
Step objects are a generic javascript object with whatever keys you like, however the following keys have special functionality attached to them:
A unique identifier for the step. If it is not supplied a random string will be generated as the ID (note: this is randomly generated every time a new Wizard is created, it will be different every time and does not persist across multiple instantiations).
skip contains the logic for skipping the step. This could be a boolean, a function that returns a boolean, or a mongo-style object that compares against the wizard responses.
If you pass an object as the value for skip you can use mongo-style syntax to compare responses and response values. Under the hood it uses sift.js and supports a variety of operators. Refer to the list of supported operators in the sift.js documentation.
const wizard = new Wizard({
steps: [
{
id: 'step1',
},
{
id: 'step2',
// skip the step if 'something' === 'test'
skip: {
something: {
$eq: 'test',
},
},
},
{
id: 'step3',
},
],
});
// outputs 'step2', because the second step is not skipped
console.log(wizard.nextStep.id);
// set the response for 'something' to 'test'
wizard.responses.set('something', 'test');
// outputs 'step3' because the second step is now skipped
console.log(wizard.nextStep.id);
The Wizard class is an EventTarget. Event listeners can be added to the class, and will trigger functionality when certain circumstances occur in usage.
Event | Description |
---|---|
step:change | Triggered when the wizard moves to a different step |
step:next | Triggered when the wizard moves forward a step |
step:previous | Triggered when the wizard moves back a step |
responses:change | Triggered when a response value is created, updated, or deleted |
The event listeners are particularly useful in Single Page Apps, they allow libraries and frameworks to listen for changes and render updates as they occur.
const wizard = new Wizard({
steps: [{}, {}, {}, {}],
});
wizard.addEventListener('step:change', () => {
console.log('hello world');
});
// Change to the next step, triggering the event listener and outputting 'hello world'
wizard.next();
Example usage is demonstrated in the React example project in this repo.
A custom hook called useFriendlyWizard wraps the Wizard class for usage in React. It manages event listeners and updates the wizard step to component state when the step changes.
Example usage is demonstrated in the Vue example project in this repo.
The Wizard class is instantiated as a global property making it available inside any component template in the application, and also on this
of any component instance.
Components accessing it can implement event listeners to render when the step changes. See App.vue for an example.
A version of the Wizard class that is extended to automatically read/write the responses to/from browser storage is included in this repo.
To use it import from the WizardStorage.js
file instead of Wizard.js
:
- import Wizard from 'friendly-wizard/Wizard.js';
+ import Wizard from 'friendly-wizard/WizardStorage.js';
Additionally, two new options will be available when instantiating the class:
Name | Type | Description |
---|---|---|
[persist] | boolean |
Whether the responses should persist when the window/tab is closed (localStorage ), or not (sessionStorage ). Defaults to true |
[storageKey] | string |
The key under which the responses should be stored. Defaults to "wizard" |
A module for handling wizard data
- friendly-wizard
- module.exports β
- new module.exports(options)
- instance
- .isLastStep β
boolean
- .isFirstStep β
boolean
- .activeStep β
Step
- .previousStep β
Step
- .nextStep β
Step
- .stepNum β
number
- .stepTotal β
number
- .progressPercent β
number
- .responses β
Map.<string, any>
- .next()
- .previous()
- .steps() β
Iterable.<Step>
- .responsesFromForm(form)
- .isLastStep β
- inner
- ~Step :
Object.<string, any>
- ~Step :
- module.exports β
A class for handling the steps in a wizard-like flow, as well as the responses to questions in the flow
Construct a new Wizard
Param | Type | Description |
---|---|---|
options | Object |
An object containing configuration for the wizard |
options.steps | Array.<Step> |
An array of Step objects, representing the screens in the wizard flow |
[options.startAtId] | string |
The ID of the step which should initially be active (defaults to the first step if not supplied) |
[options.responses] | Map.<string, any> | Record.<string, any> |
An object containing the initial set of answers/responses to the wizard |
Is the active step the last step?
Kind: instance property of module.exports
Is the active step the first step?
Kind: instance property of module.exports
Get the active step
Kind: instance property of module.exports
Get the previous step
Kind: instance property of module.exports
Get the next step
Kind: instance property of module.exports
Get the active step number
Kind: instance property of module.exports
Get the total number of steps
Kind: instance property of module.exports
Get the percentage of progress through the steps
Kind: instance property of module.exports
Get the responses to the wizard
Kind: instance property of module.exports
Sets the next step active
Kind: instance method of module.exports
Sets the previous step active
Kind: instance method of module.exports
Iterable steps
Kind: instance method of module.exports
Add the values from a HTML form element to the responses
Kind: instance method of module.exports
Param | Type |
---|---|
form | HTMLFormElement |
An object representing a step in the wizard flow
Kind: inner typedef of module.exports
Properties
Name | Type | Description |
---|---|---|
[id] | string |
A unique identifier for the step (a random string will be generated as the ID if not specified) |
[skip] | Object | boolean | function |
The logic for skipping a step (a boolean, a function that returns a boolean, or a mongo-style object) |