smartwizard.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
  1. /*!
  2. * SmartWizard v4.4.1
  3. * The awesome jQuery step wizard plugin with Bootstrap support
  4. * http://www.techlaboratory.net/smartwizard
  5. *
  6. * Created by Dipu Raj
  7. * http://dipuraj.me
  8. *
  9. * Licensed under the terms of the MIT License
  10. * https://github.com/techlab/SmartWizard/blob/master/LICENSE
  11. */
  12. ;
  13. (function ($, window, document, undefined) {
  14. "use strict"; // Default options
  15. var defaults = {
  16. selected: 0,
  17. // Initial selected step, 0 = first step
  18. keyNavigation: true,
  19. // Enable/Disable keyboard navigation(left and right keys are used if enabled)
  20. autoAdjustHeight: true,
  21. // Automatically adjust content height
  22. cycleSteps: false,
  23. // Allows to cycle the navigation of steps
  24. backButtonSupport: true,
  25. // Enable the back button support
  26. useURLhash: true,
  27. // Enable selection of the step based on url hash
  28. showStepURLhash: true,
  29. // Show url hash based on step
  30. lang: {
  31. // Language variables for button
  32. next: 'Next',
  33. previous: 'Previous'
  34. },
  35. toolbarSettings: {
  36. toolbarPosition: 'bottom',
  37. // none, top, bottom, both
  38. toolbarButtonPosition: 'end',
  39. // start, end
  40. showNextButton: true,
  41. // show/hide a Next button
  42. showPreviousButton: true,
  43. // show/hide a Previous button
  44. toolbarExtraButtons: [] // Extra buttons to show on toolbar, array of jQuery input/buttons elements
  45. },
  46. anchorSettings: {
  47. anchorClickable: true,
  48. // Enable/Disable anchor navigation
  49. enableAllAnchors: false,
  50. // Activates all anchors clickable all times
  51. markDoneStep: true,
  52. // Add done css
  53. markAllPreviousStepsAsDone: true,
  54. // When a step selected by url hash, all previous steps are marked done
  55. removeDoneStepOnNavigateBack: false,
  56. // While navigate back done step after active step will be cleared
  57. enableAnchorOnDoneStep: true // Enable/Disable the done steps navigation
  58. },
  59. contentURL: null,
  60. // content url, Enables Ajax content loading. Can also set as data data-content-url on anchor
  61. contentCache: true,
  62. // cache step contents, if false content is fetched always from ajax url
  63. ajaxSettings: {},
  64. // Ajax extra settings
  65. disabledSteps: [],
  66. // Array Steps disabled
  67. errorSteps: [],
  68. // Highlight step with errors
  69. hiddenSteps: [],
  70. // Hidden steps
  71. theme: 'default',
  72. // theme for the wizard, related css need to include for other than default theme
  73. transitionEffect: 'none',
  74. // Effect on navigation, none/slide/fade
  75. transitionSpeed: '400'
  76. }; // The plugin constructor
  77. function SmartWizard(element, options) {
  78. // Merge user settings with default, recursively
  79. this.options = $.extend(true, {}, defaults, options); // Main container element
  80. this.main = $(element); // Navigation bar element
  81. this.nav = this.main.children('ul'); // Step anchor elements
  82. this.steps = $("li > a", this.nav); // Content container
  83. this.container = this.main.children('div'); // Content pages
  84. this.pages = this.container.children('div'); // Active step index
  85. this.current_index = null; // Backward compatibility
  86. this.options.toolbarSettings.toolbarButtonPosition = this.options.toolbarSettings.toolbarButtonPosition === 'right' ? 'end' : this.options.toolbarSettings.toolbarButtonPosition;
  87. this.options.toolbarSettings.toolbarButtonPosition = this.options.toolbarSettings.toolbarButtonPosition === 'left' ? 'start' : this.options.toolbarSettings.toolbarButtonPosition; // Default fix
  88. this.options.theme = this.options.theme === null || this.options.theme === '' ? 'default' : this.options.theme; // Call initial method
  89. this.init();
  90. }
  91. $.extend(SmartWizard.prototype, {
  92. init: function () {
  93. // Set the elements
  94. this._setElements(); // Add toolbar
  95. this._setToolbar(); // Assign plugin events
  96. this._setEvents();
  97. var idx = this.options.selected; // Get selected step from the url
  98. if (this.options.useURLhash) {
  99. // Get step number from url hash if available
  100. var hash = window.location.hash;
  101. if (hash && hash.length > 0) {
  102. var elm = $("a[href*='" + hash + "']", this.nav);
  103. if (elm.length > 0) {
  104. var id = this.steps.index(elm);
  105. idx = id >= 0 ? id : idx;
  106. }
  107. }
  108. }
  109. if (idx > 0 && this.options.anchorSettings.markDoneStep && this.options.anchorSettings.markAllPreviousStepsAsDone) {
  110. // Mark previous steps of the active step as done
  111. this.steps.eq(idx).parent('li').prevAll().addClass("done");
  112. } // Show the initial step
  113. this._showStep(idx);
  114. },
  115. // PRIVATE FUNCTIONS
  116. _setElements: function () {
  117. // Set the main element
  118. this.main.addClass('sw-main sw-theme-' + this.options.theme); // Set anchor elements
  119. this.nav.addClass('nav nav-tabs step-anchor').children('li').addClass('nav-item').children('a').addClass('nav-link'); // nav-justified nav-pills
  120. // Make the anchor clickable
  121. if (this.options.anchorSettings.enableAllAnchors !== false && this.options.anchorSettings.anchorClickable !== false) {
  122. this.steps.parent('li').addClass('clickable');
  123. } // Set content container
  124. this.container.addClass('sw-container tab-content'); // Set content pages
  125. this.pages.addClass('tab-pane step-content'); // Disabled steps
  126. var mi = this;
  127. if (this.options.disabledSteps && this.options.disabledSteps.length > 0) {
  128. $.each(this.options.disabledSteps, function (i, n) {
  129. mi.steps.eq(n).parent('li').addClass('disabled');
  130. });
  131. } // Error steps
  132. if (this.options.errorSteps && this.options.errorSteps.length > 0) {
  133. $.each(this.options.errorSteps, function (i, n) {
  134. mi.steps.eq(n).parent('li').addClass('danger');
  135. });
  136. } // Hidden steps
  137. if (this.options.hiddenSteps && this.options.hiddenSteps.length > 0) {
  138. $.each(this.options.hiddenSteps, function (i, n) {
  139. mi.steps.eq(n).parent('li').addClass('hidden');
  140. });
  141. }
  142. return true;
  143. },
  144. _setToolbar: function () {
  145. // Skip right away if the toolbar is not enabled
  146. if (this.options.toolbarSettings.toolbarPosition === 'none') {
  147. return true;
  148. } // Create the toolbar buttons
  149. 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;
  150. 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;
  151. var btnGroup = $('<div></div>').addClass('btn-group mr-2 sw-btn-group').attr('role', 'group').append(btnPrevious, btnNext); // Add extra toolbar buttons
  152. var btnGroupExtra = null;
  153. if (this.options.toolbarSettings.toolbarExtraButtons && this.options.toolbarSettings.toolbarExtraButtons.length > 0) {
  154. btnGroupExtra = $('<div></div>').addClass('btn-group mr-2 sw-btn-group-extra').attr('role', 'group');
  155. $.each(this.options.toolbarSettings.toolbarExtraButtons, function (i, n) {
  156. btnGroupExtra.append(n.clone(true));
  157. });
  158. }
  159. var toolbarTop, toolbarBottom; // Append toolbar based on the position
  160. switch (this.options.toolbarSettings.toolbarPosition) {
  161. case 'top':
  162. toolbarTop = $('<div></div>').addClass('btn-toolbar sw-toolbar sw-toolbar-top justify-content-' + this.options.toolbarSettings.toolbarButtonPosition);
  163. toolbarTop.append(btnGroup);
  164. if (this.options.toolbarSettings.toolbarButtonPosition === 'start') {
  165. toolbarTop.prepend(btnGroupExtra);
  166. } else {
  167. toolbarTop.append(btnGroupExtra);
  168. }
  169. this.container.before(toolbarTop);
  170. break;
  171. case 'bottom':
  172. toolbarBottom = $('<div></div>').addClass('btn-toolbar sw-toolbar sw-toolbar-bottom justify-content-' + this.options.toolbarSettings.toolbarButtonPosition);
  173. toolbarBottom.append(btnGroup);
  174. if (this.options.toolbarSettings.toolbarButtonPosition === 'start') {
  175. toolbarBottom.prepend(btnGroupExtra);
  176. } else {
  177. toolbarBottom.append(btnGroupExtra);
  178. }
  179. this.container.after(toolbarBottom);
  180. break;
  181. case 'both':
  182. toolbarTop = $('<div></div>').addClass('btn-toolbar sw-toolbar sw-toolbar-top justify-content-' + this.options.toolbarSettings.toolbarButtonPosition);
  183. toolbarTop.append(btnGroup);
  184. if (this.options.toolbarSettings.toolbarButtonPosition === 'start') {
  185. toolbarTop.prepend(btnGroupExtra);
  186. } else {
  187. toolbarTop.append(btnGroupExtra);
  188. }
  189. this.container.before(toolbarTop);
  190. toolbarBottom = $('<div></div>').addClass('btn-toolbar sw-toolbar sw-toolbar-bottom justify-content-' + this.options.toolbarSettings.toolbarButtonPosition);
  191. toolbarBottom.append(btnGroup.clone(true));
  192. if (btnGroupExtra !== null) {
  193. if (this.options.toolbarSettings.toolbarButtonPosition === 'start') {
  194. toolbarBottom.prepend(btnGroupExtra.clone(true));
  195. } else {
  196. toolbarBottom.append(btnGroupExtra.clone(true));
  197. }
  198. }
  199. this.container.after(toolbarBottom);
  200. break;
  201. default:
  202. toolbarBottom = $('<div></div>').addClass('btn-toolbar sw-toolbar sw-toolbar-bottom justify-content-' + this.options.toolbarSettings.toolbarButtonPosition);
  203. toolbarBottom.append(btnGroup);
  204. if (this.options.toolbarSettings.toolbarButtonPosition === 'start') {
  205. toolbarBottom.append(btnGroupExtra);
  206. } else {
  207. toolbarBottom.append(btnGroupExtra);
  208. }
  209. this.container.after(toolbarBottom);
  210. break;
  211. }
  212. return true;
  213. },
  214. _setEvents: function () {
  215. // Anchor click event
  216. var mi = this;
  217. $(this.steps).on("click", function (e) {
  218. e.preventDefault();
  219. if (mi.options.anchorSettings.anchorClickable === false) {
  220. return true;
  221. }
  222. var idx = mi.steps.index(this);
  223. if (mi.options.anchorSettings.enableAnchorOnDoneStep === false && mi.steps.eq(idx).parent('li').hasClass('done')) {
  224. return true;
  225. }
  226. if (idx !== mi.current_index) {
  227. if (mi.options.anchorSettings.enableAllAnchors !== false && mi.options.anchorSettings.anchorClickable !== false) {
  228. mi._showStep(idx);
  229. } else {
  230. if (mi.steps.eq(idx).parent('li').hasClass('done')) {
  231. mi._showStep(idx);
  232. }
  233. }
  234. }
  235. }); // Next button event
  236. $('.sw-btn-next', this.main).on("click", function (e) {
  237. e.preventDefault();
  238. mi._showNext();
  239. }); // Previous button event
  240. $('.sw-btn-prev', this.main).on("click", function (e) {
  241. e.preventDefault();
  242. mi._showPrevious();
  243. }); // Keyboard navigation event
  244. if (this.options.keyNavigation) {
  245. $(document).keyup(function (e) {
  246. mi._keyNav(e);
  247. });
  248. } // Back/forward browser button event
  249. if (this.options.backButtonSupport) {
  250. $(window).on('hashchange', function (e) {
  251. if (!mi.options.useURLhash) {
  252. return true;
  253. }
  254. if (window.location.hash) {
  255. var elm = $("a[href*='" + window.location.hash + "']", mi.nav);
  256. if (elm && elm.length > 0) {
  257. e.preventDefault();
  258. mi._showStep(mi.steps.index(elm));
  259. }
  260. }
  261. });
  262. }
  263. return true;
  264. },
  265. _showNext: function () {
  266. var si = this.current_index + 1; // Find the next not disabled step
  267. for (var i = si; i < this.steps.length; i++) {
  268. if (!this.steps.eq(i).parent('li').hasClass('disabled') && !this.steps.eq(i).parent('li').hasClass('hidden')) {
  269. si = i;
  270. break;
  271. }
  272. }
  273. if (this.steps.length <= si) {
  274. if (!this.options.cycleSteps) {
  275. return false;
  276. }
  277. si = 0;
  278. }
  279. this._showStep(si);
  280. return true;
  281. },
  282. _showPrevious: function () {
  283. var si = this.current_index - 1; // Find the previous not disabled step
  284. for (var i = si; i >= 0; i--) {
  285. if (!this.steps.eq(i).parent('li').hasClass('disabled') && !this.steps.eq(i).parent('li').hasClass('hidden')) {
  286. si = i;
  287. break;
  288. }
  289. }
  290. if (0 > si) {
  291. if (!this.options.cycleSteps) {
  292. return false;
  293. }
  294. si = this.steps.length - 1;
  295. }
  296. this._showStep(si);
  297. return true;
  298. },
  299. _showStep: function (idx) {
  300. // If step not found, skip
  301. if (!this.steps.eq(idx)) {
  302. return false;
  303. } // If current step is requested again, skip
  304. if (idx == this.current_index) {
  305. return false;
  306. } // If it is a disabled step, skip
  307. if (this.steps.eq(idx).parent('li').hasClass('disabled') || this.steps.eq(idx).parent('li').hasClass('hidden')) {
  308. return false;
  309. } // Load step content
  310. this._loadStepContent(idx);
  311. return true;
  312. },
  313. _loadStepContent: function (idx) {
  314. var mi = this; // Get current step elements
  315. var curTab = this.steps.eq(this.current_index); // Get the direction of step navigation
  316. var stepDirection = '';
  317. var elm = this.steps.eq(idx);
  318. var contentURL = elm.data('content-url') && elm.data('content-url').length > 0 ? elm.data('content-url') : this.options.contentURL;
  319. if (this.current_index !== null && this.current_index !== idx) {
  320. stepDirection = this.current_index < idx ? "forward" : "backward";
  321. } // Trigger "leaveStep" event
  322. if (this.current_index !== null && this._triggerEvent("leaveStep", [curTab, this.current_index, stepDirection]) === false) {
  323. return false;
  324. }
  325. if (contentURL && contentURL.length > 0 && (!elm.data('has-content') || !this.options.contentCache)) {
  326. // Get ajax content and then show step
  327. var selPage = elm.length > 0 ? $(elm.attr("href"), this.main) : null;
  328. var ajaxSettings = $.extend(true, {}, {
  329. url: contentURL,
  330. type: "POST",
  331. data: {
  332. step_number: idx
  333. },
  334. dataType: "text",
  335. beforeSend: function () {
  336. mi._loader('show');
  337. },
  338. error: function (jqXHR, status, message) {
  339. mi._loader('hide');
  340. $.error(message);
  341. },
  342. success: function (res) {
  343. if (res && res.length > 0) {
  344. elm.data('has-content', true);
  345. selPage.html(res);
  346. }
  347. mi._loader('hide');
  348. mi._transitPage(idx);
  349. }
  350. }, this.options.ajaxSettings);
  351. $.ajax(ajaxSettings);
  352. } else {
  353. // Show step
  354. this._transitPage(idx);
  355. }
  356. return true;
  357. },
  358. _transitPage: function (idx) {
  359. var mi = this; // Get current step elements
  360. var curTab = this.steps.eq(this.current_index);
  361. var curPage = curTab.length > 0 ? $(curTab.attr("href"), this.main) : null; // Get step to show elements
  362. var selTab = this.steps.eq(idx);
  363. var selPage = selTab.length > 0 ? $(selTab.attr("href"), this.main) : null; // Get the direction of step navigation
  364. var stepDirection = '';
  365. if (this.current_index !== null && this.current_index !== idx) {
  366. stepDirection = this.current_index < idx ? "forward" : "backward";
  367. }
  368. var stepPosition = 'middle';
  369. if (idx === 0) {
  370. stepPosition = 'first';
  371. } else if (idx === this.steps.length - 1) {
  372. stepPosition = 'final';
  373. }
  374. this.options.transitionEffect = this.options.transitionEffect.toLowerCase();
  375. this.pages.finish();
  376. if (this.options.transitionEffect === 'slide') {
  377. // normal slide
  378. if (curPage && curPage.length > 0) {
  379. curPage.slideUp('fast', this.options.transitionEasing, function () {
  380. selPage.slideDown(mi.options.transitionSpeed, mi.options.transitionEasing);
  381. });
  382. } else {
  383. selPage.slideDown(this.options.transitionSpeed, this.options.transitionEasing);
  384. }
  385. } else if (this.options.transitionEffect === 'fade') {
  386. // normal fade
  387. if (curPage && curPage.length > 0) {
  388. curPage.fadeOut('fast', this.options.transitionEasing, function () {
  389. selPage.fadeIn('fast', mi.options.transitionEasing, function () {
  390. $(this).show();
  391. });
  392. });
  393. } else {
  394. selPage.fadeIn(this.options.transitionSpeed, this.options.transitionEasing, function () {
  395. $(this).show();
  396. });
  397. }
  398. } else {
  399. if (curPage && curPage.length > 0) {
  400. curPage.hide();
  401. }
  402. selPage.show();
  403. } // Change the url hash to new step
  404. this._setURLHash(selTab.attr("href")); // Update controls
  405. this._setAnchor(idx); // Set the buttons based on the step
  406. this._setButtons(idx); // Fix height with content
  407. this._fixHeight(idx); // Update the current index
  408. this.current_index = idx; // Trigger "showStep" event
  409. this._triggerEvent("showStep", [selTab, this.current_index, stepDirection, stepPosition]);
  410. return true;
  411. },
  412. _setAnchor: function (idx) {
  413. // Current step anchor > Remove other classes and add done class
  414. this.steps.eq(this.current_index).parent('li').removeClass("active");
  415. if (this.options.anchorSettings.markDoneStep !== false && this.current_index !== null) {
  416. this.steps.eq(this.current_index).parent('li').addClass("done");
  417. if (this.options.anchorSettings.removeDoneStepOnNavigateBack !== false) {
  418. this.steps.eq(idx).parent('li').nextAll().removeClass("done");
  419. }
  420. } // Next step anchor > Remove other classes and add active class
  421. this.steps.eq(idx).parent('li').removeClass("done").addClass("active");
  422. return true;
  423. },
  424. _setButtons: function (idx) {
  425. // Previous/Next Button enable/disable based on step
  426. if (!this.options.cycleSteps) {
  427. if (0 >= idx) {
  428. $('.sw-btn-prev', this.main).addClass("disabled");
  429. } else {
  430. $('.sw-btn-prev', this.main).removeClass("disabled");
  431. }
  432. if (this.steps.length - 1 <= idx) {
  433. $('.sw-btn-next', this.main).addClass("disabled");
  434. } else {
  435. $('.sw-btn-next', this.main).removeClass("disabled");
  436. }
  437. }
  438. return true;
  439. },
  440. // HELPER FUNCTIONS
  441. _keyNav: function (e) {
  442. var mi = this; // Keyboard navigation
  443. switch (e.which) {
  444. case 37:
  445. // left
  446. mi._showPrevious();
  447. e.preventDefault();
  448. break;
  449. case 39:
  450. // right
  451. mi._showNext();
  452. e.preventDefault();
  453. break;
  454. default:
  455. return;
  456. // exit this handler for other keys
  457. }
  458. },
  459. _fixHeight: function (idx) {
  460. // Auto adjust height of the container
  461. if (this.options.autoAdjustHeight) {
  462. var selPage = this.steps.eq(idx).length > 0 ? $(this.steps.eq(idx).attr("href"), this.main) : null;
  463. this.container.finish().animate({
  464. minHeight: selPage.outerHeight()
  465. }, this.options.transitionSpeed, function () {});
  466. }
  467. return true;
  468. },
  469. _triggerEvent: function (name, params) {
  470. // Trigger an event
  471. var e = $.Event(name);
  472. this.main.trigger(e, params);
  473. if (e.isDefaultPrevented()) {
  474. return false;
  475. }
  476. return e.result;
  477. },
  478. _setURLHash: function (hash) {
  479. if (this.options.showStepURLhash && window.location.hash !== hash) {
  480. window.location.hash = hash;
  481. }
  482. },
  483. _loader: function (action) {
  484. switch (action) {
  485. case 'show':
  486. this.main.addClass('sw-loading');
  487. break;
  488. case 'hide':
  489. this.main.removeClass('sw-loading');
  490. break;
  491. default:
  492. this.main.toggleClass('sw-loading');
  493. }
  494. },
  495. // PUBLIC FUNCTIONS
  496. goToStep: function (stepNum) {
  497. this._transitPage(stepNum);
  498. },
  499. hiddenSteps: function (r) {
  500. this.options.hiddenSteps = r; // Hidden steps
  501. if (this.options.hiddenSteps && this.options.hiddenSteps.length > 0) {
  502. var mi = this;
  503. $.each(mi.steps, function (i, n) {
  504. if ($.inArray(i, mi.options.hiddenSteps) > -1) {
  505. $(n).parent('li').addClass('hidden');
  506. } else {
  507. $(n).parent('li').removeClass('hidden');
  508. }
  509. });
  510. }
  511. },
  512. theme: function (v) {
  513. if (this.options.theme === v) {
  514. return false;
  515. }
  516. this.main.removeClass('sw-theme-' + this.options.theme);
  517. this.options.theme = v;
  518. this.main.addClass('sw-theme-' + this.options.theme); // Trigger "themeChanged" event
  519. this._triggerEvent("themeChanged", [this.options.theme]);
  520. },
  521. next: function () {
  522. this._showNext();
  523. },
  524. prev: function () {
  525. this._showPrevious();
  526. },
  527. reset: function () {
  528. // Trigger "beginReset" event
  529. if (this._triggerEvent("beginReset") === false) {
  530. return false;
  531. } // Reset all elements and classes
  532. this.container.stop(true);
  533. this.pages.stop(true);
  534. this.pages.hide();
  535. this.current_index = null;
  536. this._setURLHash(this.steps.eq(this.options.selected).attr("href"));
  537. $(".sw-toolbar", this.main).remove();
  538. this.steps.removeClass();
  539. this.steps.parents('li').removeClass();
  540. this.steps.data('has-content', false);
  541. this.init(); // Trigger "endReset" event
  542. this._triggerEvent("endReset");
  543. },
  544. stepState: function (stepArray, state) {
  545. var mi = this;
  546. stepArray = $.isArray(stepArray) ? stepArray : [stepArray];
  547. var selSteps = $.grep(this.steps, function (n, i) {
  548. return $.inArray(i, stepArray) !== -1; // && i !== mi.current_index
  549. });
  550. if (selSteps && selSteps.length > 0) {
  551. switch (state) {
  552. case 'disable':
  553. $(selSteps).parents('li').addClass('disabled');
  554. break;
  555. case 'enable':
  556. $(selSteps).parents('li').removeClass('disabled');
  557. break;
  558. case 'hide':
  559. $(selSteps).parents('li').addClass('hidden');
  560. break;
  561. case 'show':
  562. $(selSteps).parents('li').removeClass('hidden');
  563. break;
  564. case 'error-on':
  565. $(selSteps).parents('li').addClass('danger');
  566. break;
  567. case 'error-off':
  568. $(selSteps).parents('li').removeClass('danger');
  569. break;
  570. }
  571. }
  572. }
  573. }); // Wrapper for the plugin
  574. $.fn.smartWizard = function (options) {
  575. var args = arguments;
  576. var instance;
  577. if (options === undefined || typeof options === 'object') {
  578. return this.each(function () {
  579. if (!$.data(this, "smartWizard")) {
  580. $.data(this, "smartWizard", new SmartWizard(this, options));
  581. }
  582. });
  583. } else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') {
  584. instance = $.data(this[0], 'smartWizard');
  585. if (options === 'destroy') {
  586. $.data(this, 'smartWizard', null);
  587. }
  588. if (instance instanceof SmartWizard && typeof instance[options] === 'function') {
  589. return instance[options].apply(instance, Array.prototype.slice.call(args, 1));
  590. } else {
  591. return this;
  592. }
  593. }
  594. };
  595. })(jQuery, window, document);