bootstrap-application-wizard
bootstrap-application-wizard copied to clipboard
Bootstrap Application Wizard
This project is no longer maintained. Open issues and PRs will not be resolved. Please fork if you wish to maintain yourself.
General
Author
- Andrew Moffat, built @ Panopta
Special Thanks
Update bootstrap v3.x
- [Gert-Jan Timmer] (https://github.com/GJRTimmer)
Contributors
- [Andrew Moffat] (https://github.com/amoffat)
- [bryancallahan] (https://github.com/bryancallahan)
- [che-burashco] (https://github.com/che-burashco)
- [bluetidepro] (https://github.com/bluetidepro)
- [david-proweb] (https://github.com/david-proweb)
- [kachar] (https://github.com/kachar)
- [ludokx] (https://github.com/ludokx)
- [choudeshell] (https://github.com/choudeshell)
Dependencies
- jQuery 2.x
- Bootstrap 3.x
Installation
CSS
<link href="bootstrap-wizard/bootstrap-wizard.css" rel="stylesheet" />
Javascript
<script src="bootstrap-wizard/bootstrap-wizard.js" type="text/javascript"></script>
Usage
1) Create wizard
<div class="wizard" id="some-wizard" data-title="Wizard Title"></div>
To set the title of the application wizard use the data-title
attribute
2) Create wizard cards
Each .wizard-card will be its own step in the Application Wizard, and the h3 tag will be used for its navigation name on the left. Also notice the data-cardname
attribute on each card. While not required, this can be used to access the cards by a specific name.
Card Setup
<div class="wizard-card" data-cardname="card1">
<h3>Card 1</h3>
Some content
</div>
Basic Wizard Setup
<div class="wizard" id="some-wizard" data-title="Wizard Title">
<div class="wizard-card" data-cardname="card1">
<h3>Card 1</h3>
Some content
</div>
<div class="wizard-card" data-cardname="card2">
<h3>Card 2</h3>
Some content
</div>
</div>
3) Initialize Wizard
After setting up the wizard with it's cards you can initilize it.
$(function() {
var options = {};
var wizard = $("#some-wizard").wizard(options);
});
Wizard
Wizard Options
Name | Type | Default | Description |
---|---|---|---|
keyboard | boolean | true | Closes the modal when escape key is pressed. |
backdrop | boolean or string `static` | true | Includes a modal-backdrop element. Alternatively, specify `static` for a backdrop which doesn't close the modal on click. |
show | boolean | false | Shows the modal when initialized. |
showCancel | boolean | false | Show cancel button when initialized. |
showClose | boolean | true | Show close button when initialized |
progressBarCurrent | boolean | false | |
submitUrl | string | '' | Default submit url |
increateHeight | integer | 0 | Deprecated |
contentHeight | integer | 300 | Default height of content view |
contentWidth | integer | 580 | Default width of wizard dialog, includes step navigation, which takes 28%. |
buttons | array |
cancelText: "Cancel" nextText: "Next" backText: "Back" submitText: "Submit" submittingText: "Submitting..." |
|
formClass | string | form-horizontal | Allows the configuration of the class(es) of the form. Default `form-horizontal` is set. Multiple classes are allow by separation of space. |
Logging can be turned on by setting logging before wizard initialization
$.fn.wizard.logging = true;
Wizard Methods
Usage:
var wizard = $("#some-wizard").wizard({});
wizard.methodName(arguments);
Method | Description |
---|---|
show() | Displays the wizard |
hide() | Alias for close() |
close() | Closes the wizard |
serialize() | Returns all inputs from the wizard as serialized string, see [jQuery serialize()] (http://api.jquery.com/serialize/). Add-on: standard disabled inputs are not serialized. This function will will also serialize disabled inputs which have a attribute `data-serialize="1"`. |
serializeArray() | Returns all inputs from the wizard as array object, can be used for sending a JSON object to the server. See [jQuery serializeArray()] (http://api.jquery.com/serializeArray/) Add-on: standard disabled inputs are not serialized. This function will will also serialize disabled inputs which have a attribute `data-serialize="1"`. |
getActiveCard | Returns a wizardCard object for the active card |
setTitle(title) | Set the title of the wizard |
setSubtitle(subTitle) | Sets the secondary, less pronounced title in the wizard header |
errorPopover(element, msg, allowHtml) | This creates an error popup on element, with content msg. This is useful being called from a card-level validator, where you might want to pick specific elements on a card on which to show an error tooltip. allowHtml (default:false) allows html content as msg argument. |
changeNextButton(text, [class]) | Changes the “next” button (used to advance steps in the wizard) to have text text and optionally css class cls. This is used internally by the wizard when the last step is reached, to display a green “submit” button, but it may be useful elsewhere. |
updateProgressBar(percent) | Sets the progress bar in the lower right to percent complete. This typically shouldn’t be touched by user code, but it can be useful to call updateProgressBar(0) after a submit handler returns. [See Submitting Data]. |
hideButtons() | Hides the next and previous buttons. This is only really useful after a submission handler returns. [See Submitting Data]. |
showButtons() | Shows the next and previous buttons. This is only really useful after a submission handler returns. [See Submitting Data]. |
submitSuccess() | Shows the special submit cards. This is only really useful after a submission handler returns. [See Submitting Data]. |
submitError() | Shows the special submit cards. This is only really useful after a submission handler returns. [See Submitting Data]. |
submitFailure() | Shows the special submit cards. This is only really useful after a submission handler returns. [See Submitting Data]. |
reset() | Resets the wizard to its original state. This only resets wizard internals, and does not affect your form elements. If you want to reset those, listen for the `reset` event, and write some code to reset your elements manually. |
find(selector) | Search for the given selector within the modal. And returns the same result as jQuery.find(selector) function. |
Wizard Events
You can register on the follwing wizard events with jQuery's on(eventName, callback)
function.
Example registering on the reset event
var wizard = $("#some-wizard").wizard({});
wizard.on("reset", function() {
// Some reset actions
});
Event | Description |
---|---|
reset | Reset event is called when the dialog is either closed or when submit is done |
submit | Triggers when the submit button is clicked on the final card |
closed | Triggers when the wizard is closed |
incrementCard | Triggers when the next card becomes the current card |
decrementCard | Triggers when the previous card becomes the current card |
progressBar | Triggers when the progress bar is incremented. The first argument passed to the callback is the new progress percent from 0 to 100. |
submitSuccess | Trigger when submit was succesfull |
submitFailure | Trigger when submit failed |
Submitting Wizard
The easiest way to submit data to the wizard is to pass in a submitUrl on construction.
var wizard = $("#some-wizard").wizard({submitUrl: "/some_url"});
When the wizard reaches its last step and the user clicks the submit button, all of the inputs from all of the wizard cards will be aggregated together and POSTed to your submitUrl.
If you wish to implement your own submit listener, take a look at the source of the Wizard._defaultSubmit method, which is the default submit listener.
function(wizard) {
$.ajax({
type: "POST",
url: wizard.args.submitUrl,
data: wizard.serialize(),
dataType: "json"
}).done(function(response) {
wizard.submitSuccess();
wizard.hideButtons();
wizard.updateProgressBar(0);
}).fail(function() {
wizard.submitFailure();
wizard.hideButtons();
});
}
The wizard class implements the serialize() and serializeArray() methods of jQuery form elements. These methods will scan through all the form input elements in your wizard cards, aggregate the names and values, and return a data structure for submitting via an ajax call.
After your submission, depending on whether your submission succeeded, failed, or had an error, you can display a specific hidden card to reflect the submission status. These submission cards must first be defined in the html.
<div class="wizard" id="some-wizard">
<!-- normal wizard cards: -->
<div class="wizard-card" data-cardname="card1">
<h3>Card 1</h3>
<div>...</div>
</div>
<!-- begin special status cards below: -->
<div class="wizard-success">
submission succeeded!
</div>
<div class="wizard-error">
submission had an error
</div>
<div class="wizard-failure">
submission failed
</div>
</div>
These 3 cards are hidden by default and only appear when you specifically activate them. Typically, these cards will be activated by status of an ajax post.
wizard.on("submit", function(wizard) {
$.ajax({
url: "/wizard_submit_url",
type: "POST",
url: wizard.args.submitUrl,
data: wizard.serialize(),
dataType: "json"
}).done(function(response) {
wizard.submitSuccess(); // displays the success card
wizard.hideButtons(); // hides the next and back buttons
wizard.updateProgressBar(0); // sets the progress meter to 0
}).fail(function() {
wizard.submitError(); // display the error card
wizard.hideButtons(); // hides the next and back buttons
});
}
By activating these cards in the ajax request handlers, you can display information relevant to the status of the submit request
After submission, you may wish to reset the wizard to some default state. See the [reset()] method in the wizard class for details on this.
Wizard Cards
Access
Cards can be accessed through the cards attribute on the wizard object. By default, this is an object whose keys are the text from the h3 tags, and whose values are instances of the WizardCard class. So for example, with the following markup:
<div class="wizard" id="some-wizard">
<div class="wizard-card">
<h3>Card 1</h3>
<div>...</div>
</div>
</div>
You could access this card the following way:
var wizard = $("#some-wizard").wizard();
var card = wizard.cards["Card 1"];
From this card object, you can call any of the card methods.
You can also set a card’s name specifically by using the data-cardname
attribute
<div class="wizard" id="some-wizard">
<div class="wizard-card" data-cardname="card1">
<h3>Card 1</h3>
<div>...</div>
</div>
</div>
Now you can access the card by the name “card1″:
var wizard = $("#some-wizard").wizard();
var card = wizard.cards["card1"];
Validation
Most wizard cards will require some kind of validation of the input before proceeding to the next card. This validation is not intended to sanitize malicious data to be trustworthy (this should be done server-side), merely to catch any obvious common problems with the data.
Validation can be attached inline to form elements by using the attribute data-validate
on the input.
<div class="wizard-card">
<h3>Card 1</h3>
Name <input type="text" name="name" data-validate="validateName" />
</div>
When the Next button is clicked for the card, validateName will be called with the element as its first argument. Here’s an example validation function:
function validateName(el) {
var name = el.val();
var retValue = {};
if (name == "") {
retValue.status = false;
retValue.msg = "Please enter a name";
}
else {
retValue.status = true;
}
return retValue;
}
If the validator returns with an object with .status == false, then an error popup will display on the element and the wizard will not be allowed to progress to the next step. The wizard will only progress when all of the validators on the page return with a status of true.
Entire cards may be assigned a validation function by using the data-validate
attribute on the card.
<div class="wizard-card" data-validate="someFunction">
<h3>Card 1</h3>
Some content
</div>
someFunction()
will receive a WizardCard object on which you can manually search for the inputs on that card and validate them. This is useful for validating complex interdependencies between many inputs, for example, if a name field can only be empty if another field is populated.
The final method for validating entire cards is to subscribe to the the “validate” event and provide a validation function.
wizard.cards["Card 1"].on("validate", function(card) {
var input = card.el.find("input");
var name = input.val();
if (name == "") {
card.wizard.errorPopover(input, "Name cannot be empty");
return false;
}
return true;
});
A card-level validation function is slightly different from an input-level validation function. In a card-level function, you are required to display any error popovers, using the wizard object’s errorPopover() method, as well as returning true or false to tell the wizard whether or not it should advance to the next step.
Validation Error Popup
Input with adjacent button
Bootstrap has the possibility to have button adjacent to an input. This causes the error-popover to be misplaced. To correct this the error-popover has to be placed on the span of the adjacent button.
To accomplish this the application wizard has smart detection for this. When creating an adjacent button to an input an additionial id
has to be set on the adjacent <span>
of the button
. The id
name of the span has to be btn-(ID OF INPUT)
.
For example within the following card setup. The card uses standard bootstrap v3.x code for an input with adjacent button. The id of the input is fqdn
. The id of the adjacent span becomes btn-fqdn
.
This will cause the error-popop to be correctly displayed when there is an validation error.
<div class="wizard-card" data-cardname="address">
<h3>Address</h3>
<div class="wizard-input-section">
<p>Full Qualified Domain Name</p>
<div class="form-group">
<div class="col-sm-8">
<div class="input-group">
<input type="text" class="form-control" id="fqdn" name="fqdn" placeholder="FQDN" data-validate="validateFQDN" data-is-valid="0" data-lookup="0" />
<span class="input-group-btn" id="btn-fqdn">
<button class="btn btn-default" type="button" onclick='lookup();'>Lookup</button>
</span>
</div>
</div>
</div>
</div>
</div>
Card CSS
If you require to display an selection box overlayed over wizard, like is done within the demo for some of the selects. You have to add the following class to your wizard-card element. wizard-card-overlay
.
Card Methods
Method | Description |
---|---|
Card Events
Registering event on cards can be done with the jQuery on(event, callback)
function on the wizardCard object.
Event | Description |
---|---|
loaded | Triggers when the card is first loaded (when the card is selected but has never been selected before). This is useful for lazy-loading content. |
validate | when the card is being validated. The callback assigned to this can itself be used as a validator if it returns a boolean. |
selected | Triggers when this card is selected as the active wizard card |
deselect | Triggers when this card is changed from. The new card will receive the select event, and the old card will receive the deselect event. |
enabled | |
disabled | |
reload | Triggers when the card is first loaded or when the reload() function is called. |
validate | Called when the card is being validated. The callback assigned to this can serve as a validator itself, if it returns a boolean. |
validated | Triggers when validation is done |
invalid | Triggers when validation failed |
markVisited | Triggers when this card is marked as visited, meaning, typically, that the user can go back to it from a different step |
unmarkVisited | Triggers removing this card as a visited card |