|
1 |
| -(function (factory) { |
| 1 | +(function(factory) { |
2 | 2 | 'use strict';
|
3 | 3 | if (typeof define === 'function' && define.amd) {
|
4 | 4 | // AMD is used - Register as an anonymous module.
|
5 | 5 | define(['jquery', 'jquery-validation'], factory);
|
6 |
| - } else if (typeof exports === 'object') { |
| 6 | + } |
| 7 | + else if (typeof exports === 'object') { |
7 | 8 | factory(require('jquery'), require('jquery-validation'));
|
8 |
| - } else { |
| 9 | + } |
| 10 | + else { |
9 | 11 | // Neither AMD nor CommonJS used. Use global variables.
|
10 | 12 | if (typeof jQuery === 'undefined') {
|
11 | 13 | throw 'multi-step-form-js requires jQuery to be loaded first';
|
|
15 | 17 | }
|
16 | 18 | factory(jQuery);
|
17 | 19 | }
|
18 |
| -}(function ($) { |
| 20 | +}(function($) { |
19 | 21 | 'use strict';
|
20 | 22 |
|
21 | 23 | const msfCssClasses = {
|
|
48 | 50 | viewChanged: "msf:viewChanged"
|
49 | 51 | };
|
50 | 52 |
|
51 |
| - $.fn.multiStepForm = function (options) { |
| 53 | + $.fn.multiStepForm = function(options) { |
52 | 54 | var form = this;
|
53 | 55 |
|
54 | 56 | var defaults = {
|
|
80 | 82 | form.steps = [];
|
81 | 83 | //form.completedSteps = 0;
|
82 | 84 |
|
83 |
| - form.getActiveView = function () { |
84 |
| - return form.views.filter(function () { return this.style && this.style.display !== '' && this.style.display !== 'none' }); |
| 85 | + form.getActiveView = function() { |
| 86 | + return form.views.filter(function() { |
| 87 | + return this.style && this.style.display !== '' && this.style.display !== 'none' |
| 88 | + }); |
85 | 89 | };
|
86 | 90 |
|
87 |
| - form.setActiveView = function (index) { |
| 91 | + form.setActiveView = function(index) { |
88 | 92 | var previousView = form.getActiveView()[0];
|
89 | 93 | var previousIndex = form.views.index(previousView);
|
90 | 94 |
|
|
97 | 101 | view.find(':input').first().focus();
|
98 | 102 |
|
99 | 103 | var completedSteps = 0;
|
100 |
| - $.each(form.views, function (index, view) { |
| 104 | + $.each(form.views, function(index, view) { |
101 | 105 | if ($.data(view, msfJqueryData.validated)) {
|
102 | 106 | completedSteps++;
|
103 | 107 | }
|
|
112 | 116 | });
|
113 | 117 | }
|
114 | 118 |
|
115 |
| - form.setStatusCssClass = function (step, cssClass) { |
| 119 | + form.setStatusCssClass = function(step, cssClass) { |
116 | 120 | $(step).removeClass(msfCssClasses.statuses.stepComplete);
|
117 | 121 | $(step).removeClass(msfCssClasses.statuses.stepIncomplete);
|
118 | 122 |
|
119 | 123 | $(step).addClass(cssClass);
|
120 | 124 | }
|
121 | 125 |
|
122 |
| - form.tryNavigateToView= function(currentIndex, targetIndex) { |
| 126 | + form.tryNavigateToView = function(currentIndex, targetIndex) { |
123 | 127 | if (targetIndex <= currentIndex) {
|
124 | 128 | form.views[currentIndex]
|
125 | 129 | form.validateView(form.views[currentIndex]);
|
126 | 130 | form.setActiveView(targetIndex);
|
127 | 131 | return;
|
128 | 132 | }
|
129 | 133 |
|
130 |
| - if (!form.validateViews(currentIndex, targetIndex - currentIndex, function (i) { |
131 |
| - if (!settings.allowUnvalidatedStep) { |
132 |
| - form.setActiveView(i); |
133 |
| - return false; |
134 |
| - } |
| 134 | + if (!form.validateViews(currentIndex, targetIndex - currentIndex, function(i) { |
| 135 | + if (!settings.allowUnvalidatedStep) { |
| 136 | + form.setActiveView(i); |
| 137 | + return false; |
| 138 | + } |
135 | 139 |
|
136 |
| - return true; |
137 |
| - })) { |
| 140 | + return true; |
| 141 | + })) { |
138 | 142 | if (!settings.allowUnvalidatedStep) {
|
139 | 143 | return;
|
140 | 144 | }
|
141 | 145 | }
|
142 | 146 | form.setActiveView(targetIndex);
|
143 | 147 | }
|
144 | 148 |
|
145 |
| - form.init = function () { |
| 149 | + form.init = function() { |
146 | 150 |
|
147 |
| - this.initHeader = function () { |
| 151 | + this.initHeader = function() { |
148 | 152 | if (form.header.length === 0) {
|
149 | 153 | form.header = $("<div/>", {
|
150 | 154 | "class": msfCssClasses.header,
|
|
156 | 160 |
|
157 | 161 | form.steps = $(form.header).find("." + msfCssClasses.step);
|
158 | 162 |
|
159 |
| - this.initStep = function (index, view) { |
| 163 | + this.initStep = function(index, view) { |
160 | 164 |
|
161 | 165 | //append steps to header if they do not exist
|
162 | 166 | if (form.steps.length < index + 1) {
|
|
168 | 172 |
|
169 | 173 | if (settings.allowClickNavigation) {
|
170 | 174 | //bind the click event to the header step
|
171 |
| - $(form.steps[index]).click(function (e) { |
| 175 | + $(form.steps[index]).click(function(e) { |
172 | 176 | var view = form.getActiveView()[0];
|
173 | 177 | var currentIndex = form.views.index(view);
|
174 | 178 | var targetIndex = form.steps.index($(e.target).closest("." + msfCssClasses.step)[0]);
|
175 | 179 |
|
176 |
| - form.tryNavigateToView(currentIndex,targetIndex); |
| 180 | + form.tryNavigateToView(currentIndex, targetIndex); |
177 | 181 | });
|
178 | 182 | }
|
179 |
| - |
180 | 183 | }
|
181 | 184 |
|
182 | 185 | $.each(form.views, this.initStep);
|
|
185 | 188 | };
|
186 | 189 |
|
187 | 190 |
|
188 |
| - this.initNavigation = function () { |
| 191 | + this.initNavigation = function() { |
189 | 192 |
|
190 | 193 | if (form.navigation.length === 0) {
|
191 | 194 | form.navigation = $("<div/>", {
|
|
195 | 198 | $(form.content).after(form.navigation);
|
196 | 199 | }
|
197 | 200 |
|
198 |
| - this.initNavButton = function (type) { |
199 |
| - var element = this.navigation.find("button[data-type='" + type + "'], input[type='button']"), type; |
| 201 | + this.initNavButton = function(type) { |
| 202 | + var element = this.navigation.find("button[data-type='" + type + "'], input[type='button']"), |
| 203 | + type; |
200 | 204 | if (element.length === 0) {
|
201 | 205 | element = $("<button/>", {
|
202 | 206 | "class": msfCssClasses.navButton,
|
|
205 | 209 | });
|
206 | 210 | element.appendTo(form.navigation);
|
207 | 211 | }
|
208 |
| - |
209 | 212 | return element;
|
210 | 213 | };
|
211 | 214 |
|
|
214 | 217 | form.submitNavButton = this.initNavButton(msfNavTypes.submit);
|
215 | 218 | };
|
216 | 219 |
|
217 |
| - |
218 | 220 | this.initHeader();
|
219 | 221 | this.initNavigation();
|
220 | 222 |
|
221 |
| - this.views.each(function (index, view) { |
| 223 | + this.views.each(function(index, view) { |
222 | 224 |
|
223 | 225 | $.data(view, msfJqueryData.validated, false);
|
224 | 226 | $.data(view, msfJqueryData.visited, false);
|
225 | 227 |
|
226 | 228 | //if this is not the last view do not allow the enter key to submit the form as it is not completed yet
|
227 |
| - if (index != form.views.length - 1) { |
228 |
| - $(view).find(':input').not('textarea').keypress(function (e) { |
229 |
| - if (e.which == 13) // Enter key = keycode 13 |
| 229 | + if (index !== form.views.length - 1) { |
| 230 | + $(view).find(':input').not('textarea').keypress(function(e) { |
| 231 | + if (e.which === 13) // Enter key = keycode 13 |
230 | 232 | {
|
231 | 233 | form.nextNavButton.click();
|
232 | 234 | return false;
|
233 | 235 | }
|
234 | 236 | });
|
235 | 237 | }
|
236 | 238 |
|
237 |
| - $(view).on('show', function (e) { |
| 239 | + $(view).on('show', function(e) { |
238 | 240 | if (this !== e.target)
|
239 | 241 | return;
|
240 | 242 |
|
241 |
| - var view = e.target |
| 243 | + var view = e.target; |
242 | 244 | $.data(view, msfJqueryData.visited, true);
|
243 | 245 |
|
244 | 246 | var index = form.views.index(view);
|
|
262 | 264 | }
|
263 | 265 | });
|
264 | 266 |
|
265 |
| - $(view).on('hide', function (e) { |
| 267 | + $(view).on('hide', function(e) { |
266 | 268 | if (this !== e.target)
|
267 | 269 | return;
|
268 | 270 |
|
|
292 | 294 | });
|
293 | 295 |
|
294 | 296 |
|
295 |
| - if(settings.activeIndex > 0) { |
296 |
| - $(form).ready(function(){ |
| 297 | + if (settings.activeIndex > 0) { |
| 298 | + $(form).ready(function() { |
297 | 299 | form.tryNavigateToView(0, settings.activeIndex);
|
298 | 300 | });
|
299 |
| - |
300 | 301 | }
|
301 | 302 | else {
|
302 | 303 | form.setActiveView(0);
|
303 | 304 | }
|
304 | 305 |
|
305 | 306 | };
|
306 | 307 |
|
307 |
| - form.validateView = function (view) { |
| 308 | + form.validateView = function(view) { |
308 | 309 | var index = form.views.index(view);
|
| 310 | + |
309 | 311 | if (form.validate().subset(view)) {
|
310 | 312 | $.data(view, msfJqueryData.validated, true);
|
311 | 313 | form.setStatusCssClass(form.steps[index], msfCssClasses.statuses.stepComplete);
|
|
318 | 320 | }
|
319 | 321 | };
|
320 | 322 |
|
321 |
| - form.validateViews = function (i, length, invalid) { |
| 323 | + form.validateViews = function(i, length, invalid) { |
322 | 324 | i = typeof i === 'undefined' ? 0 : i;
|
323 | 325 | length = typeof length === 'undefined' ? form.views.length : length;
|
324 |
| - |
325 | 326 |
|
326 |
| - var validationIgnore = ""; |
| 327 | + |
| 328 | + var validationIgnore = ""; // Saving the existing validator ignore settings to reset them after validating multi-step form |
327 | 329 | var isValid = true;
|
328 | 330 |
|
329 | 331 | //remember original validation setings for ignores
|
330 | 332 | if ($(form).data("validator")) {
|
331 |
| - validationIgnore = $(form).data("validator").settings.ignore |
332 |
| - $(form).data("validator").settings.ignore = ""; |
| 333 | + var formValidatorSettings = $(form).data("validator").settings; |
| 334 | + validationIgnore = formValidatorSettings.ignore; |
| 335 | + |
| 336 | + var currentValidationIgnoreSettingsArray = validationIgnore.split(","); |
| 337 | + if (currentValidationIgnoreSettingsArray.length >= 1) { |
| 338 | + // Remove the ":hidden" selector from validator ignore settings as we want our hidden fieldsets/steps to be validated before final submit |
| 339 | + var hiddenIndex = $.inArray(":hidden", currentValidationIgnoreSettingsArray); |
| 340 | + currentValidationIgnoreSettingsArray.splice(hiddenIndex, 1); |
| 341 | + $(form).data("validator").settings.ignore = currentValidationIgnoreSettingsArray.toString(); |
| 342 | + } |
333 | 343 | }
|
334 | 344 |
|
335 | 345 | for (i; i < length; i++) {
|
336 | 346 | if (!form.validateView(form.views[i])) {
|
337 | 347 | isValid = false;
|
338 | 348 |
|
339 |
| - if(!invalid(i)) { |
| 349 | + if (!invalid(i)) { |
340 | 350 | break;
|
341 | 351 | }
|
342 | 352 | }
|
|
351 | 361 |
|
352 | 362 | form.init();
|
353 | 363 |
|
354 |
| - form.nextNavButton.click(function () { |
| 364 | + form.nextNavButton.click(function() { |
355 | 365 | var view = form.getActiveView()[0];
|
356 | 366 | var index = form.views.index(view);
|
357 | 367 |
|
|
363 | 373 | }
|
364 | 374 | });
|
365 | 375 |
|
366 |
| - form.backNavButton.click(function () { |
| 376 | + form.backNavButton.click(function() { |
367 | 377 | var view = form.getActiveView()[0];
|
368 | 378 | var index = form.views.index(view);
|
369 | 379 |
|
|
372 | 382 | form.setActiveView(index - 1);
|
373 | 383 | });
|
374 | 384 |
|
375 |
| - form.submit(function (e) { |
| 385 | + form.submit(function(e) { |
376 | 386 | var validationIgnore = "";
|
377 | 387 |
|
378 |
| - form.validateViews(0, form.views.length, function () { |
| 388 | + form.validateViews(0, form.views.length, function() { |
379 | 389 | e.preventDefault();
|
380 | 390 | return true;
|
381 | 391 | });
|
382 | 392 | });
|
383 |
| - |
384 | 393 | return form;
|
385 | 394 | };
|
386 | 395 |
|
387 |
| - $.validator.prototype.subset = function (container) { |
| 396 | + $.validator.prototype.subset = function(container) { |
388 | 397 | var ok = true;
|
389 | 398 | var self = this;
|
390 |
| - $(container).find(':input').each(function () { |
| 399 | + $(container).find(':input').each(function() { |
391 | 400 | if (!self.element($(this))) ok = false;
|
392 | 401 | });
|
393 | 402 | return ok;
|
394 | 403 | };
|
395 | 404 |
|
396 |
| - $.each(['show', 'hide'], function (i, ev) { |
| 405 | + $.each(['show', 'hide'], function(i, ev) { |
397 | 406 | var el = $.fn[ev];
|
398 |
| - $.fn[ev] = function () { |
| 407 | + $.fn[ev] = function() { |
399 | 408 | this.trigger(ev);
|
400 | 409 | return el.apply(this, arguments);
|
401 | 410 | };
|
|
0 commit comments