Alpaca lets you arrange your form into simple multi-step wizards along with buttons for previous, next and submit using a simple configuration-driven approach. Wizards are essentially fields within a single form that are split across multiple DIVS, letting you orchestrate a single and non-conditional flow path as DIVs are hidden and shown in sequence.
In addition, wizards optionally allow for configuration-driven options to assert the validation state of the set of shown fields before allowing the user to proceed to the next page.
The basic wizard functionality in Alpaca is an extension of custom layouts. It may help to read up on custom layouts to get a better understanding of wizards as much of the wizard functionality depends on it.
In this example, we use our customer profile data, schema and options, all of which are loaded via HTTP by Alpaca at the onset. These files are acquired here:
We use a special wizard
block to tell Alpaca that we want the wizard to be built upon the layout.
We can also use this block to configure the wizard as we see fit.
title
- (optional) title for the wizarddescription
- (optional) description for the wizardbindings
- (optional) maps fields to steps of the wizardsteps
- (optional) provides labels and descriptions for the navigationAll that is required for the wizard to be rendered is for the wizard
block to be present. Everything
inside of the wizard block is optional.
You can control the layout of individual steps of the wizard by using a wizard layout template. A wizard layout template is simply a layout template that has some specific DOM attributes in it to identify the containers for your steps. These containers are then hidden and shown as the wizard is navigated through.
If you haven't read up on layouts yet, we recommend that you do as many of the concepts expressed here are covered over there.
In this example, we use the layout wizards-example2-template.html to generate the HTML that ultimately will be injected for each step of the wizard.
The wizard requires that the layout identify step containers. Each step must be wrapped in a DOM element
with the attribute data-alpaca-wizard-role="step"
. Alpaca uses this attribute to find the steps
and sequence them.
With wizard templates, you can also configure the wizard from within the DOM itself. This lets you configure some aspects of the wizard from right within the HTML. In addition, you can use DOM selectors to identify the field bindings, giving you a bit more flexibility.
There are a number of DOM-driven configurations that can be supplied from within the HTML.
For the top-level DOM element:
data-alpaca-wizard-title
- the wizard title (wizard.title
)data-alpaca-wizard-description
- the wizard description (wizard.description
)data-alpaca-wizard-validation
- whether to run validation between steps (wizard.validation
)data-alpaca-wizard-show-steps
- whether to render the steps selector (wizard.showSteps
)data-alpaca-wizard-show-progress-bar
- whether to render the progress bar (wizard.showProgressBar
)And for each step:
data-alpaca-wizard-step-title
- the step title (wizard.steps[i].title
)
data-alpaca-wizard-step-description
- the step description (wizard.steps[i].description
)In this example, we use this DOM-based configuration to reduce the amount of JSON we pass in for the wizard config. It's all contained in the template HTML. And the bindings are contained in the layout.
The layout file being used is wizards-example3-template.html.
Note that in this case, since everything is driven out of the layout, we don't need to specify much regarding the
wizard within the config at all. In fact, we can simply pass wizard: {}
or wizard: true
to run the wizard, but that's it.
Another feature that wizard layouts give you is the ability to bind fields into exact positions within the layout. This lets you identify the field within the template itself, allowing for exact specification of where the field should be inserted. This is an advantage for highly specific forms with needs for exact field placement but also generally makes your templates less re-usable. In effect, you trade off reusability for accuracy.
To mark exact field placements, you simply use the data-alpaca-layout-binding
attribute.
Here is an example that does just that. This uses the wizards-example4-template.html template.
By default, steps are validated prior to transitioning between previous and next. You can turn this on and off
using the validation
wizard setting.
You can also customize buttons and set up custom validation functions for each transition. You can add a click
handler for the submit button. If no click handler is supplied and the wizard is inside of a form, the form will
be submitted.
The submit button here also has an id
setting on it which sets the DOM ID for the button element. It
uses the attributes
setting to specify custom DOM attributes - in this case, data-test='123'
.
Custom buttons are also possible as shown with the "start over" button below. Use the align
property
to indicate placement of the button.
By default, three buttons are placed into the wizard - previous
, next
and submit
.
If you are embedding the wizard within an outer form and wish to handle the submit yourself, you can set the
hideSubmitButton
wizard setting to true. The submit button will then be hidden. By default, this
setting is falsy and the submit button will be shown.
The wizard tracks multiple pages (or steps). As you moved from to step, the current step is marked as "active" as well as "visited". When you track backwards by clicking the "previous" button, knowledge about the visited steps is retained and made visible to the end user.
If you'd like to mark all steps as visited upon initial load, set the markAllStepsVisited
wizard setting
to true.
Wizards also support custom events that you can fire using the top level control (returned during the postRender
callback). These callbacks let you transition to specific pages and control wizard flow within your button handlers.
Moves to a specific step in the wizard. Takes a configuration object to indicate the page number and whether validation should be skipped. If validation processes and determines the current page in the wizard is invalid, the transition will be blocked.
Example:
control.trigger("moveToStep", {
"index": 1,
"skipValidation": true
});
Advances the wizard to the next page. If the wizard is on the last page, the wizard is submitted.
Example:
control.trigger("advanceOrSubmit");
When using bindings to bind fields into wizard steps, you can further specify the order of fields using the
order
option for the fields. This is in the same manner as field orderings as specified within
objects. The wizard layout engine will take this into consideration and order your fields as specified.
Here is a very simple example to demonstrate field ordering. It builds on the previous examples but is stripped down so as to show how fields can be ordered in reverse per page.