├── .editorconfig ├── .eslintrc.js ├── .gitattributes ├── .gitignore ├── .prettierignore ├── .prettierrc.js ├── README.md ├── dist ├── jquery-steps.css ├── jquery-steps.css.map ├── jquery-steps.js ├── jquery-steps.js.map └── jquery-steps.min.js ├── examples ├── api.html ├── async.html ├── basic.html ├── callbacks.html ├── css │ └── style.css └── multiple.html ├── package-lock.json ├── package.json ├── rollup.config.js ├── src ├── Defaults.js ├── Plugin.js ├── Steps.js └── styl │ └── jquery-steps.styl └── test ├── index.html └── spec.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parserOptions: { 3 | sourceType: 'module', 4 | }, 5 | env: { 6 | es6: true, 7 | browser: true, 8 | jquery: true, 9 | }, 10 | extends: ['eslint:recommended', 'airbnb-base', 'plugin:prettier/recommended'], 11 | rules: { 12 | 'prettier/prettier': ['error', {}, { usePrettierrc: true }], 13 | indent: ['error', 2], 14 | quotes: ['error', 'single'], 15 | semi: ['error', 'always'], 16 | 'linebreak-style': ['error', 'unix'], 17 | 'no-unused-vars': [ 18 | 'error', 19 | { 20 | argsIgnorePattern: 'next', 21 | }, 22 | ], 23 | 'eol-last': ['error', 'always'], 24 | 'class-methods-use-this': 0, 25 | 'func-names': 0, 26 | }, 27 | }; 28 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Autodetect text files 2 | * text=auto 3 | 4 | # Force the following filetypes to have unix eols, so Windows does not break them 5 | *.* text eol=lf 6 | 7 | # Force images/fonts to be handled as binaries 8 | *.jpg binary 9 | *.jpeg binary 10 | *.gif binary 11 | *.png binary 12 | *.ttf binary 13 | *.eof binary 14 | *.eot binary 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | website/ 2 | 3 | # OS X 4 | .DS_Store* 5 | Icon? 6 | ._* 7 | 8 | # Windows 9 | Thumbs.db 10 | ehthumbs.db 11 | Desktop.ini 12 | 13 | # Linux 14 | .directory 15 | *~ 16 | 17 | # API keys and secrets 18 | .env 19 | 20 | # npm 21 | .npm # Optional npm cache directory 22 | node_modules 23 | bower_components 24 | *.log 25 | *.gz 26 | 27 | # others 28 | lib-cov 29 | *.csv 30 | *.dat 31 | *.out 32 | *.swp 33 | 34 | # Coveralls 35 | coverage 36 | 37 | # Benchmarking 38 | benchmarks/graphs 39 | 40 | # Compiled binary addons (http://nodejs.org/api/addons.html) 41 | build/Release 42 | 43 | # Optional REPL history 44 | .node_repl_history 45 | 46 | # Runtime data 47 | pids 48 | *.pid 49 | *.seed 50 | 51 | # Editors 52 | .idea 53 | *.iml 54 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | package-lock.json 3 | dist 4 | examples 5 | *.md 6 | *.css 7 | *.html 8 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | semi: true, 3 | trailingComma: 'all', 4 | singleQuote: true, 5 | printWidth: 80, 6 | tabWidth: 2, 7 | useTabs: false, 8 | bracketSameLine: true, 9 | endOfLine: 'lf', 10 | }; 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## ![jquery-steps](https://oguzhanoya.github.io/jquery-steps/img/logo.svg) 2 | 3 | [![npm](https://img.shields.io/npm/v/jquery.steps)](https://www.npmjs.com/package/jquery.steps) 4 | [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) 5 | [![npm](https://img.shields.io/npm/dm/jquery.steps)](https://www.npmjs.com/package/jquery.steps) 6 | [![npm](https://img.shields.io/jsdelivr/npm/hm/jquery.steps)](https://www.jsdelivr.com/package/npm/jquery.steps) 7 | 8 | > A simple, lightweight jQuery step wizard plugin. 9 | 10 | ## Features 11 | - Easy configuration 12 | - Lightweight (2KB gzipped) 13 | - Works in all major browsers including IE11+ 14 | 15 | ## Compatibility 16 | IE11+, Edge, Chrome, Firefox, Opera, Safari 17 | 18 | ## Installation 19 | NPM 20 | ```sh 21 | npm install jquery.steps 22 | ``` 23 | Github 24 | ```sh 25 | git clone http://github.com/oguzhanoya/jquery-steps.git 26 | ``` 27 | CDN 28 | ```html 29 | 30 | 31 | ``` 32 | 33 | ## Setup 34 | 35 | Include plugin stylesheets. 36 | ```html 37 | 38 | ``` 39 | Make necessary markup for wizard. That's all, you don't need to do anything else. 40 | ```html 41 |
42 | 47 |
48 |
49 | ... 50 |
51 |
52 | ... 53 |
54 |
55 | ... 56 |
57 |
58 | 63 |
64 | ``` 65 | Include plugin and dependeces. jQuery is the only dependency, make sure to include it. 66 | ```html 67 | 68 | 69 | ``` 70 | Init plugin with choosen options. 71 | ```html 72 | 77 | ``` 78 | ## Configuration 79 | 80 | |Setting|Default Value|Description| 81 | |---|---|---| 82 | |startAt|`0`|Starts wizard at specifed step number.| 83 | |showBackButton|`true`|Indicates whether the back button will be visible.| 84 | |showFooterButtons|`true`|Indicates whether the footer buttons will be visible.| 85 | |stepSelector|`.step-steps`|The selector used for each step.| 86 | |contentSelector|`.step-content`|The selector used for the step content.| 87 | |footerSelector|`.step-footer`|The selector used for the buttons.| 88 | |activeClass|`active`|The class used when a step is active.| 89 | |doneClass|`done`|The class used when a step is done.| 90 | |errorClass|`error`|The class used when an error occurs in a step.| 91 | |onInit|`function(){}`|Fired when plugin is initialized.| 92 | |onChange|`function(currentIndex, newIndex, stepDirection){return true;}`|Fired when plugin step changed.| 93 | |onFinish|`function(){}`|Fired when plugin wizard finished.| 94 | |onDestroy|`function(){}`|Fired when plugin destroy.| 95 | 96 | ## Methods 97 | 98 | |Name|Description| 99 | |---|---| 100 | |destory|Destroy the plugin instance.| 101 | |next|Goes to the next step.| 102 | |prev|Goes to the previous step.| 103 | |finish|Trigger the onFinish event.| 104 | |getStepIndex|Gets the current step index.(start from 0)| 105 | |getMaxStepIndex|Gets the max step index.| 106 | |setStepIndex|Sets the step index.| 107 | 108 | ## License 109 | 110 | MIT 111 | -------------------------------------------------------------------------------- /dist/jquery-steps.css: -------------------------------------------------------------------------------- 1 | .step-app > .step-steps { 2 | margin: 0; 3 | padding: 0; 4 | display: flex; 5 | border-radius: 3px 3px 0 0; 6 | overflow: hidden; 7 | } 8 | .step-app > .step-steps > li { 9 | list-style: none; 10 | flex: 1; 11 | cursor: pointer; 12 | display: block; 13 | padding: 10px; 14 | color: #333; 15 | background-color: #e5e5e5; 16 | text-decoration: none; 17 | border-right: 1px solid #fff; 18 | } 19 | .step-app > .step-steps > li:hover { 20 | background-color: #ddd; 21 | } 22 | .step-app > .step-steps > li:last-child a { 23 | border: none; 24 | } 25 | .step-app > .step-steps > li.active { 26 | background-color: #32c5d2; 27 | color: #fff; 28 | } 29 | .step-app > .step-steps > li.error { 30 | background-color: #e7505a; 31 | color: #fff; 32 | } 33 | .step-app > .step-steps > li.done { 34 | background-color: #3cb371; 35 | color: #fff; 36 | } 37 | .step-app > .step-steps > li > .number { 38 | background: #fff; 39 | padding: 0 8px; 40 | display: inline-block; 41 | text-align: center; 42 | margin-right: 15px; 43 | border-radius: 3px; 44 | color: #333; 45 | } 46 | .step-app > .step-content { 47 | border: 1px solid #e5e5e5; 48 | padding: 10px; 49 | border-top: 0; 50 | } 51 | .step-app > .step-content > .step-tab-panel { 52 | display: none; 53 | } 54 | .step-app > .step-content > .step-tab-panel.active { 55 | display: block; 56 | } 57 | .step-app > .step-footer { 58 | margin-top: 15px; 59 | margin-bottom: 15px; 60 | } 61 | .step-app > .step-footer > .step-btn { 62 | padding: 4px 16px; 63 | color: #333; 64 | text-decoration: none; 65 | background: #e5e5e5; 66 | border-radius: 3px; 67 | border: none; 68 | outline: none; 69 | cursor: pointer; 70 | } 71 | /*# sourceMappingURL=jquery-steps.css.map */ -------------------------------------------------------------------------------- /dist/jquery-steps.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["../src/styl/jquery-steps.styl"],"names":[],"mappings":"AAOE;EACE,QAAO,EAAP;EACA,SAAQ,EAAR;EACA,SAAQ,KAAR;EACA,eAAc,YAAd;EACA,UAAS,OAAT;;AACA;EACE,YAAW,KAAX;EACA,MAAK,EAAL;EAcA,QAAO,QAAP;EACA,SAAQ,MAAR;EACA,SAAQ,KAAR;EACA,OAAM,KAAN;EACA,kBAAiB,QAAjB;EACA,iBAAgB,KAAhB;EACA,cAAa,eAAb;;AAnBA;EACE,kBAAiB,KAAjB;;AACF;EACI,QAAO,KAAP;;AACJ;EACE,kBAAiB,QAAjB;EACA,OAAM,KAAN;;AACF;EACE,kBAAiB,QAAjB;EACA,OAAM,KAAN;;AACF;EACE,kBAAiB,QAAjB;EACA,OAAM,KAAN;;AAQF;EACE,YAAW,KAAX;EACA,SAAQ,MAAR;EACA,SAAQ,aAAR;EACA,YAAW,OAAX;EACA,cAAa,KAAb;EACA,eAAc,IAAd;EACA,OAAM,KAAN;;AAEN;EACE,QAAO,kBAAP;EACA,SAAQ,KAAR;EACA,YAAW,EAAX;;AACA;EACE,SAAQ,KAAR;;AACA;EACE,SAAQ,MAAR;;AACN;EACE,YAAW,KAAX;EACA,eAAc,KAAd;;AACA;EACE,SAAQ,SAAR;EACA,OAAM,KAAN;EACA,iBAAgB,KAAhB;EACA,YAAW,QAAX;EACA,eAAc,IAAd;EACA,QAAO,KAAP;EACA,SAAQ,KAAR;EACA,QAAO,QAAP","file":"jquery-steps.css"} -------------------------------------------------------------------------------- /dist/jquery-steps.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Steps v1.1.4 3 | * https://github.com/oguzhanoya/jquery-steps 4 | * 5 | * Copyright (c) 2022 oguzhanoya 6 | * Released under the MIT license 7 | */ 8 | 9 | (function (global, factory) { 10 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('jquery')) : 11 | typeof define === 'function' && define.amd ? define(['jquery'], factory) : 12 | (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.$)); 13 | })(this, (function ($$1) { 'use strict'; 14 | 15 | function _classCallCheck(instance, Constructor) { 16 | if (!(instance instanceof Constructor)) { 17 | throw new TypeError("Cannot call a class as a function"); 18 | } 19 | } 20 | function _defineProperties(target, props) { 21 | for (var i = 0; i < props.length; i++) { 22 | var descriptor = props[i]; 23 | descriptor.enumerable = descriptor.enumerable || false; 24 | descriptor.configurable = true; 25 | if ("value" in descriptor) descriptor.writable = true; 26 | Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); 27 | } 28 | } 29 | function _createClass(Constructor, protoProps, staticProps) { 30 | if (protoProps) _defineProperties(Constructor.prototype, protoProps); 31 | if (staticProps) _defineProperties(Constructor, staticProps); 32 | Object.defineProperty(Constructor, "prototype", { 33 | writable: false 34 | }); 35 | return Constructor; 36 | } 37 | function _toPrimitive(input, hint) { 38 | if (typeof input !== "object" || input === null) return input; 39 | var prim = input[Symbol.toPrimitive]; 40 | if (prim !== undefined) { 41 | var res = prim.call(input, hint || "default"); 42 | if (typeof res !== "object") return res; 43 | throw new TypeError("@@toPrimitive must return a primitive value."); 44 | } 45 | return (hint === "string" ? String : Number)(input); 46 | } 47 | function _toPropertyKey(arg) { 48 | var key = _toPrimitive(arg, "string"); 49 | return typeof key === "symbol" ? key : String(key); 50 | } 51 | 52 | var DEFAULTS = { 53 | startAt: 0, 54 | showBackButton: true, 55 | showFooterButtons: true, 56 | onInit: $.noop, 57 | onDestroy: $.noop, 58 | onFinish: $.noop, 59 | onChange: function onChange() { 60 | return true; 61 | }, 62 | stepSelector: '.step-steps', 63 | contentSelector: '.step-content', 64 | footerSelector: '.step-footer', 65 | activeClass: 'active', 66 | doneClass: 'done', 67 | errorClass: 'error' 68 | }; 69 | 70 | var Steps = /*#__PURE__*/function () { 71 | function Steps(element, options) { 72 | _classCallCheck(this, Steps); 73 | // Extend defaults with the init options. 74 | this.options = $$1.extend({}, DEFAULTS, options); 75 | 76 | // Store main DOM element. 77 | this.el = $$1(element); 78 | this.selectors = { 79 | step: "".concat(this.options.stepSelector, " [data-step-target]"), 80 | footer: "".concat(this.options.footerSelector, " [data-step-action]"), 81 | content: "".concat(this.options.contentSelector, " [data-step]") 82 | }; 83 | 84 | // Initialize 85 | this.init(); 86 | } 87 | _createClass(Steps, [{ 88 | key: "stepClick", 89 | value: function stepClick(e) { 90 | e.preventDefault(); 91 | var self = e.data.self; 92 | var all = self.el.find(self.selectors.step); 93 | var next = e.currentTarget; 94 | var nextStepIndex = all.index(next); 95 | var currentStepIndex = e.data.self.getStepIndex(); 96 | e.data.self.setActiveStep(currentStepIndex, nextStepIndex); 97 | } 98 | }, { 99 | key: "btnClick", 100 | value: function btnClick(e) { 101 | e.preventDefault(); 102 | var statusAction = $$1(this).data('step-action'); 103 | e.data.self.setAction(statusAction); 104 | } 105 | }, { 106 | key: "init", 107 | value: function init() { 108 | this.hook('onInit'); 109 | this.initEventListeners(); 110 | 111 | // set default step 112 | this.setActiveStep(0, this.options.startAt, true); 113 | 114 | // show footer buttons 115 | if (!this.options.showFooterButtons) { 116 | this.hideFooterButtons(); 117 | this.updateFooterButtons = $$1.noop; 118 | } 119 | } 120 | }, { 121 | key: "initEventListeners", 122 | value: function initEventListeners() { 123 | // step click event 124 | $$1(this.el).find(this.selectors.step).on('click', { 125 | self: this 126 | }, this.stepClick); 127 | 128 | // button click event 129 | $$1(this.el).find(this.selectors.footer).on('click', { 130 | self: this 131 | }, this.btnClick); 132 | } 133 | }, { 134 | key: "hook", 135 | value: function hook(hookName) { 136 | if (this.options[hookName] !== undefined) { 137 | this.options[hookName].call(this.el); 138 | } 139 | } 140 | }, { 141 | key: "destroy", 142 | value: function destroy() { 143 | this.hook('onDestroy'); 144 | $$1(this.el).find(this.selectors.step).off('click'); 145 | $$1(this.el).find(this.selectors.footer).off('click'); 146 | this.el.removeData('plugin_Steps'); 147 | this.el.remove(); 148 | } 149 | }, { 150 | key: "getStepIndex", 151 | value: function getStepIndex() { 152 | var all = this.el.find(this.selectors.step); 153 | var activeClass = this.options.activeClass.split(' ').join('.'); 154 | var stepIndex = all.index(all.filter(".".concat(activeClass))); 155 | return stepIndex; 156 | } 157 | }, { 158 | key: "getMaxStepIndex", 159 | value: function getMaxStepIndex() { 160 | return this.el.find(this.selectors.step).length - 1; 161 | } 162 | }, { 163 | key: "getStepDirection", 164 | value: function getStepDirection(stepIndex, newIndex) { 165 | var direction = 'none'; 166 | if (newIndex < stepIndex) { 167 | direction = 'backward'; 168 | } else if (newIndex > stepIndex) { 169 | direction = 'forward'; 170 | } 171 | return direction; 172 | } 173 | }, { 174 | key: "setShowStep", 175 | value: function setShowStep(idx, removeClass) { 176 | var addClass = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; 177 | var $targetStep = this.el.find(this.selectors.step).eq(idx); 178 | $targetStep.removeClass(removeClass).addClass(addClass); 179 | var $tabContent = this.el.find(this.selectors.content); 180 | $tabContent.removeClass(this.options.activeClass).eq(idx).addClass(this.options.activeClass); 181 | } 182 | }, { 183 | key: "setActiveStep", 184 | value: function setActiveStep(currentIndex, newIndex) { 185 | var init = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; 186 | if (newIndex !== currentIndex || init) { 187 | var conditionDirection = newIndex > currentIndex ? function (start) { 188 | return start <= newIndex; 189 | } : function (start) { 190 | return start >= newIndex; 191 | }; 192 | 193 | // prettier-ignore 194 | var conditionIncrementOrDecrement = newIndex > currentIndex ? function (start) { 195 | return start + 1; 196 | } : function (start) { 197 | return start - 1; 198 | }; 199 | var i = currentIndex; 200 | while (conditionDirection(i)) { 201 | var stepDirection = this.getStepDirection(i, newIndex); 202 | this.updateStep(i, newIndex, stepDirection); 203 | var validStep = this.isValidStep(i, newIndex, stepDirection); 204 | if (!validStep) { 205 | this.updateStep(i, newIndex, stepDirection, validStep); 206 | i = newIndex; 207 | } 208 | i = conditionIncrementOrDecrement(i); 209 | } 210 | this.updateFooterButtons(); 211 | } 212 | } 213 | }, { 214 | key: "updateStep", 215 | value: function updateStep(currentIndex, newIndex, direction) { 216 | var isValidStep = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; 217 | if (currentIndex === newIndex) { 218 | this.setShowStep(currentIndex, this.options.doneClass, this.options.activeClass); 219 | } else if (isValidStep) { 220 | var checkDone = direction === 'forward' && this.options.doneClass; 221 | this.setShowStep(currentIndex, "".concat(this.options.activeClass, " ").concat(this.options.errorClass, " ").concat(this.options.doneClass), checkDone); 222 | } else { 223 | this.setShowStep(currentIndex, this.options.doneClass, "".concat(this.options.activeClass, " ").concat(this.options.errorClass)); 224 | } 225 | } 226 | }, { 227 | key: "isValidStep", 228 | value: function isValidStep(currentIndex, newIndex, direction) { 229 | return this.options.onChange(currentIndex, newIndex, direction); 230 | } 231 | }, { 232 | key: "updateFooterButtons", 233 | value: function updateFooterButtons() { 234 | var currentStepIndex = this.getStepIndex(); 235 | var maxStepIndex = this.getMaxStepIndex(); 236 | var $footer = this.el.find(this.selectors.footer); 237 | var $prevButton = $footer.filter('[data-step-action="prev"]'); 238 | var $nextButton = $footer.filter('[data-step-action="next"]'); 239 | var $finishButton = $footer.filter('[data-step-action="finish"]'); 240 | 241 | // hide prev button if current step is the first step 242 | if (currentStepIndex === 0) { 243 | $prevButton.hide(); 244 | } else { 245 | $prevButton.show(); 246 | } 247 | 248 | // hide forward button and show finish button if current step is the last step 249 | if (currentStepIndex === maxStepIndex) { 250 | $nextButton.hide(); 251 | $finishButton.show(); 252 | } else { 253 | $nextButton.show(); 254 | $finishButton.hide(); 255 | } 256 | 257 | // hide back button if showBackButton option is false 258 | if (!this.options.showBackButton) { 259 | $prevButton.hide(); 260 | } 261 | } 262 | }, { 263 | key: "setAction", 264 | value: function setAction(action) { 265 | var currentStepIndex = this.getStepIndex(); 266 | var nextStep = currentStepIndex; 267 | if (action === 'prev') { 268 | nextStep -= 1; 269 | } 270 | if (action === 'next') { 271 | nextStep += 1; 272 | } 273 | if (action === 'finish') { 274 | var validStep = this.isValidStep(currentStepIndex, nextStep, 'forward'); 275 | if (validStep) { 276 | this.hook('onFinish'); 277 | } else { 278 | this.setShowStep(currentStepIndex, '', this.options.errorClass); 279 | } 280 | } else { 281 | this.setActiveStep(currentStepIndex, nextStep); 282 | } 283 | } 284 | }, { 285 | key: "setStepIndex", 286 | value: function setStepIndex(idx) { 287 | var maxIndex = this.getMaxStepIndex(); 288 | if (idx <= maxIndex) { 289 | var currentStepIndex = this.getStepIndex(); 290 | this.setActiveStep(currentStepIndex, idx); 291 | } 292 | } 293 | }, { 294 | key: "next", 295 | value: function next() { 296 | var currentStepIndex = this.getStepIndex(); 297 | var maxIndex = this.getMaxStepIndex(); 298 | return maxIndex === currentStepIndex ? this.setAction('finish') : this.setAction('next'); 299 | } 300 | }, { 301 | key: "prev", 302 | value: function prev() { 303 | var currentStepIndex = this.getStepIndex(); 304 | return currentStepIndex !== 0 && this.setAction('prev'); 305 | } 306 | }, { 307 | key: "finish", 308 | value: function finish() { 309 | this.hook('onFinish'); 310 | } 311 | }, { 312 | key: "hideFooterButtons", 313 | value: function hideFooterButtons() { 314 | this.el.find(this.selectors.footer).hide(); 315 | } 316 | }], [{ 317 | key: "setDefaults", 318 | value: function setDefaults(options) { 319 | $$1.extend(DEFAULTS, $$1.isPlainObject(options) && options); 320 | } 321 | }]); 322 | return Steps; 323 | }(); 324 | 325 | var version = "1.1.4"; 326 | 327 | var previousStepsPlugin = $$1.fn.steps; 328 | $$1.fn.steps = function (options) { 329 | return this.each(function () { 330 | if (!$$1.data(this, 'plugin_Steps')) { 331 | $$1.data(this, 'plugin_Steps', new Steps(this, options)); 332 | } 333 | }); 334 | }; 335 | $$1.fn.steps.version = version; 336 | $$1.fn.steps.setDefaults = Steps.setDefaults; 337 | 338 | // No conflict 339 | $$1.fn.steps.noConflict = function () { 340 | $$1.fn.steps = previousStepsPlugin; 341 | return this; 342 | }; 343 | 344 | })); 345 | //# sourceMappingURL=jquery-steps.js.map 346 | -------------------------------------------------------------------------------- /dist/jquery-steps.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"jquery-steps.js","sources":["../src/Defaults.js","../src/Steps.js","../src/Plugin.js"],"sourcesContent":["export default {\n startAt: 0,\n showBackButton: true,\n showFooterButtons: true,\n onInit: $.noop,\n onDestroy: $.noop,\n onFinish: $.noop,\n onChange() {\n return true;\n },\n stepSelector: '.step-steps',\n contentSelector: '.step-content',\n footerSelector: '.step-footer',\n activeClass: 'active',\n doneClass: 'done',\n errorClass: 'error',\n};\n","import $ from 'jquery';\nimport DEFAULTS from './Defaults';\n\nclass Steps {\n constructor(element, options) {\n // Extend defaults with the init options.\n this.options = $.extend({}, DEFAULTS, options);\n\n // Store main DOM element.\n this.el = $(element);\n\n this.selectors = {\n step: `${this.options.stepSelector} [data-step-target]`,\n footer: `${this.options.footerSelector} [data-step-action]`,\n content: `${this.options.contentSelector} [data-step]`,\n };\n\n // Initialize\n this.init();\n }\n\n stepClick(e) {\n e.preventDefault();\n const { self } = e.data;\n const all = self.el.find(self.selectors.step);\n const next = e.currentTarget;\n const nextStepIndex = all.index(next);\n const currentStepIndex = e.data.self.getStepIndex();\n e.data.self.setActiveStep(currentStepIndex, nextStepIndex);\n }\n\n btnClick(e) {\n e.preventDefault();\n const statusAction = $(this).data('step-action');\n e.data.self.setAction(statusAction);\n }\n\n init() {\n this.hook('onInit');\n\n this.initEventListeners();\n\n // set default step\n this.setActiveStep(0, this.options.startAt, true);\n\n // show footer buttons\n if (!this.options.showFooterButtons) {\n this.hideFooterButtons();\n this.updateFooterButtons = $.noop;\n }\n }\n\n initEventListeners() {\n // step click event\n $(this.el)\n .find(this.selectors.step)\n .on('click', { self: this }, this.stepClick);\n\n // button click event\n $(this.el)\n .find(this.selectors.footer)\n .on('click', { self: this }, this.btnClick);\n }\n\n hook(hookName) {\n if (this.options[hookName] !== undefined) {\n this.options[hookName].call(this.el);\n }\n }\n\n destroy() {\n this.hook('onDestroy');\n $(this.el).find(this.selectors.step).off('click');\n $(this.el).find(this.selectors.footer).off('click');\n this.el.removeData('plugin_Steps');\n this.el.remove();\n }\n\n getStepIndex() {\n const all = this.el.find(this.selectors.step);\n const activeClass = this.options.activeClass.split(' ').join('.');\n const stepIndex = all.index(all.filter(`.${activeClass}`));\n return stepIndex;\n }\n\n getMaxStepIndex() {\n return this.el.find(this.selectors.step).length - 1;\n }\n\n getStepDirection(stepIndex, newIndex) {\n let direction = 'none';\n if (newIndex < stepIndex) {\n direction = 'backward';\n } else if (newIndex > stepIndex) {\n direction = 'forward';\n }\n return direction;\n }\n\n setShowStep(idx, removeClass, addClass = '') {\n const $targetStep = this.el.find(this.selectors.step).eq(idx);\n $targetStep.removeClass(removeClass).addClass(addClass);\n\n const $tabContent = this.el.find(this.selectors.content);\n $tabContent\n .removeClass(this.options.activeClass)\n .eq(idx)\n .addClass(this.options.activeClass);\n }\n\n setActiveStep(currentIndex, newIndex, init = false) {\n if (newIndex !== currentIndex || init) {\n const conditionDirection =\n newIndex > currentIndex\n ? (start) => start <= newIndex\n : (start) => start >= newIndex;\n\n // prettier-ignore\n const conditionIncrementOrDecrement = (newIndex > currentIndex)\n ? (start) => start + 1\n : (start) => start - 1;\n\n let i = currentIndex;\n while (conditionDirection(i)) {\n const stepDirection = this.getStepDirection(i, newIndex);\n this.updateStep(i, newIndex, stepDirection);\n const validStep = this.isValidStep(i, newIndex, stepDirection);\n if (!validStep) {\n this.updateStep(i, newIndex, stepDirection, validStep);\n i = newIndex;\n }\n i = conditionIncrementOrDecrement(i);\n }\n this.updateFooterButtons();\n }\n }\n\n updateStep(currentIndex, newIndex, direction, isValidStep = true) {\n if (currentIndex === newIndex) {\n this.setShowStep(\n currentIndex,\n this.options.doneClass,\n this.options.activeClass,\n );\n } else if (isValidStep) {\n const checkDone = direction === 'forward' && this.options.doneClass;\n this.setShowStep(\n currentIndex,\n `${this.options.activeClass} ${this.options.errorClass} ${this.options.doneClass}`,\n checkDone,\n );\n } else {\n this.setShowStep(\n currentIndex,\n this.options.doneClass,\n `${this.options.activeClass} ${this.options.errorClass}`,\n );\n }\n }\n\n isValidStep(currentIndex, newIndex, direction) {\n return this.options.onChange(currentIndex, newIndex, direction);\n }\n\n updateFooterButtons() {\n const currentStepIndex = this.getStepIndex();\n const maxStepIndex = this.getMaxStepIndex();\n\n const $footer = this.el.find(this.selectors.footer);\n\n const $prevButton = $footer.filter('[data-step-action=\"prev\"]');\n const $nextButton = $footer.filter('[data-step-action=\"next\"]');\n const $finishButton = $footer.filter('[data-step-action=\"finish\"]');\n\n // hide prev button if current step is the first step\n if (currentStepIndex === 0) {\n $prevButton.hide();\n } else {\n $prevButton.show();\n }\n\n // hide forward button and show finish button if current step is the last step\n if (currentStepIndex === maxStepIndex) {\n $nextButton.hide();\n $finishButton.show();\n } else {\n $nextButton.show();\n $finishButton.hide();\n }\n\n // hide back button if showBackButton option is false\n if (!this.options.showBackButton) {\n $prevButton.hide();\n }\n }\n\n setAction(action) {\n const currentStepIndex = this.getStepIndex();\n let nextStep = currentStepIndex;\n if (action === 'prev') {\n nextStep -= 1;\n }\n if (action === 'next') {\n nextStep += 1;\n }\n if (action === 'finish') {\n const validStep = this.isValidStep(currentStepIndex, nextStep, 'forward');\n if (validStep) {\n this.hook('onFinish');\n } else {\n this.setShowStep(currentStepIndex, '', this.options.errorClass);\n }\n } else {\n this.setActiveStep(currentStepIndex, nextStep);\n }\n }\n\n setStepIndex(idx) {\n const maxIndex = this.getMaxStepIndex();\n if (idx <= maxIndex) {\n const currentStepIndex = this.getStepIndex();\n this.setActiveStep(currentStepIndex, idx);\n }\n }\n\n next() {\n const currentStepIndex = this.getStepIndex();\n const maxIndex = this.getMaxStepIndex();\n return maxIndex === currentStepIndex\n ? this.setAction('finish')\n : this.setAction('next');\n }\n\n prev() {\n const currentStepIndex = this.getStepIndex();\n return currentStepIndex !== 0 && this.setAction('prev');\n }\n\n finish() {\n this.hook('onFinish');\n }\n\n hideFooterButtons() {\n this.el.find(this.selectors.footer).hide();\n }\n\n static setDefaults(options) {\n $.extend(DEFAULTS, $.isPlainObject(options) && options);\n }\n}\n\nexport default Steps;\n","import $ from 'jquery';\nimport Steps from './Steps';\nimport { version } from '../package.json';\n\nconst previousStepsPlugin = $.fn.steps;\n\n$.fn.steps = function (options) {\n return this.each(function () {\n if (!$.data(this, 'plugin_Steps')) {\n $.data(this, 'plugin_Steps', new Steps(this, options));\n }\n });\n};\n\n$.fn.steps.version = version;\n$.fn.steps.setDefaults = Steps.setDefaults;\n\n// No conflict\n$.fn.steps.noConflict = function () {\n $.fn.steps = previousStepsPlugin;\n return this;\n};\n"],"names":["startAt","showBackButton","showFooterButtons","onInit","$","noop","onDestroy","onFinish","onChange","stepSelector","contentSelector","footerSelector","activeClass","doneClass","errorClass","Steps","element","options","extend","DEFAULTS","el","selectors","step","footer","content","init","e","preventDefault","self","data","all","find","next","currentTarget","nextStepIndex","index","currentStepIndex","getStepIndex","setActiveStep","statusAction","setAction","hook","initEventListeners","hideFooterButtons","updateFooterButtons","on","stepClick","btnClick","hookName","undefined","call","off","removeData","remove","split","join","stepIndex","filter","length","newIndex","direction","idx","removeClass","addClass","$targetStep","eq","$tabContent","currentIndex","conditionDirection","start","conditionIncrementOrDecrement","i","stepDirection","getStepDirection","updateStep","validStep","isValidStep","setShowStep","checkDone","maxStepIndex","getMaxStepIndex","$footer","$prevButton","$nextButton","$finishButton","hide","show","action","nextStep","maxIndex","isPlainObject","previousStepsPlugin","fn","steps","each","version","setDefaults","noConflict"],"mappings":"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"} -------------------------------------------------------------------------------- /dist/jquery-steps.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Steps v1.1.4 3 | * https://github.com/oguzhanoya/jquery-steps 4 | * 5 | * Copyright (c) 2022 oguzhanoya 6 | * Released under the MIT license 7 | */ 8 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(require("jquery")):"function"==typeof define&&define.amd?define(["jquery"],e):e(("undefined"!=typeof globalThis?globalThis:t||self).$)}(this,function(n){"use strict";function o(t,e){for(var s=0;s 2 | 3 | 4 | 5 | 6 | 7 | Api 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 20 |
21 |
22 | ... step1 23 |
24 |
25 | ... step2 26 |
27 |
28 | ... step3 29 |
30 |
31 | 36 |
37 | 38 |
39 | 40 | 41 |
42 | 43 | 44 |
45 | 46 | 47 | 48 |
49 | 50 | 51 | 52 | 53 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /examples/async.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Async 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 20 |
21 |
22 | ... step1 23 |
24 |
25 | ... step2 26 |
27 |
28 | ... step3 29 |
30 |
31 | 36 |
37 |
Loading...
38 | 39 | 40 | 41 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /examples/basic.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Basic 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 20 |
21 |
22 | ... step1 23 |
24 |
25 | ... step2 26 |
27 |
28 | ... step3 29 |
30 |
31 | 36 |
37 | 38 | 39 | 40 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /examples/callbacks.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Callbacks 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 22 |
23 |
24 |

Tab1

25 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minus facere porro iste quas numquam officia totam facilis suscipit, expedita rem quod, fugiat quo, veniam voluptate ut autem quia qui amet necessitatibus perferendis dignissimos ipsa doloremque. Necessitatibus delectus voluptatem unde. Architecto animi unde nostrum tenetur, doloremque distinctio, porro officiis dicta similique omnis quos odit ducimus minima ea quas facilis quod. Natus adipisci consequuntur sapiente alias culpa fugit tenetur, doloribus? Magni ipsum dolor debitis beatae quo, dicta voluptas veritatis, quos. Iusto quisquam doloribus laboriosam esse, dicta, odio facilis eligendi explicabo sequi accusamus a iste minus alias. Nisi sed laborum, aut maiores beatae aliquam voluptatum est enim impedit delectus blanditiis, neque sint nemo deleniti a quaerat voluptatem harum! Laboriosam assumenda, ullam iure. Corrupti maxime perferendis facilis ipsum, eius excepturi commodi consectetur, velit nobis reiciendis, ipsam! Maiores possimus tempore vel doloremque in facilis qui quos molestias. Culpa eius magnam repellat, ad eaque. Possimus, voluptatem.

26 |
27 |
28 |

Tab2

29 |
30 | First name:
31 | 32 |
Last name:
33 | 34 |
35 |
36 |
37 |

Tab3

38 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minus facere porro iste quas numquam officia totam facilis suscipit, expedita rem quod, fugiat quo, veniam voluptate ut autem quia qui amet necessitatibus perferendis dignissimos ipsa doloremque. Necessitatibus delectus voluptatem unde. Architecto animi unde nostrum tenetur, doloremque distinctio, porro officiis dicta similique omnis quos odit ducimus minima ea quas facilis quod. Natus adipisci consequuntur sapiente alias culpa fugit tenetur, doloribus? Magni ipsum dolor debitis beatae quo, dicta voluptas veritatis, quos. Iusto quisquam doloribus laboriosam esse, dicta, odio facilis eligendi explicabo sequi accusamus a iste minus alias. Nisi sed laborum, aut maiores beatae aliquam voluptatum est enim impedit delectus blanditiis, neque sint nemo deleniti a quaerat voluptatem harum! Laboriosam assumenda, ullam iure. Corrupti maxime perferendis facilis ipsum, eius excepturi commodi consectetur, velit nobis reiciendis, ipsam! Maiores possimus tempore vel doloremque in facilis qui quos molestias. Culpa eius magnam repellat, ad eaque. Possimus, voluptatem.

39 |
40 |
41 |

Tab4

42 |
43 | Email address:
44 | 45 |
Password:
46 | 47 |
48 |
49 |
50 |

Tab5

51 |
52 | Mobile No:
53 | 54 |
55 |
56 |
57 | 62 |
63 | 64 | 65 | 66 | 67 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /examples/css/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-size: 14px; 3 | font-family: Arial, Helvetica, sans-serif; 4 | padding: 100px; 5 | } 6 | button, input, select, textarea { 7 | font-family: inherit; 8 | font-size: inherit; 9 | line-height: inherit; 10 | } 11 | /* jquery validation */ 12 | label.error { 13 | color: #e7505a; 14 | margin-left: 10px; 15 | padding: 7px; 16 | } 17 | input.error { 18 | border: 2px solid #e7505a; 19 | } 20 | 21 | .loader, 22 | .loader:after { 23 | border-radius: 50%; 24 | width: 10em; 25 | height: 10em; 26 | } 27 | .loader { 28 | display: none; 29 | margin-top: 10px; 30 | overflow: hidden; 31 | font-size: 3px; 32 | text-indent: -9999em; 33 | border-top: 1.1em solid rgba(255, 255, 255, 0.2); 34 | border-right: 1.1em solid rgba(255, 255, 255, 0.2); 35 | border-bottom: 1.1em solid rgba(255, 255, 255, 0.2); 36 | border-left: 1.1em solid #31c5d2; 37 | -webkit-transform: translateZ(0); 38 | -ms-transform: translateZ(0); 39 | transform: translateZ(0); 40 | -webkit-animation: load8 1.1s infinite linear; 41 | animation: load8 1.1s infinite linear; 42 | } 43 | @-webkit-keyframes load8 { 44 | 0% { 45 | -webkit-transform: rotate(0deg); 46 | transform: rotate(0deg); 47 | } 48 | 100% { 49 | -webkit-transform: rotate(360deg); 50 | transform: rotate(360deg); 51 | } 52 | } 53 | @keyframes load8 { 54 | 0% { 55 | -webkit-transform: rotate(0deg); 56 | transform: rotate(0deg); 57 | } 58 | 100% { 59 | -webkit-transform: rotate(360deg); 60 | transform: rotate(360deg); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /examples/multiple.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Multiple 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 20 |
21 |
22 | ... step1 23 |
24 |
25 | ... step2 26 |
27 |
28 | ... step3 29 |
30 |
31 | 36 |
37 | 38 |
39 | 44 |
45 |
46 | ... step1 47 |
48 |
49 | ... step2 50 |
51 |
52 | ... step3 53 |
54 |
55 | 60 |
61 | 62 | 63 | 64 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery.steps", 3 | "version": "1.1.4", 4 | "description": "A simple, lightweight jQuery step wizard plugin.", 5 | "main": "./dist/jquery-steps.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/oguzhanoya/jquery-steps.git" 9 | }, 10 | "bugs": { 11 | "url": "https://github.com/oguzhanoya/jquery-steps/issues" 12 | }, 13 | "homepage": "https://oguzhanoya.github.io/jquery-steps", 14 | "scripts": { 15 | "build:css": "stylus src/styl/jquery-steps.styl -m -o dist/", 16 | "build:css-dev": "stylus -w src/styl/jquery-steps.styl -m -o dist/", 17 | "build:js": "rollup -c --bundleConfigAsCjs", 18 | "build:js-dev": "rollup -c -w --bundleConfigAsCjs", 19 | "build": "run-p build:js build:css", 20 | "dev": "run-p build:css-dev build:js-dev", 21 | "lint": "eslint --fix src", 22 | "format": "prettier . --write --list-different", 23 | "compress": "uglifyjs dist/jquery-steps.js -o dist/jquery-steps.min.js -c -m --comments /^!/", 24 | "prebuild": "npm run lint", 25 | "postbuild": "npm run compress", 26 | "clean": "rm -rf dist/*" 27 | }, 28 | "author": "oguzhanoya", 29 | "license": "MIT", 30 | "devDependencies": { 31 | "@babel/core": "^7.20.7", 32 | "@babel/preset-env": "^7.20.2", 33 | "@rollup/plugin-babel": "^6.0.3", 34 | "@rollup/plugin-json": "^6.0.0", 35 | "eslint": "^8.30.0", 36 | "eslint-config-airbnb-base": "^15.0.0", 37 | "eslint-config-prettier": "^8.5.0", 38 | "eslint-plugin-import": "^2.26.0", 39 | "eslint-plugin-prettier": "^4.2.1", 40 | "npm-run-all": "^4.1.5", 41 | "prettier": "^2.8.1", 42 | "rollup": "^3.9.0", 43 | "stylus": "^0.59.0", 44 | "uglify-js": "^3.17.4" 45 | }, 46 | "dependencies": { 47 | "jquery": "^3.6.3" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import { babel } from '@rollup/plugin-babel'; 2 | import json from '@rollup/plugin-json'; 3 | import pkg from './package.json'; 4 | 5 | const now = new Date(); 6 | 7 | export default { 8 | external: ['jquery'], 9 | input: 'src/Plugin.js', 10 | output: { 11 | file: 'dist/jquery-steps.js', 12 | format: 'umd', 13 | name: 'Steps', 14 | banner: `/*! 15 | * Steps v${pkg.version} 16 | * ${pkg.repository.url.replace('.git', '')} 17 | * 18 | * Copyright (c) ${now.getFullYear()} ${pkg.author} 19 | * Released under the ${pkg.license} license 20 | */ 21 | `, 22 | globals: { 23 | jquery: '$', 24 | }, 25 | sourcemap: true, 26 | }, 27 | plugins: [ 28 | babel({ 29 | exclude: 'node_modules/**', 30 | presets: ['@babel/preset-env'], 31 | babelrc: false, 32 | }), 33 | json({ 34 | exclude: 'node_modules/**', 35 | }), 36 | ], 37 | }; 38 | -------------------------------------------------------------------------------- /src/Defaults.js: -------------------------------------------------------------------------------- 1 | export default { 2 | startAt: 0, 3 | showBackButton: true, 4 | showFooterButtons: true, 5 | onInit: $.noop, 6 | onDestroy: $.noop, 7 | onFinish: $.noop, 8 | onChange() { 9 | return true; 10 | }, 11 | stepSelector: '.step-steps', 12 | contentSelector: '.step-content', 13 | footerSelector: '.step-footer', 14 | activeClass: 'active', 15 | doneClass: 'done', 16 | errorClass: 'error', 17 | }; 18 | -------------------------------------------------------------------------------- /src/Plugin.js: -------------------------------------------------------------------------------- 1 | import $ from 'jquery'; 2 | import Steps from './Steps'; 3 | import { version } from '../package.json'; 4 | 5 | const previousStepsPlugin = $.fn.steps; 6 | 7 | $.fn.steps = function (options) { 8 | return this.each(function () { 9 | if (!$.data(this, 'plugin_Steps')) { 10 | $.data(this, 'plugin_Steps', new Steps(this, options)); 11 | } 12 | }); 13 | }; 14 | 15 | $.fn.steps.version = version; 16 | $.fn.steps.setDefaults = Steps.setDefaults; 17 | 18 | // No conflict 19 | $.fn.steps.noConflict = function () { 20 | $.fn.steps = previousStepsPlugin; 21 | return this; 22 | }; 23 | -------------------------------------------------------------------------------- /src/Steps.js: -------------------------------------------------------------------------------- 1 | import $ from 'jquery'; 2 | import DEFAULTS from './Defaults'; 3 | 4 | class Steps { 5 | constructor(element, options) { 6 | // Extend defaults with the init options. 7 | this.options = $.extend({}, DEFAULTS, options); 8 | 9 | // Store main DOM element. 10 | this.el = $(element); 11 | 12 | this.selectors = { 13 | step: `${this.options.stepSelector} [data-step-target]`, 14 | footer: `${this.options.footerSelector} [data-step-action]`, 15 | content: `${this.options.contentSelector} [data-step]`, 16 | }; 17 | 18 | // Initialize 19 | this.init(); 20 | } 21 | 22 | stepClick(e) { 23 | e.preventDefault(); 24 | const { self } = e.data; 25 | const all = self.el.find(self.selectors.step); 26 | const next = e.currentTarget; 27 | const nextStepIndex = all.index(next); 28 | const currentStepIndex = e.data.self.getStepIndex(); 29 | e.data.self.setActiveStep(currentStepIndex, nextStepIndex); 30 | } 31 | 32 | btnClick(e) { 33 | e.preventDefault(); 34 | const statusAction = $(this).data('step-action'); 35 | e.data.self.setAction(statusAction); 36 | } 37 | 38 | init() { 39 | this.hook('onInit'); 40 | 41 | this.initEventListeners(); 42 | 43 | // set default step 44 | this.setActiveStep(0, this.options.startAt, true); 45 | 46 | // show footer buttons 47 | if (!this.options.showFooterButtons) { 48 | this.hideFooterButtons(); 49 | this.updateFooterButtons = $.noop; 50 | } 51 | } 52 | 53 | initEventListeners() { 54 | // step click event 55 | $(this.el) 56 | .find(this.selectors.step) 57 | .on('click', { self: this }, this.stepClick); 58 | 59 | // button click event 60 | $(this.el) 61 | .find(this.selectors.footer) 62 | .on('click', { self: this }, this.btnClick); 63 | } 64 | 65 | hook(hookName) { 66 | if (this.options[hookName] !== undefined) { 67 | this.options[hookName].call(this.el); 68 | } 69 | } 70 | 71 | destroy() { 72 | this.hook('onDestroy'); 73 | $(this.el).find(this.selectors.step).off('click'); 74 | $(this.el).find(this.selectors.footer).off('click'); 75 | this.el.removeData('plugin_Steps'); 76 | this.el.remove(); 77 | } 78 | 79 | getStepIndex() { 80 | const all = this.el.find(this.selectors.step); 81 | const activeClass = this.options.activeClass.split(' ').join('.'); 82 | const stepIndex = all.index(all.filter(`.${activeClass}`)); 83 | return stepIndex; 84 | } 85 | 86 | getMaxStepIndex() { 87 | return this.el.find(this.selectors.step).length - 1; 88 | } 89 | 90 | getStepDirection(stepIndex, newIndex) { 91 | let direction = 'none'; 92 | if (newIndex < stepIndex) { 93 | direction = 'backward'; 94 | } else if (newIndex > stepIndex) { 95 | direction = 'forward'; 96 | } 97 | return direction; 98 | } 99 | 100 | setShowStep(idx, removeClass, addClass = '') { 101 | const $targetStep = this.el.find(this.selectors.step).eq(idx); 102 | $targetStep.removeClass(removeClass).addClass(addClass); 103 | 104 | const $tabContent = this.el.find(this.selectors.content); 105 | $tabContent 106 | .removeClass(this.options.activeClass) 107 | .eq(idx) 108 | .addClass(this.options.activeClass); 109 | } 110 | 111 | setActiveStep(currentIndex, newIndex, init = false) { 112 | if (newIndex !== currentIndex || init) { 113 | const conditionDirection = 114 | newIndex > currentIndex 115 | ? (start) => start <= newIndex 116 | : (start) => start >= newIndex; 117 | 118 | // prettier-ignore 119 | const conditionIncrementOrDecrement = (newIndex > currentIndex) 120 | ? (start) => start + 1 121 | : (start) => start - 1; 122 | 123 | let i = currentIndex; 124 | while (conditionDirection(i)) { 125 | const stepDirection = this.getStepDirection(i, newIndex); 126 | this.updateStep(i, newIndex, stepDirection); 127 | const validStep = this.isValidStep(i, newIndex, stepDirection); 128 | if (!validStep) { 129 | this.updateStep(i, newIndex, stepDirection, validStep); 130 | i = newIndex; 131 | } 132 | i = conditionIncrementOrDecrement(i); 133 | } 134 | this.updateFooterButtons(); 135 | } 136 | } 137 | 138 | updateStep(currentIndex, newIndex, direction, isValidStep = true) { 139 | if (currentIndex === newIndex) { 140 | this.setShowStep( 141 | currentIndex, 142 | this.options.doneClass, 143 | this.options.activeClass, 144 | ); 145 | } else if (isValidStep) { 146 | const checkDone = direction === 'forward' && this.options.doneClass; 147 | this.setShowStep( 148 | currentIndex, 149 | `${this.options.activeClass} ${this.options.errorClass} ${this.options.doneClass}`, 150 | checkDone, 151 | ); 152 | } else { 153 | this.setShowStep( 154 | currentIndex, 155 | this.options.doneClass, 156 | `${this.options.activeClass} ${this.options.errorClass}`, 157 | ); 158 | } 159 | } 160 | 161 | isValidStep(currentIndex, newIndex, direction) { 162 | return this.options.onChange(currentIndex, newIndex, direction); 163 | } 164 | 165 | updateFooterButtons() { 166 | const currentStepIndex = this.getStepIndex(); 167 | const maxStepIndex = this.getMaxStepIndex(); 168 | 169 | const $footer = this.el.find(this.selectors.footer); 170 | 171 | const $prevButton = $footer.filter('[data-step-action="prev"]'); 172 | const $nextButton = $footer.filter('[data-step-action="next"]'); 173 | const $finishButton = $footer.filter('[data-step-action="finish"]'); 174 | 175 | // hide prev button if current step is the first step 176 | if (currentStepIndex === 0) { 177 | $prevButton.hide(); 178 | } else { 179 | $prevButton.show(); 180 | } 181 | 182 | // hide forward button and show finish button if current step is the last step 183 | if (currentStepIndex === maxStepIndex) { 184 | $nextButton.hide(); 185 | $finishButton.show(); 186 | } else { 187 | $nextButton.show(); 188 | $finishButton.hide(); 189 | } 190 | 191 | // hide back button if showBackButton option is false 192 | if (!this.options.showBackButton) { 193 | $prevButton.hide(); 194 | } 195 | } 196 | 197 | setAction(action) { 198 | const currentStepIndex = this.getStepIndex(); 199 | let nextStep = currentStepIndex; 200 | if (action === 'prev') { 201 | nextStep -= 1; 202 | } 203 | if (action === 'next') { 204 | nextStep += 1; 205 | } 206 | if (action === 'finish') { 207 | const validStep = this.isValidStep(currentStepIndex, nextStep, 'forward'); 208 | if (validStep) { 209 | this.hook('onFinish'); 210 | } else { 211 | this.setShowStep(currentStepIndex, '', this.options.errorClass); 212 | } 213 | } else { 214 | this.setActiveStep(currentStepIndex, nextStep); 215 | } 216 | } 217 | 218 | setStepIndex(idx) { 219 | const maxIndex = this.getMaxStepIndex(); 220 | if (idx <= maxIndex) { 221 | const currentStepIndex = this.getStepIndex(); 222 | this.setActiveStep(currentStepIndex, idx); 223 | } 224 | } 225 | 226 | next() { 227 | const currentStepIndex = this.getStepIndex(); 228 | const maxIndex = this.getMaxStepIndex(); 229 | return maxIndex === currentStepIndex 230 | ? this.setAction('finish') 231 | : this.setAction('next'); 232 | } 233 | 234 | prev() { 235 | const currentStepIndex = this.getStepIndex(); 236 | return currentStepIndex !== 0 && this.setAction('prev'); 237 | } 238 | 239 | finish() { 240 | this.hook('onFinish'); 241 | } 242 | 243 | hideFooterButtons() { 244 | this.el.find(this.selectors.footer).hide(); 245 | } 246 | 247 | static setDefaults(options) { 248 | $.extend(DEFAULTS, $.isPlainObject(options) && options); 249 | } 250 | } 251 | 252 | export default Steps; 253 | -------------------------------------------------------------------------------- /src/styl/jquery-steps.styl: -------------------------------------------------------------------------------- 1 | 2 | bg-done = #3cb371; 3 | bg-error = #e7505a; 4 | bg-active = #32c5d2; 5 | bg-gray = #e5e5e5; 6 | 7 | .step-app 8 | & > .step-steps 9 | margin 0 10 | padding 0 11 | display flex 12 | border-radius 3px 3px 0 0 13 | overflow hidden 14 | & > li 15 | list-style none 16 | flex 1 17 | &:hover 18 | background-color darken(bg-gray, 3) 19 | &:last-child a 20 | border none 21 | &.active 22 | background-color bg-active 23 | color #fff 24 | &.error 25 | background-color bg-error 26 | color #fff 27 | &.done 28 | background-color bg-done 29 | color #fff 30 | cursor pointer 31 | display block 32 | padding 10px 33 | color #333 34 | background-color bg-gray 35 | text-decoration none 36 | border-right 1px solid #fff 37 | & > .number 38 | background #fff 39 | padding 0 8px 40 | display inline-block 41 | text-align center 42 | margin-right 15px 43 | border-radius 3px 44 | color #333 45 | 46 | & > .step-content 47 | border 1px solid bg-gray 48 | padding 10px 49 | border-top 0 50 | & > .step-tab-panel 51 | display none 52 | &.active 53 | display block 54 | & > .step-footer 55 | margin-top 15px 56 | margin-bottom 15px 57 | & > .step-btn 58 | padding 4px 16px 59 | color #333 60 | text-decoration none 61 | background bg-gray 62 | border-radius 3px 63 | border none 64 | outline none 65 | cursor pointer 66 | -------------------------------------------------------------------------------- /test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Jasmine Spec Runner 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /test/spec.js: -------------------------------------------------------------------------------- 1 | describe('jquery steps', function () { 2 | var steps_api; 3 | beforeEach(function () { 4 | var data = { 5 | stepsCount: 3, 6 | }; 7 | var html = template('tpl-demo', data); 8 | document.body.insertAdjacentHTML('afterbegin', html); 9 | var steps = $('#demo').steps(); 10 | steps_api = steps.data('plugin_Steps'); 11 | }); 12 | 13 | afterEach(function () { 14 | steps_api.destroy(); 15 | }); 16 | 17 | it('version', function () { 18 | var ver = $.fn.steps.version; 19 | expect(ver).toEqual('1.1.4'); 20 | }); 21 | 22 | it('next', function () { 23 | steps_api.next(); 24 | steps_api.next(); 25 | var idx = steps_api.getStepIndex(); 26 | expect(idx).toEqual(2); 27 | }); 28 | 29 | it('prev', function () { 30 | steps_api.next(); 31 | steps_api.next(); 32 | steps_api.prev(); 33 | var idx = steps_api.getStepIndex(); 34 | expect(idx).toEqual(1); 35 | }); 36 | }); 37 | --------------------------------------------------------------------------------