123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750 |
- /*!
- * SmartWizard v4.4.1
- * The awesome jQuery step wizard plugin with Bootstrap support
- * http://www.techlaboratory.net/smartwizard
- *
- * Created by Dipu Raj
- * http://dipuraj.me
- *
- * Licensed under the terms of the MIT License
- * https://github.com/techlab/SmartWizard/blob/master/LICENSE
- */
- ;
- (function ($, window, document, undefined) {
- "use strict"; // Default options
- var defaults = {
- selected: 0,
- // Initial selected step, 0 = first step
- keyNavigation: true,
- // Enable/Disable keyboard navigation(left and right keys are used if enabled)
- autoAdjustHeight: true,
- // Automatically adjust content height
- cycleSteps: false,
- // Allows to cycle the navigation of steps
- backButtonSupport: true,
- // Enable the back button support
- useURLhash: true,
- // Enable selection of the step based on url hash
- showStepURLhash: true,
- // Show url hash based on step
- lang: {
- // Language variables for button
- next: 'Next',
- previous: 'Previous'
- },
- toolbarSettings: {
- toolbarPosition: 'bottom',
- // none, top, bottom, both
- toolbarButtonPosition: 'end',
- // start, end
- showNextButton: true,
- // show/hide a Next button
- showPreviousButton: true,
- // show/hide a Previous button
- toolbarExtraButtons: [] // Extra buttons to show on toolbar, array of jQuery input/buttons elements
- },
- anchorSettings: {
- anchorClickable: true,
- // Enable/Disable anchor navigation
- enableAllAnchors: false,
- // Activates all anchors clickable all times
- markDoneStep: true,
- // Add done css
- markAllPreviousStepsAsDone: true,
- // When a step selected by url hash, all previous steps are marked done
- removeDoneStepOnNavigateBack: false,
- // While navigate back done step after active step will be cleared
- enableAnchorOnDoneStep: true // Enable/Disable the done steps navigation
- },
- contentURL: null,
- // content url, Enables Ajax content loading. Can also set as data data-content-url on anchor
- contentCache: true,
- // cache step contents, if false content is fetched always from ajax url
- ajaxSettings: {},
- // Ajax extra settings
- disabledSteps: [],
- // Array Steps disabled
- errorSteps: [],
- // Highlight step with errors
- hiddenSteps: [],
- // Hidden steps
- theme: 'default',
- // theme for the wizard, related css need to include for other than default theme
- transitionEffect: 'none',
- // Effect on navigation, none/slide/fade
- transitionSpeed: '400'
- }; // The plugin constructor
- function SmartWizard(element, options) {
- // Merge user settings with default, recursively
- this.options = $.extend(true, {}, defaults, options); // Main container element
- this.main = $(element); // Navigation bar element
- this.nav = this.main.children('ul'); // Step anchor elements
- this.steps = $("li > a", this.nav); // Content container
- this.container = this.main.children('div'); // Content pages
- this.pages = this.container.children('div'); // Active step index
- this.current_index = null; // Backward compatibility
- this.options.toolbarSettings.toolbarButtonPosition = this.options.toolbarSettings.toolbarButtonPosition === 'right' ? 'end' : this.options.toolbarSettings.toolbarButtonPosition;
- this.options.toolbarSettings.toolbarButtonPosition = this.options.toolbarSettings.toolbarButtonPosition === 'left' ? 'start' : this.options.toolbarSettings.toolbarButtonPosition; // Default fix
- this.options.theme = this.options.theme === null || this.options.theme === '' ? 'default' : this.options.theme; // Call initial method
- this.init();
- }
- $.extend(SmartWizard.prototype, {
- init: function () {
- // Set the elements
- this._setElements(); // Add toolbar
- this._setToolbar(); // Assign plugin events
- this._setEvents();
- var idx = this.options.selected; // Get selected step from the url
- if (this.options.useURLhash) {
- // Get step number from url hash if available
- var hash = window.location.hash;
- if (hash && hash.length > 0) {
- var elm = $("a[href*='" + hash + "']", this.nav);
- if (elm.length > 0) {
- var id = this.steps.index(elm);
- idx = id >= 0 ? id : idx;
- }
- }
- }
- if (idx > 0 && this.options.anchorSettings.markDoneStep && this.options.anchorSettings.markAllPreviousStepsAsDone) {
- // Mark previous steps of the active step as done
- this.steps.eq(idx).parent('li').prevAll().addClass("done");
- } // Show the initial step
- this._showStep(idx);
- },
- // PRIVATE FUNCTIONS
- _setElements: function () {
- // Set the main element
- this.main.addClass('sw-main sw-theme-' + this.options.theme); // Set anchor elements
- this.nav.addClass('nav nav-tabs step-anchor').children('li').addClass('nav-item').children('a').addClass('nav-link'); // nav-justified nav-pills
- // Make the anchor clickable
- if (this.options.anchorSettings.enableAllAnchors !== false && this.options.anchorSettings.anchorClickable !== false) {
- this.steps.parent('li').addClass('clickable');
- } // Set content container
- this.container.addClass('sw-container tab-content'); // Set content pages
- this.pages.addClass('tab-pane step-content'); // Disabled steps
- var mi = this;
- if (this.options.disabledSteps && this.options.disabledSteps.length > 0) {
- $.each(this.options.disabledSteps, function (i, n) {
- mi.steps.eq(n).parent('li').addClass('disabled');
- });
- } // Error steps
- if (this.options.errorSteps && this.options.errorSteps.length > 0) {
- $.each(this.options.errorSteps, function (i, n) {
- mi.steps.eq(n).parent('li').addClass('danger');
- });
- } // Hidden steps
- if (this.options.hiddenSteps && this.options.hiddenSteps.length > 0) {
- $.each(this.options.hiddenSteps, function (i, n) {
- mi.steps.eq(n).parent('li').addClass('hidden');
- });
- }
- return true;
- },
- _setToolbar: function () {
- // Skip right away if the toolbar is not enabled
- if (this.options.toolbarSettings.toolbarPosition === 'none') {
- return true;
- } // Create the toolbar buttons
- var btnNext = this.options.toolbarSettings.showNextButton !== false ? $('<button></button>').text(this.options.lang.next).addClass('btn btn-secondary sw-btn-next').attr('type', 'button') : null;
- var btnPrevious = this.options.toolbarSettings.showPreviousButton !== false ? $('<button></button>').text(this.options.lang.previous).addClass('btn btn-secondary sw-btn-prev').attr('type', 'button') : null;
- var btnGroup = $('<div></div>').addClass('btn-group mr-2 sw-btn-group').attr('role', 'group').append(btnPrevious, btnNext); // Add extra toolbar buttons
- var btnGroupExtra = null;
- if (this.options.toolbarSettings.toolbarExtraButtons && this.options.toolbarSettings.toolbarExtraButtons.length > 0) {
- btnGroupExtra = $('<div></div>').addClass('btn-group mr-2 sw-btn-group-extra').attr('role', 'group');
- $.each(this.options.toolbarSettings.toolbarExtraButtons, function (i, n) {
- btnGroupExtra.append(n.clone(true));
- });
- }
- var toolbarTop, toolbarBottom; // Append toolbar based on the position
- switch (this.options.toolbarSettings.toolbarPosition) {
- case 'top':
- toolbarTop = $('<div></div>').addClass('btn-toolbar sw-toolbar sw-toolbar-top justify-content-' + this.options.toolbarSettings.toolbarButtonPosition);
- toolbarTop.append(btnGroup);
- if (this.options.toolbarSettings.toolbarButtonPosition === 'start') {
- toolbarTop.prepend(btnGroupExtra);
- } else {
- toolbarTop.append(btnGroupExtra);
- }
- this.container.before(toolbarTop);
- break;
- case 'bottom':
- toolbarBottom = $('<div></div>').addClass('btn-toolbar sw-toolbar sw-toolbar-bottom justify-content-' + this.options.toolbarSettings.toolbarButtonPosition);
- toolbarBottom.append(btnGroup);
- if (this.options.toolbarSettings.toolbarButtonPosition === 'start') {
- toolbarBottom.prepend(btnGroupExtra);
- } else {
- toolbarBottom.append(btnGroupExtra);
- }
- this.container.after(toolbarBottom);
- break;
- case 'both':
- toolbarTop = $('<div></div>').addClass('btn-toolbar sw-toolbar sw-toolbar-top justify-content-' + this.options.toolbarSettings.toolbarButtonPosition);
- toolbarTop.append(btnGroup);
- if (this.options.toolbarSettings.toolbarButtonPosition === 'start') {
- toolbarTop.prepend(btnGroupExtra);
- } else {
- toolbarTop.append(btnGroupExtra);
- }
- this.container.before(toolbarTop);
- toolbarBottom = $('<div></div>').addClass('btn-toolbar sw-toolbar sw-toolbar-bottom justify-content-' + this.options.toolbarSettings.toolbarButtonPosition);
- toolbarBottom.append(btnGroup.clone(true));
- if (btnGroupExtra !== null) {
- if (this.options.toolbarSettings.toolbarButtonPosition === 'start') {
- toolbarBottom.prepend(btnGroupExtra.clone(true));
- } else {
- toolbarBottom.append(btnGroupExtra.clone(true));
- }
- }
- this.container.after(toolbarBottom);
- break;
- default:
- toolbarBottom = $('<div></div>').addClass('btn-toolbar sw-toolbar sw-toolbar-bottom justify-content-' + this.options.toolbarSettings.toolbarButtonPosition);
- toolbarBottom.append(btnGroup);
- if (this.options.toolbarSettings.toolbarButtonPosition === 'start') {
- toolbarBottom.append(btnGroupExtra);
- } else {
- toolbarBottom.append(btnGroupExtra);
- }
- this.container.after(toolbarBottom);
- break;
- }
- return true;
- },
- _setEvents: function () {
- // Anchor click event
- var mi = this;
- $(this.steps).on("click", function (e) {
- e.preventDefault();
- if (mi.options.anchorSettings.anchorClickable === false) {
- return true;
- }
- var idx = mi.steps.index(this);
- if (mi.options.anchorSettings.enableAnchorOnDoneStep === false && mi.steps.eq(idx).parent('li').hasClass('done')) {
- return true;
- }
- if (idx !== mi.current_index) {
- if (mi.options.anchorSettings.enableAllAnchors !== false && mi.options.anchorSettings.anchorClickable !== false) {
- mi._showStep(idx);
- } else {
- if (mi.steps.eq(idx).parent('li').hasClass('done')) {
- mi._showStep(idx);
- }
- }
- }
- }); // Next button event
- $('.sw-btn-next', this.main).on("click", function (e) {
- e.preventDefault();
- mi._showNext();
- }); // Previous button event
- $('.sw-btn-prev', this.main).on("click", function (e) {
- e.preventDefault();
- mi._showPrevious();
- }); // Keyboard navigation event
- if (this.options.keyNavigation) {
- $(document).keyup(function (e) {
- mi._keyNav(e);
- });
- } // Back/forward browser button event
- if (this.options.backButtonSupport) {
- $(window).on('hashchange', function (e) {
- if (!mi.options.useURLhash) {
- return true;
- }
- if (window.location.hash) {
- var elm = $("a[href*='" + window.location.hash + "']", mi.nav);
- if (elm && elm.length > 0) {
- e.preventDefault();
- mi._showStep(mi.steps.index(elm));
- }
- }
- });
- }
- return true;
- },
- _showNext: function () {
- var si = this.current_index + 1; // Find the next not disabled step
- for (var i = si; i < this.steps.length; i++) {
- if (!this.steps.eq(i).parent('li').hasClass('disabled') && !this.steps.eq(i).parent('li').hasClass('hidden')) {
- si = i;
- break;
- }
- }
- if (this.steps.length <= si) {
- if (!this.options.cycleSteps) {
- return false;
- }
- si = 0;
- }
- this._showStep(si);
- return true;
- },
- _showPrevious: function () {
- var si = this.current_index - 1; // Find the previous not disabled step
- for (var i = si; i >= 0; i--) {
- if (!this.steps.eq(i).parent('li').hasClass('disabled') && !this.steps.eq(i).parent('li').hasClass('hidden')) {
- si = i;
- break;
- }
- }
- if (0 > si) {
- if (!this.options.cycleSteps) {
- return false;
- }
- si = this.steps.length - 1;
- }
- this._showStep(si);
- return true;
- },
- _showStep: function (idx) {
- // If step not found, skip
- if (!this.steps.eq(idx)) {
- return false;
- } // If current step is requested again, skip
- if (idx == this.current_index) {
- return false;
- } // If it is a disabled step, skip
- if (this.steps.eq(idx).parent('li').hasClass('disabled') || this.steps.eq(idx).parent('li').hasClass('hidden')) {
- return false;
- } // Load step content
- this._loadStepContent(idx);
- return true;
- },
- _loadStepContent: function (idx) {
- var mi = this; // Get current step elements
- var curTab = this.steps.eq(this.current_index); // Get the direction of step navigation
- var stepDirection = '';
- var elm = this.steps.eq(idx);
- var contentURL = elm.data('content-url') && elm.data('content-url').length > 0 ? elm.data('content-url') : this.options.contentURL;
- if (this.current_index !== null && this.current_index !== idx) {
- stepDirection = this.current_index < idx ? "forward" : "backward";
- } // Trigger "leaveStep" event
- if (this.current_index !== null && this._triggerEvent("leaveStep", [curTab, this.current_index, stepDirection]) === false) {
- return false;
- }
- if (contentURL && contentURL.length > 0 && (!elm.data('has-content') || !this.options.contentCache)) {
- // Get ajax content and then show step
- var selPage = elm.length > 0 ? $(elm.attr("href"), this.main) : null;
- var ajaxSettings = $.extend(true, {}, {
- url: contentURL,
- type: "POST",
- data: {
- step_number: idx
- },
- dataType: "text",
- beforeSend: function () {
- mi._loader('show');
- },
- error: function (jqXHR, status, message) {
- mi._loader('hide');
- $.error(message);
- },
- success: function (res) {
- if (res && res.length > 0) {
- elm.data('has-content', true);
- selPage.html(res);
- }
- mi._loader('hide');
- mi._transitPage(idx);
- }
- }, this.options.ajaxSettings);
- $.ajax(ajaxSettings);
- } else {
- // Show step
- this._transitPage(idx);
- }
- return true;
- },
- _transitPage: function (idx) {
- var mi = this; // Get current step elements
- var curTab = this.steps.eq(this.current_index);
- var curPage = curTab.length > 0 ? $(curTab.attr("href"), this.main) : null; // Get step to show elements
- var selTab = this.steps.eq(idx);
- var selPage = selTab.length > 0 ? $(selTab.attr("href"), this.main) : null; // Get the direction of step navigation
- var stepDirection = '';
- if (this.current_index !== null && this.current_index !== idx) {
- stepDirection = this.current_index < idx ? "forward" : "backward";
- }
- var stepPosition = 'middle';
- if (idx === 0) {
- stepPosition = 'first';
- } else if (idx === this.steps.length - 1) {
- stepPosition = 'final';
- }
- this.options.transitionEffect = this.options.transitionEffect.toLowerCase();
- this.pages.finish();
- if (this.options.transitionEffect === 'slide') {
- // normal slide
- if (curPage && curPage.length > 0) {
- curPage.slideUp('fast', this.options.transitionEasing, function () {
- selPage.slideDown(mi.options.transitionSpeed, mi.options.transitionEasing);
- });
- } else {
- selPage.slideDown(this.options.transitionSpeed, this.options.transitionEasing);
- }
- } else if (this.options.transitionEffect === 'fade') {
- // normal fade
- if (curPage && curPage.length > 0) {
- curPage.fadeOut('fast', this.options.transitionEasing, function () {
- selPage.fadeIn('fast', mi.options.transitionEasing, function () {
- $(this).show();
- });
- });
- } else {
- selPage.fadeIn(this.options.transitionSpeed, this.options.transitionEasing, function () {
- $(this).show();
- });
- }
- } else {
- if (curPage && curPage.length > 0) {
- curPage.hide();
- }
- selPage.show();
- } // Change the url hash to new step
- this._setURLHash(selTab.attr("href")); // Update controls
- this._setAnchor(idx); // Set the buttons based on the step
- this._setButtons(idx); // Fix height with content
- this._fixHeight(idx); // Update the current index
- this.current_index = idx; // Trigger "showStep" event
- this._triggerEvent("showStep", [selTab, this.current_index, stepDirection, stepPosition]);
- return true;
- },
- _setAnchor: function (idx) {
- // Current step anchor > Remove other classes and add done class
- this.steps.eq(this.current_index).parent('li').removeClass("active");
- if (this.options.anchorSettings.markDoneStep !== false && this.current_index !== null) {
- this.steps.eq(this.current_index).parent('li').addClass("done");
- if (this.options.anchorSettings.removeDoneStepOnNavigateBack !== false) {
- this.steps.eq(idx).parent('li').nextAll().removeClass("done");
- }
- } // Next step anchor > Remove other classes and add active class
- this.steps.eq(idx).parent('li').removeClass("done").addClass("active");
- return true;
- },
- _setButtons: function (idx) {
- // Previous/Next Button enable/disable based on step
- if (!this.options.cycleSteps) {
- if (0 >= idx) {
- $('.sw-btn-prev', this.main).addClass("disabled");
- } else {
- $('.sw-btn-prev', this.main).removeClass("disabled");
- }
- if (this.steps.length - 1 <= idx) {
- $('.sw-btn-next', this.main).addClass("disabled");
- } else {
- $('.sw-btn-next', this.main).removeClass("disabled");
- }
- }
- return true;
- },
- // HELPER FUNCTIONS
- _keyNav: function (e) {
- var mi = this; // Keyboard navigation
- switch (e.which) {
- case 37:
- // left
- mi._showPrevious();
- e.preventDefault();
- break;
- case 39:
- // right
- mi._showNext();
- e.preventDefault();
- break;
- default:
- return;
- // exit this handler for other keys
- }
- },
- _fixHeight: function (idx) {
- // Auto adjust height of the container
- if (this.options.autoAdjustHeight) {
- var selPage = this.steps.eq(idx).length > 0 ? $(this.steps.eq(idx).attr("href"), this.main) : null;
- this.container.finish().animate({
- minHeight: selPage.outerHeight()
- }, this.options.transitionSpeed, function () {});
- }
- return true;
- },
- _triggerEvent: function (name, params) {
- // Trigger an event
- var e = $.Event(name);
- this.main.trigger(e, params);
- if (e.isDefaultPrevented()) {
- return false;
- }
- return e.result;
- },
- _setURLHash: function (hash) {
- if (this.options.showStepURLhash && window.location.hash !== hash) {
- window.location.hash = hash;
- }
- },
- _loader: function (action) {
- switch (action) {
- case 'show':
- this.main.addClass('sw-loading');
- break;
- case 'hide':
- this.main.removeClass('sw-loading');
- break;
- default:
- this.main.toggleClass('sw-loading');
- }
- },
- // PUBLIC FUNCTIONS
- goToStep: function (stepNum) {
- this._transitPage(stepNum);
- },
- hiddenSteps: function (r) {
- this.options.hiddenSteps = r; // Hidden steps
- if (this.options.hiddenSteps && this.options.hiddenSteps.length > 0) {
- var mi = this;
- $.each(mi.steps, function (i, n) {
- if ($.inArray(i, mi.options.hiddenSteps) > -1) {
- $(n).parent('li').addClass('hidden');
- } else {
- $(n).parent('li').removeClass('hidden');
- }
- });
- }
- },
- theme: function (v) {
- if (this.options.theme === v) {
- return false;
- }
- this.main.removeClass('sw-theme-' + this.options.theme);
- this.options.theme = v;
- this.main.addClass('sw-theme-' + this.options.theme); // Trigger "themeChanged" event
- this._triggerEvent("themeChanged", [this.options.theme]);
- },
- next: function () {
- this._showNext();
- },
- prev: function () {
- this._showPrevious();
- },
- reset: function () {
- // Trigger "beginReset" event
- if (this._triggerEvent("beginReset") === false) {
- return false;
- } // Reset all elements and classes
- this.container.stop(true);
- this.pages.stop(true);
- this.pages.hide();
- this.current_index = null;
- this._setURLHash(this.steps.eq(this.options.selected).attr("href"));
- $(".sw-toolbar", this.main).remove();
- this.steps.removeClass();
- this.steps.parents('li').removeClass();
- this.steps.data('has-content', false);
- this.init(); // Trigger "endReset" event
- this._triggerEvent("endReset");
- },
- stepState: function (stepArray, state) {
- var mi = this;
- stepArray = $.isArray(stepArray) ? stepArray : [stepArray];
- var selSteps = $.grep(this.steps, function (n, i) {
- return $.inArray(i, stepArray) !== -1; // && i !== mi.current_index
- });
- if (selSteps && selSteps.length > 0) {
- switch (state) {
- case 'disable':
- $(selSteps).parents('li').addClass('disabled');
- break;
- case 'enable':
- $(selSteps).parents('li').removeClass('disabled');
- break;
- case 'hide':
- $(selSteps).parents('li').addClass('hidden');
- break;
- case 'show':
- $(selSteps).parents('li').removeClass('hidden');
- break;
- case 'error-on':
- $(selSteps).parents('li').addClass('danger');
- break;
- case 'error-off':
- $(selSteps).parents('li').removeClass('danger');
- break;
- }
- }
- }
- }); // Wrapper for the plugin
- $.fn.smartWizard = function (options) {
- var args = arguments;
- var instance;
- if (options === undefined || typeof options === 'object') {
- return this.each(function () {
- if (!$.data(this, "smartWizard")) {
- $.data(this, "smartWizard", new SmartWizard(this, options));
- }
- });
- } else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') {
- instance = $.data(this[0], 'smartWizard');
- if (options === 'destroy') {
- $.data(this, 'smartWizard', null);
- }
- if (instance instanceof SmartWizard && typeof instance[options] === 'function') {
- return instance[options].apply(instance, Array.prototype.slice.call(args, 1));
- } else {
- return this;
- }
- }
- };
- })(jQuery, window, document);
|