rails-jquery-steps 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e9d1e011b461dd8d0c9b2796e35e7dc8c4a2ae88
4
+ data.tar.gz: 4b4b7b32c9044c3c23113b93c514b0274c0ac515
5
+ SHA512:
6
+ metadata.gz: 454464ad48d4c47021765a5d62d31062c1d513cdfbcb91e4da4ce4a0b18617e8b92d24829415e124534154c29609c2ef170a8dfc829b71996aaf05595288d44d
7
+ data.tar.gz: c25d303f6edad6c97e0a813a8b04d94d4b41534329c74e4d1c810b8f6a648438af515d541a1c2dfd40e4de98579ffad36d6bfb6aa765f23d9ba7138201dec325
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Buford Taylor
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,25 @@
1
+ # rails-jquery-steps
2
+
3
+ rails-jquery-steps inserts the [jQuery-Steps](https://github.com/rstaib/jquery-steps) plugin in the rails asset pipeline.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'rails-jquery-steps'
10
+
11
+ ## Usage
12
+
13
+ js
14
+
15
+ //= require jquery.steps
16
+
17
+
18
+ css
19
+
20
+ *= require jquery.steps
21
+
22
+ ## Versioning
23
+
24
+ rails-jquery-steps 1.0.0 == jQuery-Steps 1.1.0
25
+
@@ -0,0 +1,8 @@
1
+ require 'rails-jquery-steps/version'
2
+
3
+ module RailsJquerySteps
4
+ module Rails
5
+ class Engine < ::Rails::Engine
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ module RailsJquerySteps
2
+ module Rails
3
+ VERSION = '1.0.0'
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ require 'rails-jquery-tags-input/version'
2
+
3
+ module RailsJqueryTagsInput
4
+ module Rails
5
+ class Engine < ::Rails::Engine
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,2042 @@
1
+ /*!
2
+ * jQuery Steps v1.1.0 - 09/04/2014
3
+ * Copyright (c) 2014 Rafael Staib (http://www.jquery-steps.com)
4
+ * Licensed under MIT http://www.opensource.org/licenses/MIT
5
+ */
6
+ ;(function ($, undefined)
7
+ {
8
+ $.fn.extend({
9
+ _aria: function (name, value)
10
+ {
11
+ return this.attr("aria-" + name, value);
12
+ },
13
+
14
+ _removeAria: function (name)
15
+ {
16
+ return this.removeAttr("aria-" + name);
17
+ },
18
+
19
+ _enableAria: function (enable)
20
+ {
21
+ return (enable == null || enable) ?
22
+ this.removeClass("disabled")._aria("disabled", "false") :
23
+ this.addClass("disabled")._aria("disabled", "true");
24
+ },
25
+
26
+ _showAria: function (show)
27
+ {
28
+ return (show == null || show) ?
29
+ this.show()._aria("hidden", "false") :
30
+ this.hide()._aria("hidden", "true");
31
+ },
32
+
33
+ _selectAria: function (select)
34
+ {
35
+ return (select == null || select) ?
36
+ this.addClass("current")._aria("selected", "true") :
37
+ this.removeClass("current")._aria("selected", "false");
38
+ },
39
+
40
+ _id: function (id)
41
+ {
42
+ return (id) ? this.attr("id", id) : this.attr("id");
43
+ }
44
+ });
45
+
46
+ if (!String.prototype.format)
47
+ {
48
+ String.prototype.format = function()
49
+ {
50
+ var args = (arguments.length === 1 && $.isArray(arguments[0])) ? arguments[0] : arguments;
51
+ var formattedString = this;
52
+ for (var i = 0; i < args.length; i++)
53
+ {
54
+ var pattern = new RegExp("\\{" + i + "\\}", "gm");
55
+ formattedString = formattedString.replace(pattern, args[i]);
56
+ }
57
+ return formattedString;
58
+ };
59
+ }
60
+
61
+ /**
62
+ * A global unique id count.
63
+ *
64
+ * @static
65
+ * @private
66
+ * @property _uniqueId
67
+ * @type Integer
68
+ **/
69
+ var _uniqueId = 0;
70
+
71
+ /**
72
+ * The plugin prefix for cookies.
73
+ *
74
+ * @final
75
+ * @private
76
+ * @property _cookiePrefix
77
+ * @type String
78
+ **/
79
+ var _cookiePrefix = "jQu3ry_5teps_St@te_";
80
+
81
+ /**
82
+ * Suffix for the unique tab id.
83
+ *
84
+ * @final
85
+ * @private
86
+ * @property _tabSuffix
87
+ * @type String
88
+ * @since 0.9.7
89
+ **/
90
+ var _tabSuffix = "-t-";
91
+
92
+ /**
93
+ * Suffix for the unique tabpanel id.
94
+ *
95
+ * @final
96
+ * @private
97
+ * @property _tabpanelSuffix
98
+ * @type String
99
+ * @since 0.9.7
100
+ **/
101
+ var _tabpanelSuffix = "-p-";
102
+
103
+ /**
104
+ * Suffix for the unique title id.
105
+ *
106
+ * @final
107
+ * @private
108
+ * @property _titleSuffix
109
+ * @type String
110
+ * @since 0.9.7
111
+ **/
112
+ var _titleSuffix = "-h-";
113
+
114
+ /**
115
+ * An error message for an "index out of range" error.
116
+ *
117
+ * @final
118
+ * @private
119
+ * @property _indexOutOfRangeErrorMessage
120
+ * @type String
121
+ **/
122
+ var _indexOutOfRangeErrorMessage = "Index out of range.";
123
+
124
+ /**
125
+ * An error message for an "missing corresponding element" error.
126
+ *
127
+ * @final
128
+ * @private
129
+ * @property _missingCorrespondingElementErrorMessage
130
+ * @type String
131
+ **/
132
+ var _missingCorrespondingElementErrorMessage = "One or more corresponding step {0} are missing.";
133
+
134
+ /**
135
+ * Adds a step to the cache.
136
+ *
137
+ * @static
138
+ * @private
139
+ * @method addStepToCache
140
+ * @param wizard {Object} A jQuery wizard object
141
+ * @param step {Object} The step object to add
142
+ **/
143
+ function addStepToCache(wizard, step)
144
+ {
145
+ getSteps(wizard).push(step);
146
+ }
147
+
148
+ function analyzeData(wizard, options, state)
149
+ {
150
+ var stepTitles = wizard.children(options.headerTag),
151
+ stepContents = wizard.children(options.bodyTag);
152
+
153
+ // Validate content
154
+ if (stepTitles.length > stepContents.length)
155
+ {
156
+ throwError(_missingCorrespondingElementErrorMessage, "contents");
157
+ }
158
+ else if (stepTitles.length < stepContents.length)
159
+ {
160
+ throwError(_missingCorrespondingElementErrorMessage, "titles");
161
+ }
162
+
163
+ var startIndex = options.startIndex;
164
+
165
+ state.stepCount = stepTitles.length;
166
+
167
+ // Tries to load the saved state (step position)
168
+ if (options.saveState && $.cookie)
169
+ {
170
+ var savedState = $.cookie(_cookiePrefix + getUniqueId(wizard));
171
+ // Sets the saved position to the start index if not undefined or out of range
172
+ var savedIndex = parseInt(savedState, 0);
173
+ if (!isNaN(savedIndex) && savedIndex < state.stepCount)
174
+ {
175
+ startIndex = savedIndex;
176
+ }
177
+ }
178
+
179
+ state.currentIndex = startIndex;
180
+
181
+ stepTitles.each(function (index)
182
+ {
183
+ var item = $(this), // item == header
184
+ content = stepContents.eq(index),
185
+ modeData = content.data("mode"),
186
+ mode = (modeData == null) ? contentMode.html : getValidEnumValue(contentMode,
187
+ (/^\s*$/.test(modeData) || isNaN(modeData)) ? modeData : parseInt(modeData, 0)),
188
+ contentUrl = (mode === contentMode.html || content.data("url") === undefined) ?
189
+ "" : content.data("url"),
190
+ contentLoaded = (mode !== contentMode.html && content.data("loaded") === "1"),
191
+ step = $.extend({}, stepModel, {
192
+ title: item.html(),
193
+ content: (mode === contentMode.html) ? content.html() : "",
194
+ contentUrl: contentUrl,
195
+ contentMode: mode,
196
+ contentLoaded: contentLoaded
197
+ });
198
+
199
+ addStepToCache(wizard, step);
200
+ });
201
+ }
202
+
203
+ /**
204
+ * Triggers the onCanceled event.
205
+ *
206
+ * @static
207
+ * @private
208
+ * @method cancel
209
+ * @param wizard {Object} The jQuery wizard object
210
+ **/
211
+ function cancel(wizard)
212
+ {
213
+ wizard.triggerHandler("canceled");
214
+ }
215
+
216
+ function decreaseCurrentIndexBy(state, decreaseBy)
217
+ {
218
+ return state.currentIndex - decreaseBy;
219
+ }
220
+
221
+ /**
222
+ * Removes the control functionality completely and transforms the current state to the initial HTML structure.
223
+ *
224
+ * @static
225
+ * @private
226
+ * @method destroy
227
+ * @param wizard {Object} A jQuery wizard object
228
+ **/
229
+ function destroy(wizard, options)
230
+ {
231
+ var eventNamespace = getEventNamespace(wizard);
232
+
233
+ // Remove virtual data objects from the wizard
234
+ wizard.unbind(eventNamespace).removeData("uid").removeData("options")
235
+ .removeData("state").removeData("steps").removeData("eventNamespace")
236
+ .find(".actions a").unbind(eventNamespace);
237
+
238
+ // Remove attributes and CSS classes from the wizard
239
+ wizard.removeClass(options.clearFixCssClass + " vertical");
240
+
241
+ var contents = wizard.find(".content > *");
242
+
243
+ // Remove virtual data objects from panels and their titles
244
+ contents.removeData("loaded").removeData("mode").removeData("url");
245
+
246
+ // Remove attributes, CSS classes and reset inline styles on all panels and their titles
247
+ contents.removeAttr("id").removeAttr("role").removeAttr("tabindex")
248
+ .removeAttr("class").removeAttr("style")._removeAria("labelledby")
249
+ ._removeAria("hidden");
250
+
251
+ // Empty panels if the mode is set to 'async' or 'iframe'
252
+ wizard.find(".content > [data-mode='async'],.content > [data-mode='iframe']").empty();
253
+
254
+ var wizardSubstitute = $("<{0} class=\"{1}\"></{0}>".format(wizard.get(0).tagName, wizard.attr("class")));
255
+
256
+ var wizardId = wizard._id();
257
+ if (wizardId != null && wizardId !== "")
258
+ {
259
+ wizardSubstitute._id(wizardId);
260
+ }
261
+
262
+ wizardSubstitute.html(wizard.find(".content").html());
263
+ wizard.after(wizardSubstitute);
264
+ wizard.remove();
265
+
266
+ return wizardSubstitute;
267
+ }
268
+
269
+ /**
270
+ * Triggers the onFinishing and onFinished event.
271
+ *
272
+ * @static
273
+ * @private
274
+ * @method finishStep
275
+ * @param wizard {Object} The jQuery wizard object
276
+ * @param state {Object} The state container of the current wizard
277
+ **/
278
+ function finishStep(wizard, state)
279
+ {
280
+ var currentStep = wizard.find(".steps li").eq(state.currentIndex);
281
+
282
+ if (wizard.triggerHandler("finishing", [state.currentIndex]))
283
+ {
284
+ currentStep.addClass("done").removeClass("error");
285
+ wizard.triggerHandler("finished", [state.currentIndex]);
286
+ }
287
+ else
288
+ {
289
+ currentStep.addClass("error");
290
+ }
291
+ }
292
+
293
+ /**
294
+ * Gets or creates if not exist an unique event namespace for the given wizard instance.
295
+ *
296
+ * @static
297
+ * @private
298
+ * @method getEventNamespace
299
+ * @param wizard {Object} A jQuery wizard object
300
+ * @return {String} Returns the unique event namespace for the given wizard
301
+ */
302
+ function getEventNamespace(wizard)
303
+ {
304
+ var eventNamespace = wizard.data("eventNamespace");
305
+
306
+ if (eventNamespace == null)
307
+ {
308
+ eventNamespace = "." + getUniqueId(wizard);
309
+ wizard.data("eventNamespace", eventNamespace);
310
+ }
311
+
312
+ return eventNamespace;
313
+ }
314
+
315
+ function getStepAnchor(wizard, index)
316
+ {
317
+ var uniqueId = getUniqueId(wizard);
318
+
319
+ return wizard.find("#" + uniqueId + _tabSuffix + index);
320
+ }
321
+
322
+ function getStepPanel(wizard, index)
323
+ {
324
+ var uniqueId = getUniqueId(wizard);
325
+
326
+ return wizard.find("#" + uniqueId + _tabpanelSuffix + index);
327
+ }
328
+
329
+ function getStepTitle(wizard, index)
330
+ {
331
+ var uniqueId = getUniqueId(wizard);
332
+
333
+ return wizard.find("#" + uniqueId + _titleSuffix + index);
334
+ }
335
+
336
+ function getOptions(wizard)
337
+ {
338
+ return wizard.data("options");
339
+ }
340
+
341
+ function getState(wizard)
342
+ {
343
+ return wizard.data("state");
344
+ }
345
+
346
+ function getSteps(wizard)
347
+ {
348
+ return wizard.data("steps");
349
+ }
350
+
351
+ /**
352
+ * Gets a specific step object by index.
353
+ *
354
+ * @static
355
+ * @private
356
+ * @method getStep
357
+ * @param index {Integer} An integer that belongs to the position of a step
358
+ * @return {Object} A specific step object
359
+ **/
360
+ function getStep(wizard, index)
361
+ {
362
+ var steps = getSteps(wizard);
363
+
364
+ if (index < 0 || index >= steps.length)
365
+ {
366
+ throwError(_indexOutOfRangeErrorMessage);
367
+ }
368
+
369
+ return steps[index];
370
+ }
371
+
372
+ /**
373
+ * Gets or creates if not exist an unique id from the given wizard instance.
374
+ *
375
+ * @static
376
+ * @private
377
+ * @method getUniqueId
378
+ * @param wizard {Object} A jQuery wizard object
379
+ * @return {String} Returns the unique id for the given wizard
380
+ */
381
+ function getUniqueId(wizard)
382
+ {
383
+ var uniqueId = wizard.data("uid");
384
+
385
+ if (uniqueId == null)
386
+ {
387
+ uniqueId = wizard._id();
388
+ if (uniqueId == null)
389
+ {
390
+ uniqueId = "steps-uid-".concat(_uniqueId);
391
+ wizard._id(uniqueId);
392
+ }
393
+
394
+ _uniqueId++;
395
+ wizard.data("uid", uniqueId);
396
+ }
397
+
398
+ return uniqueId;
399
+ }
400
+
401
+ /**
402
+ * Gets a valid enum value by checking a specific enum key or value.
403
+ *
404
+ * @static
405
+ * @private
406
+ * @method getValidEnumValue
407
+ * @param enumType {Object} Type of enum
408
+ * @param keyOrValue {Object} Key as `String` or value as `Integer` to check for
409
+ */
410
+ function getValidEnumValue(enumType, keyOrValue)
411
+ {
412
+ validateArgument("enumType", enumType);
413
+ validateArgument("keyOrValue", keyOrValue);
414
+
415
+ // Is key
416
+ if (typeof keyOrValue === "string")
417
+ {
418
+ var value = enumType[keyOrValue];
419
+ if (value === undefined)
420
+ {
421
+ throwError("The enum key '{0}' does not exist.", keyOrValue);
422
+ }
423
+
424
+ return value;
425
+ }
426
+ // Is value
427
+ else if (typeof keyOrValue === "number")
428
+ {
429
+ for (var key in enumType)
430
+ {
431
+ if (enumType[key] === keyOrValue)
432
+ {
433
+ return keyOrValue;
434
+ }
435
+ }
436
+
437
+ throwError("Invalid enum value '{0}'.", keyOrValue);
438
+ }
439
+ // Type is not supported
440
+ else
441
+ {
442
+ throwError("Invalid key or value type.");
443
+ }
444
+ }
445
+
446
+ /**
447
+ * Routes to the next step.
448
+ *
449
+ * @static
450
+ * @private
451
+ * @method goToNextStep
452
+ * @param wizard {Object} The jQuery wizard object
453
+ * @param options {Object} Settings of the current wizard
454
+ * @param state {Object} The state container of the current wizard
455
+ * @return {Boolean} Indicates whether the action executed
456
+ **/
457
+ function goToNextStep(wizard, options, state)
458
+ {
459
+ return paginationClick(wizard, options, state, increaseCurrentIndexBy(state, 1));
460
+ }
461
+
462
+ /**
463
+ * Routes to the previous step.
464
+ *
465
+ * @static
466
+ * @private
467
+ * @method goToPreviousStep
468
+ * @param wizard {Object} The jQuery wizard object
469
+ * @param options {Object} Settings of the current wizard
470
+ * @param state {Object} The state container of the current wizard
471
+ * @return {Boolean} Indicates whether the action executed
472
+ **/
473
+ function goToPreviousStep(wizard, options, state)
474
+ {
475
+ return paginationClick(wizard, options, state, decreaseCurrentIndexBy(state, 1));
476
+ }
477
+
478
+ /**
479
+ * Routes to a specific step by a given index.
480
+ *
481
+ * @static
482
+ * @private
483
+ * @method goToStep
484
+ * @param wizard {Object} The jQuery wizard object
485
+ * @param options {Object} Settings of the current wizard
486
+ * @param state {Object} The state container of the current wizard
487
+ * @param index {Integer} The position (zero-based) to route to
488
+ * @return {Boolean} Indicates whether the action succeeded or failed
489
+ **/
490
+ function goToStep(wizard, options, state, index)
491
+ {
492
+ if (index < 0 || index >= state.stepCount)
493
+ {
494
+ throwError(_indexOutOfRangeErrorMessage);
495
+ }
496
+
497
+ if (options.forceMoveForward && index < state.currentIndex)
498
+ {
499
+ return;
500
+ }
501
+
502
+ var oldIndex = state.currentIndex;
503
+ if (wizard.triggerHandler("stepChanging", [state.currentIndex, index]))
504
+ {
505
+ // Save new state
506
+ state.currentIndex = index;
507
+ saveCurrentStateToCookie(wizard, options, state);
508
+
509
+ // Change visualisation
510
+ refreshStepNavigation(wizard, options, state, oldIndex);
511
+ refreshPagination(wizard, options, state);
512
+ loadAsyncContent(wizard, options, state);
513
+ startTransitionEffect(wizard, options, state, index, oldIndex, function()
514
+ {
515
+ wizard.triggerHandler("stepChanged", [index, oldIndex]);
516
+ });
517
+ }
518
+ else
519
+ {
520
+ wizard.find(".steps li").eq(oldIndex).addClass("error");
521
+ }
522
+
523
+ return true;
524
+ }
525
+
526
+ function increaseCurrentIndexBy(state, increaseBy)
527
+ {
528
+ return state.currentIndex + increaseBy;
529
+ }
530
+
531
+ /**
532
+ * Initializes the component.
533
+ *
534
+ * @static
535
+ * @private
536
+ * @method initialize
537
+ * @param options {Object} The component settings
538
+ **/
539
+ function initialize(options)
540
+ {
541
+ /*jshint -W040 */
542
+ var opts = $.extend(true, {}, defaults, options);
543
+
544
+ return this.each(function ()
545
+ {
546
+ var wizard = $(this);
547
+ var state = {
548
+ currentIndex: opts.startIndex,
549
+ currentStep: null,
550
+ stepCount: 0,
551
+ transitionElement: null
552
+ };
553
+
554
+ // Create data container
555
+ wizard.data("options", opts);
556
+ wizard.data("state", state);
557
+ wizard.data("steps", []);
558
+
559
+ analyzeData(wizard, opts, state);
560
+ render(wizard, opts, state);
561
+ registerEvents(wizard, opts);
562
+
563
+ // Trigger focus
564
+ if (opts.autoFocus && _uniqueId === 0)
565
+ {
566
+ getStepAnchor(wizard, opts.startIndex).focus();
567
+ }
568
+
569
+ wizard.triggerHandler("init", [opts.startIndex]);
570
+ });
571
+ }
572
+
573
+ /**
574
+ * Inserts a new step to a specific position.
575
+ *
576
+ * @static
577
+ * @private
578
+ * @method insertStep
579
+ * @param wizard {Object} The jQuery wizard object
580
+ * @param options {Object} Settings of the current wizard
581
+ * @param state {Object} The state container of the current wizard
582
+ * @param index {Integer} The position (zero-based) to add
583
+ * @param step {Object} The step object to add
584
+ * @example
585
+ * $("#wizard").steps().insert(0, {
586
+ * title: "Title",
587
+ * content: "", // optional
588
+ * contentMode: "async", // optional
589
+ * contentUrl: "/Content/Step/1" // optional
590
+ * });
591
+ * @chainable
592
+ **/
593
+ function insertStep(wizard, options, state, index, step)
594
+ {
595
+ if (index < 0 || index > state.stepCount)
596
+ {
597
+ throwError(_indexOutOfRangeErrorMessage);
598
+ }
599
+
600
+ // TODO: Validate step object
601
+
602
+ // Change data
603
+ step = $.extend({}, stepModel, step);
604
+ insertStepToCache(wizard, index, step);
605
+ if (state.currentIndex !== state.stepCount && state.currentIndex >= index)
606
+ {
607
+ state.currentIndex++;
608
+ saveCurrentStateToCookie(wizard, options, state);
609
+ }
610
+ state.stepCount++;
611
+
612
+ var contentContainer = wizard.find(".content"),
613
+ header = $("<{0}>{1}</{0}>".format(options.headerTag, step.title)),
614
+ body = $("<{0}></{0}>".format(options.bodyTag));
615
+
616
+ if (step.contentMode == null || step.contentMode === contentMode.html)
617
+ {
618
+ body.html(step.content);
619
+ }
620
+
621
+ if (index === 0)
622
+ {
623
+ contentContainer.prepend(body).prepend(header);
624
+ }
625
+ else
626
+ {
627
+ getStepPanel(wizard, (index - 1)).after(body).after(header);
628
+ }
629
+
630
+ renderBody(wizard, state, body, index);
631
+ renderTitle(wizard, options, state, header, index);
632
+ refreshSteps(wizard, options, state, index);
633
+ if (index === state.currentIndex)
634
+ {
635
+ refreshStepNavigation(wizard, options, state);
636
+ }
637
+ refreshPagination(wizard, options, state);
638
+
639
+ return wizard;
640
+ }
641
+
642
+ /**
643
+ * Inserts a step object to the cache at a specific position.
644
+ *
645
+ * @static
646
+ * @private
647
+ * @method insertStepToCache
648
+ * @param wizard {Object} A jQuery wizard object
649
+ * @param index {Integer} The position (zero-based) to add
650
+ * @param step {Object} The step object to add
651
+ **/
652
+ function insertStepToCache(wizard, index, step)
653
+ {
654
+ getSteps(wizard).splice(index, 0, step);
655
+ }
656
+
657
+ /**
658
+ * Handles the keyup DOM event for pagination.
659
+ *
660
+ * @static
661
+ * @private
662
+ * @event keyup
663
+ * @param event {Object} An event object
664
+ */
665
+ function keyUpHandler(event)
666
+ {
667
+ var wizard = $(this),
668
+ options = getOptions(wizard),
669
+ state = getState(wizard);
670
+
671
+ if (options.suppressPaginationOnFocus && wizard.find(":focus").is(":input"))
672
+ {
673
+ event.preventDefault();
674
+ return false;
675
+ }
676
+
677
+ var keyCodes = { left: 37, right: 39 };
678
+ if (event.keyCode === keyCodes.left)
679
+ {
680
+ event.preventDefault();
681
+ goToPreviousStep(wizard, options, state);
682
+ }
683
+ else if (event.keyCode === keyCodes.right)
684
+ {
685
+ event.preventDefault();
686
+ goToNextStep(wizard, options, state);
687
+ }
688
+ }
689
+
690
+ /**
691
+ * Loads and includes async content.
692
+ *
693
+ * @static
694
+ * @private
695
+ * @method loadAsyncContent
696
+ * @param wizard {Object} A jQuery wizard object
697
+ * @param options {Object} Settings of the current wizard
698
+ * @param state {Object} The state container of the current wizard
699
+ */
700
+ function loadAsyncContent(wizard, options, state)
701
+ {
702
+ if (state.stepCount > 0)
703
+ {
704
+ var currentIndex = state.currentIndex,
705
+ currentStep = getStep(wizard, currentIndex);
706
+
707
+ if (!options.enableContentCache || !currentStep.contentLoaded)
708
+ {
709
+ switch (getValidEnumValue(contentMode, currentStep.contentMode))
710
+ {
711
+ case contentMode.iframe:
712
+ wizard.find(".content > .body").eq(state.currentIndex).empty()
713
+ .html("<iframe src=\"" + currentStep.contentUrl + "\" frameborder=\"0\" scrolling=\"no\" />")
714
+ .data("loaded", "1");
715
+ break;
716
+
717
+ case contentMode.async:
718
+ var currentStepContent = getStepPanel(wizard, currentIndex)._aria("busy", "true")
719
+ .empty().append(renderTemplate(options.loadingTemplate, { text: options.labels.loading }));
720
+
721
+ $.ajax({ url: currentStep.contentUrl, cache: false }).done(function (data)
722
+ {
723
+ currentStepContent.empty().html(data)._aria("busy", "false").data("loaded", "1");
724
+ wizard.triggerHandler("contentLoaded", [currentIndex]);
725
+ });
726
+ break;
727
+ }
728
+ }
729
+ }
730
+ }
731
+
732
+ /**
733
+ * Fires the action next or previous click event.
734
+ *
735
+ * @static
736
+ * @private
737
+ * @method paginationClick
738
+ * @param wizard {Object} The jQuery wizard object
739
+ * @param options {Object} Settings of the current wizard
740
+ * @param state {Object} The state container of the current wizard
741
+ * @param index {Integer} The position (zero-based) to route to
742
+ * @return {Boolean} Indicates whether the event fired successfully or not
743
+ **/
744
+ function paginationClick(wizard, options, state, index)
745
+ {
746
+ var oldIndex = state.currentIndex;
747
+
748
+ if (index >= 0 && index < state.stepCount && !(options.forceMoveForward && index < state.currentIndex))
749
+ {
750
+ var anchor = getStepAnchor(wizard, index),
751
+ parent = anchor.parent(),
752
+ isDisabled = parent.hasClass("disabled");
753
+
754
+ // Enable the step to make the anchor clickable!
755
+ parent._enableAria();
756
+ anchor.click();
757
+
758
+ // An error occured
759
+ if (oldIndex === state.currentIndex && isDisabled)
760
+ {
761
+ // Disable the step again if current index has not changed; prevents click action.
762
+ parent._enableAria(false);
763
+ return false;
764
+ }
765
+
766
+ return true;
767
+ }
768
+
769
+ return false;
770
+ }
771
+
772
+ /**
773
+ * Fires when a pagination click happens.
774
+ *
775
+ * @static
776
+ * @private
777
+ * @event click
778
+ * @param event {Object} An event object
779
+ */
780
+ function paginationClickHandler(event)
781
+ {
782
+ event.preventDefault();
783
+
784
+ var anchor = $(this),
785
+ wizard = anchor.parent().parent().parent().parent(),
786
+ options = getOptions(wizard),
787
+ state = getState(wizard),
788
+ href = anchor.attr("href");
789
+
790
+ switch (href.substring(href.lastIndexOf("#") + 1))
791
+ {
792
+ case "cancel":
793
+ cancel(wizard);
794
+ break;
795
+
796
+ case "finish":
797
+ finishStep(wizard, state);
798
+ break;
799
+
800
+ case "next":
801
+ goToNextStep(wizard, options, state);
802
+ break;
803
+
804
+ case "previous":
805
+ goToPreviousStep(wizard, options, state);
806
+ break;
807
+ }
808
+ }
809
+
810
+ /**
811
+ * Refreshs the visualization state for the entire pagination.
812
+ *
813
+ * @static
814
+ * @private
815
+ * @method refreshPagination
816
+ * @param wizard {Object} A jQuery wizard object
817
+ * @param options {Object} Settings of the current wizard
818
+ * @param state {Object} The state container of the current wizard
819
+ */
820
+ function refreshPagination(wizard, options, state)
821
+ {
822
+ if (options.enablePagination)
823
+ {
824
+ var finish = wizard.find(".actions a[href$='#finish']").parent(),
825
+ next = wizard.find(".actions a[href$='#next']").parent();
826
+
827
+ if (!options.forceMoveForward)
828
+ {
829
+ var previous = wizard.find(".actions a[href$='#previous']").parent();
830
+ previous._enableAria(state.currentIndex > 0);
831
+ }
832
+
833
+ if (options.enableFinishButton && options.showFinishButtonAlways)
834
+ {
835
+ finish._enableAria(state.stepCount > 0);
836
+ next._enableAria(state.stepCount > 1 && state.stepCount > (state.currentIndex + 1));
837
+ }
838
+ else
839
+ {
840
+ finish._showAria(options.enableFinishButton && state.stepCount === (state.currentIndex + 1));
841
+ next._showAria(state.stepCount === 0 || state.stepCount > (state.currentIndex + 1)).
842
+ _enableAria(state.stepCount > (state.currentIndex + 1) || !options.enableFinishButton);
843
+ }
844
+ }
845
+ }
846
+
847
+ /**
848
+ * Refreshs the visualization state for the step navigation (tabs).
849
+ *
850
+ * @static
851
+ * @private
852
+ * @method refreshStepNavigation
853
+ * @param wizard {Object} A jQuery wizard object
854
+ * @param options {Object} Settings of the current wizard
855
+ * @param state {Object} The state container of the current wizard
856
+ * @param [oldIndex] {Integer} The index of the prior step
857
+ */
858
+ function refreshStepNavigation(wizard, options, state, oldIndex)
859
+ {
860
+ var currentOrNewStepAnchor = getStepAnchor(wizard, state.currentIndex),
861
+ currentInfo = $("<span class=\"current-info audible\">" + options.labels.current + " </span>"),
862
+ stepTitles = wizard.find(".content > .title");
863
+
864
+ if (oldIndex != null)
865
+ {
866
+ var oldStepAnchor = getStepAnchor(wizard, oldIndex);
867
+ oldStepAnchor.parent().addClass("done").removeClass("error")._selectAria(false);
868
+ stepTitles.eq(oldIndex).removeClass("current").next(".body").removeClass("current");
869
+ currentInfo = oldStepAnchor.find(".current-info");
870
+ currentOrNewStepAnchor.focus();
871
+ }
872
+
873
+ currentOrNewStepAnchor.prepend(currentInfo).parent()._selectAria().removeClass("done")._enableAria();
874
+ stepTitles.eq(state.currentIndex).addClass("current").next(".body").addClass("current");
875
+ }
876
+
877
+ /**
878
+ * Refreshes step buttons and their related titles beyond a certain position.
879
+ *
880
+ * @static
881
+ * @private
882
+ * @method refreshSteps
883
+ * @param wizard {Object} A jQuery wizard object
884
+ * @param options {Object} Settings of the current wizard
885
+ * @param state {Object} The state container of the current wizard
886
+ * @param index {Integer} The start point for refreshing ids
887
+ */
888
+ function refreshSteps(wizard, options, state, index)
889
+ {
890
+ var uniqueId = getUniqueId(wizard);
891
+
892
+ for (var i = index; i < state.stepCount; i++)
893
+ {
894
+ var uniqueStepId = uniqueId + _tabSuffix + i,
895
+ uniqueBodyId = uniqueId + _tabpanelSuffix + i,
896
+ uniqueHeaderId = uniqueId + _titleSuffix + i,
897
+ title = wizard.find(".title").eq(i)._id(uniqueHeaderId);
898
+
899
+ wizard.find(".steps a").eq(i)._id(uniqueStepId)
900
+ ._aria("controls", uniqueBodyId).attr("href", "#" + uniqueHeaderId)
901
+ .html(renderTemplate(options.titleTemplate, { index: i + 1, title: title.html() }));
902
+ wizard.find(".body").eq(i)._id(uniqueBodyId)
903
+ ._aria("labelledby", uniqueHeaderId);
904
+ }
905
+ }
906
+
907
+ function registerEvents(wizard, options)
908
+ {
909
+ var eventNamespace = getEventNamespace(wizard);
910
+
911
+ wizard.bind("canceled" + eventNamespace, options.onCanceled);
912
+ wizard.bind("contentLoaded" + eventNamespace, options.onContentLoaded);
913
+ wizard.bind("finishing" + eventNamespace, options.onFinishing);
914
+ wizard.bind("finished" + eventNamespace, options.onFinished);
915
+ wizard.bind("init" + eventNamespace, options.onInit);
916
+ wizard.bind("stepChanging" + eventNamespace, options.onStepChanging);
917
+ wizard.bind("stepChanged" + eventNamespace, options.onStepChanged);
918
+
919
+ if (options.enableKeyNavigation)
920
+ {
921
+ wizard.bind("keyup" + eventNamespace, keyUpHandler);
922
+ }
923
+
924
+ wizard.find(".actions a").bind("click" + eventNamespace, paginationClickHandler);
925
+ }
926
+
927
+ /**
928
+ * Removes a specific step by an given index.
929
+ *
930
+ * @static
931
+ * @private
932
+ * @method removeStep
933
+ * @param wizard {Object} A jQuery wizard object
934
+ * @param options {Object} Settings of the current wizard
935
+ * @param state {Object} The state container of the current wizard
936
+ * @param index {Integer} The position (zero-based) of the step to remove
937
+ * @return Indecates whether the item is removed.
938
+ **/
939
+ function removeStep(wizard, options, state, index)
940
+ {
941
+ // Index out of range and try deleting current item will return false.
942
+ if (index < 0 || index >= state.stepCount || state.currentIndex === index)
943
+ {
944
+ return false;
945
+ }
946
+
947
+ // Change data
948
+ removeStepFromCache(wizard, index);
949
+ if (state.currentIndex > index)
950
+ {
951
+ state.currentIndex--;
952
+ saveCurrentStateToCookie(wizard, options, state);
953
+ }
954
+ state.stepCount--;
955
+
956
+ getStepTitle(wizard, index).remove();
957
+ getStepPanel(wizard, index).remove();
958
+ getStepAnchor(wizard, index).parent().remove();
959
+
960
+ // Set the "first" class to the new first step button
961
+ if (index === 0)
962
+ {
963
+ wizard.find(".steps li").first().addClass("first");
964
+ }
965
+
966
+ // Set the "last" class to the new last step button
967
+ if (index === state.stepCount)
968
+ {
969
+ wizard.find(".steps li").eq(index).addClass("last");
970
+ }
971
+
972
+ refreshSteps(wizard, options, state, index);
973
+ refreshPagination(wizard, options, state);
974
+
975
+ return true;
976
+ }
977
+
978
+ function removeStepFromCache(wizard, index)
979
+ {
980
+ getSteps(wizard).splice(index, 1);
981
+ }
982
+
983
+ /**
984
+ * Transforms the base html structure to a more sensible html structure.
985
+ *
986
+ * @static
987
+ * @private
988
+ * @method render
989
+ * @param wizard {Object} A jQuery wizard object
990
+ * @param options {Object} Settings of the current wizard
991
+ * @param state {Object} The state container of the current wizard
992
+ **/
993
+ function render(wizard, options, state)
994
+ {
995
+ // Create a content wrapper and copy HTML from the intial wizard structure
996
+ var wrapperTemplate = "<{0} class=\"{1}\">{2}</{0}>",
997
+ orientation = getValidEnumValue(stepsOrientation, options.stepsOrientation),
998
+ verticalCssClass = (orientation === stepsOrientation.vertical) ? " vertical" : "",
999
+ contentWrapper = $(wrapperTemplate.format(options.contentContainerTag, "content " + options.clearFixCssClass, wizard.html())),
1000
+ stepsWrapper = $(wrapperTemplate.format(options.stepsContainerTag, "steps " + options.clearFixCssClass, "<ul role=\"tablist\"></ul>")),
1001
+ stepTitles = contentWrapper.children(options.headerTag),
1002
+ stepContents = contentWrapper.children(options.bodyTag);
1003
+
1004
+ // Transform the wizard wrapper and remove the inner HTML
1005
+ wizard.attr("role", "application").empty().append(stepsWrapper).append(contentWrapper)
1006
+ .addClass(options.cssClass + " " + options.clearFixCssClass + verticalCssClass);
1007
+
1008
+ // Add WIA-ARIA support
1009
+ stepContents.each(function (index)
1010
+ {
1011
+ renderBody(wizard, state, $(this), index);
1012
+ });
1013
+
1014
+ stepTitles.each(function (index)
1015
+ {
1016
+ renderTitle(wizard, options, state, $(this), index);
1017
+ });
1018
+
1019
+ refreshStepNavigation(wizard, options, state);
1020
+ renderPagination(wizard, options, state);
1021
+ }
1022
+
1023
+ /**
1024
+ * Transforms the body to a proper tabpanel.
1025
+ *
1026
+ * @static
1027
+ * @private
1028
+ * @method renderBody
1029
+ * @param wizard {Object} A jQuery wizard object
1030
+ * @param body {Object} A jQuery body object
1031
+ * @param index {Integer} The position of the body
1032
+ */
1033
+ function renderBody(wizard, state, body, index)
1034
+ {
1035
+ var uniqueId = getUniqueId(wizard),
1036
+ uniqueBodyId = uniqueId + _tabpanelSuffix + index,
1037
+ uniqueHeaderId = uniqueId + _titleSuffix + index;
1038
+
1039
+ body._id(uniqueBodyId).attr("role", "tabpanel")._aria("labelledby", uniqueHeaderId)
1040
+ .addClass("body")._showAria(state.currentIndex === index);
1041
+ }
1042
+
1043
+ /**
1044
+ * Renders a pagination if enabled.
1045
+ *
1046
+ * @static
1047
+ * @private
1048
+ * @method renderPagination
1049
+ * @param wizard {Object} A jQuery wizard object
1050
+ * @param options {Object} Settings of the current wizard
1051
+ * @param state {Object} The state container of the current wizard
1052
+ */
1053
+ function renderPagination(wizard, options, state)
1054
+ {
1055
+ if (options.enablePagination)
1056
+ {
1057
+ var pagination = "<{0} class=\"actions {1}\"><ul role=\"menu\" aria-label=\"{2}\">{3}</ul></{0}>",
1058
+ buttonTemplate = "<li><a href=\"#{0}\" role=\"menuitem\">{1}</a></li>",
1059
+ buttons = "";
1060
+
1061
+ if (!options.forceMoveForward)
1062
+ {
1063
+ buttons += buttonTemplate.format("previous", options.labels.previous);
1064
+ }
1065
+
1066
+ buttons += buttonTemplate.format("next", options.labels.next);
1067
+
1068
+ if (options.enableFinishButton)
1069
+ {
1070
+ buttons += buttonTemplate.format("finish", options.labels.finish);
1071
+ }
1072
+
1073
+ if (options.enableCancelButton)
1074
+ {
1075
+ buttons += buttonTemplate.format("cancel", options.labels.cancel);
1076
+ }
1077
+
1078
+ wizard.append(pagination.format(options.actionContainerTag, options.clearFixCssClass,
1079
+ options.labels.pagination, buttons));
1080
+
1081
+ refreshPagination(wizard, options, state);
1082
+ loadAsyncContent(wizard, options, state);
1083
+ }
1084
+ }
1085
+
1086
+ /**
1087
+ * Renders a template and replaces all placeholder.
1088
+ *
1089
+ * @static
1090
+ * @private
1091
+ * @method renderTemplate
1092
+ * @param template {String} A template
1093
+ * @param substitutes {Object} A list of substitute
1094
+ * @return {String} The rendered template
1095
+ */
1096
+ function renderTemplate(template, substitutes)
1097
+ {
1098
+ var matches = template.match(/#([a-z]*)#/gi);
1099
+
1100
+ for (var i = 0; i < matches.length; i++)
1101
+ {
1102
+ var match = matches[i],
1103
+ key = match.substring(1, match.length - 1);
1104
+
1105
+ if (substitutes[key] === undefined)
1106
+ {
1107
+ throwError("The key '{0}' does not exist in the substitute collection!", key);
1108
+ }
1109
+
1110
+ template = template.replace(match, substitutes[key]);
1111
+ }
1112
+
1113
+ return template;
1114
+ }
1115
+
1116
+ /**
1117
+ * Transforms the title to a step item button.
1118
+ *
1119
+ * @static
1120
+ * @private
1121
+ * @method renderTitle
1122
+ * @param wizard {Object} A jQuery wizard object
1123
+ * @param options {Object} Settings of the current wizard
1124
+ * @param state {Object} The state container of the current wizard
1125
+ * @param header {Object} A jQuery header object
1126
+ * @param index {Integer} The position of the header
1127
+ */
1128
+ function renderTitle(wizard, options, state, header, index)
1129
+ {
1130
+ var uniqueId = getUniqueId(wizard),
1131
+ uniqueStepId = uniqueId + _tabSuffix + index,
1132
+ uniqueBodyId = uniqueId + _tabpanelSuffix + index,
1133
+ uniqueHeaderId = uniqueId + _titleSuffix + index,
1134
+ stepCollection = wizard.find(".steps > ul"),
1135
+ title = renderTemplate(options.titleTemplate, {
1136
+ index: index + 1,
1137
+ title: header.html()
1138
+ }),
1139
+ stepItem = $("<li role=\"tab\"><a id=\"" + uniqueStepId + "\" href=\"#" + uniqueHeaderId +
1140
+ "\" aria-controls=\"" + uniqueBodyId + "\">" + title + "</a></li>");
1141
+
1142
+ stepItem._enableAria(options.enableAllSteps || state.currentIndex > index);
1143
+
1144
+ if (state.currentIndex > index)
1145
+ {
1146
+ stepItem.addClass("done");
1147
+ }
1148
+
1149
+ header._id(uniqueHeaderId).attr("tabindex", "-1").addClass("title");
1150
+
1151
+ if (index === 0)
1152
+ {
1153
+ stepCollection.prepend(stepItem);
1154
+ }
1155
+ else
1156
+ {
1157
+ stepCollection.find("li").eq(index - 1).after(stepItem);
1158
+ }
1159
+
1160
+ // Set the "first" class to the new first step button
1161
+ if (index === 0)
1162
+ {
1163
+ stepCollection.find("li").removeClass("first").eq(index).addClass("first");
1164
+ }
1165
+
1166
+ // Set the "last" class to the new last step button
1167
+ if (index === (state.stepCount - 1))
1168
+ {
1169
+ stepCollection.find("li").removeClass("last").eq(index).addClass("last");
1170
+ }
1171
+
1172
+ // Register click event
1173
+ stepItem.children("a").bind("click" + getEventNamespace(wizard), stepClickHandler);
1174
+ }
1175
+
1176
+ /**
1177
+ * Saves the current state to a cookie.
1178
+ *
1179
+ * @static
1180
+ * @private
1181
+ * @method saveCurrentStateToCookie
1182
+ * @param wizard {Object} A jQuery wizard object
1183
+ * @param options {Object} Settings of the current wizard
1184
+ * @param state {Object} The state container of the current wizard
1185
+ */
1186
+ function saveCurrentStateToCookie(wizard, options, state)
1187
+ {
1188
+ if (options.saveState && $.cookie)
1189
+ {
1190
+ $.cookie(_cookiePrefix + getUniqueId(wizard), state.currentIndex);
1191
+ }
1192
+ }
1193
+
1194
+ function startTransitionEffect(wizard, options, state, index, oldIndex, doneCallback)
1195
+ {
1196
+ var stepContents = wizard.find(".content > .body"),
1197
+ effect = getValidEnumValue(transitionEffect, options.transitionEffect),
1198
+ effectSpeed = options.transitionEffectSpeed,
1199
+ newStep = stepContents.eq(index),
1200
+ currentStep = stepContents.eq(oldIndex);
1201
+
1202
+ switch (effect)
1203
+ {
1204
+ case transitionEffect.fade:
1205
+ case transitionEffect.slide:
1206
+ var hide = (effect === transitionEffect.fade) ? "fadeOut" : "slideUp",
1207
+ show = (effect === transitionEffect.fade) ? "fadeIn" : "slideDown";
1208
+
1209
+ state.transitionElement = newStep;
1210
+ currentStep[hide](effectSpeed, function ()
1211
+ {
1212
+ var wizard = $(this)._showAria(false).parent().parent(),
1213
+ state = getState(wizard);
1214
+
1215
+ if (state.transitionElement)
1216
+ {
1217
+ state.transitionElement[show](effectSpeed, function ()
1218
+ {
1219
+ $(this)._showAria();
1220
+ }).promise().done(doneCallback);
1221
+ state.transitionElement = null;
1222
+ }
1223
+ });
1224
+ break;
1225
+
1226
+ case transitionEffect.slideLeft:
1227
+ var outerWidth = currentStep.outerWidth(true),
1228
+ posFadeOut = (index > oldIndex) ? -(outerWidth) : outerWidth,
1229
+ posFadeIn = (index > oldIndex) ? outerWidth : -(outerWidth);
1230
+
1231
+ $.when(currentStep.animate({ left: posFadeOut }, effectSpeed,
1232
+ function () { $(this)._showAria(false); }),
1233
+ newStep.css("left", posFadeIn + "px")._showAria()
1234
+ .animate({ left: 0 }, effectSpeed)).done(doneCallback);
1235
+ break;
1236
+
1237
+ default:
1238
+ $.when(currentStep._showAria(false), newStep._showAria())
1239
+ .done(doneCallback);
1240
+ break;
1241
+ }
1242
+ }
1243
+
1244
+ /**
1245
+ * Fires when a step click happens.
1246
+ *
1247
+ * @static
1248
+ * @private
1249
+ * @event click
1250
+ * @param event {Object} An event object
1251
+ */
1252
+ function stepClickHandler(event)
1253
+ {
1254
+ event.preventDefault();
1255
+
1256
+ var anchor = $(this),
1257
+ wizard = anchor.parent().parent().parent().parent(),
1258
+ options = getOptions(wizard),
1259
+ state = getState(wizard),
1260
+ oldIndex = state.currentIndex;
1261
+
1262
+ if (anchor.parent().is(":not(.disabled):not(.current)"))
1263
+ {
1264
+ var href = anchor.attr("href"),
1265
+ position = parseInt(href.substring(href.lastIndexOf("-") + 1), 0);
1266
+
1267
+ goToStep(wizard, options, state, position);
1268
+ }
1269
+
1270
+ // If nothing has changed
1271
+ if (oldIndex === state.currentIndex)
1272
+ {
1273
+ getStepAnchor(wizard, oldIndex).focus();
1274
+ return false;
1275
+ }
1276
+ }
1277
+
1278
+ function throwError(message)
1279
+ {
1280
+ if (arguments.length > 1)
1281
+ {
1282
+ message = message.format(Array.prototype.slice.call(arguments, 1));
1283
+ }
1284
+
1285
+ throw new Error(message);
1286
+ }
1287
+
1288
+ /**
1289
+ * Checks an argument for null or undefined and throws an error if one check applies.
1290
+ *
1291
+ * @static
1292
+ * @private
1293
+ * @method validateArgument
1294
+ * @param argumentName {String} The name of the given argument
1295
+ * @param argumentValue {Object} The argument itself
1296
+ */
1297
+ function validateArgument(argumentName, argumentValue)
1298
+ {
1299
+ if (argumentValue == null)
1300
+ {
1301
+ throwError("The argument '{0}' is null or undefined.", argumentName);
1302
+ }
1303
+ }
1304
+
1305
+ /**
1306
+ * Represents a jQuery wizard plugin.
1307
+ *
1308
+ * @class steps
1309
+ * @constructor
1310
+ * @param [method={}] The name of the method as `String` or an JSON object for initialization
1311
+ * @param [params=]* {Array} Additional arguments for a method call
1312
+ * @chainable
1313
+ **/
1314
+ $.fn.steps = function (method)
1315
+ {
1316
+ if ($.fn.steps[method])
1317
+ {
1318
+ return $.fn.steps[method].apply(this, Array.prototype.slice.call(arguments, 1));
1319
+ }
1320
+ else if (typeof method === "object" || !method)
1321
+ {
1322
+ return initialize.apply(this, arguments);
1323
+ }
1324
+ else
1325
+ {
1326
+ $.error("Method " + method + " does not exist on jQuery.steps");
1327
+ }
1328
+ };
1329
+
1330
+ /**
1331
+ * Adds a new step.
1332
+ *
1333
+ * @method add
1334
+ * @param step {Object} The step object to add
1335
+ * @chainable
1336
+ **/
1337
+ $.fn.steps.add = function (step)
1338
+ {
1339
+ var state = getState(this);
1340
+ return insertStep(this, getOptions(this), state, state.stepCount, step);
1341
+ };
1342
+
1343
+ /**
1344
+ * Removes the control functionality completely and transforms the current state to the initial HTML structure.
1345
+ *
1346
+ * @method destroy
1347
+ * @chainable
1348
+ **/
1349
+ $.fn.steps.destroy = function ()
1350
+ {
1351
+ return destroy(this, getOptions(this));
1352
+ };
1353
+
1354
+ /**
1355
+ * Triggers the onFinishing and onFinished event.
1356
+ *
1357
+ * @method finish
1358
+ **/
1359
+ $.fn.steps.finish = function ()
1360
+ {
1361
+ finishStep(this, getState(this));
1362
+ };
1363
+
1364
+ /**
1365
+ * Gets the current step index.
1366
+ *
1367
+ * @method getCurrentIndex
1368
+ * @return {Integer} The actual step index (zero-based)
1369
+ * @for steps
1370
+ **/
1371
+ $.fn.steps.getCurrentIndex = function ()
1372
+ {
1373
+ return getState(this).currentIndex;
1374
+ };
1375
+
1376
+ /**
1377
+ * Gets the current step object.
1378
+ *
1379
+ * @method getCurrentStep
1380
+ * @return {Object} The actual step object
1381
+ **/
1382
+ $.fn.steps.getCurrentStep = function ()
1383
+ {
1384
+ return getStep(this, getState(this).currentIndex);
1385
+ };
1386
+
1387
+ /**
1388
+ * Gets a specific step object by index.
1389
+ *
1390
+ * @method getStep
1391
+ * @param index {Integer} An integer that belongs to the position of a step
1392
+ * @return {Object} A specific step object
1393
+ **/
1394
+ $.fn.steps.getStep = function (index)
1395
+ {
1396
+ return getStep(this, index);
1397
+ };
1398
+
1399
+ /**
1400
+ * Inserts a new step to a specific position.
1401
+ *
1402
+ * @method insert
1403
+ * @param index {Integer} The position (zero-based) to add
1404
+ * @param step {Object} The step object to add
1405
+ * @example
1406
+ * $("#wizard").steps().insert(0, {
1407
+ * title: "Title",
1408
+ * content: "", // optional
1409
+ * contentMode: "async", // optional
1410
+ * contentUrl: "/Content/Step/1" // optional
1411
+ * });
1412
+ * @chainable
1413
+ **/
1414
+ $.fn.steps.insert = function (index, step)
1415
+ {
1416
+ return insertStep(this, getOptions(this), getState(this), index, step);
1417
+ };
1418
+
1419
+ /**
1420
+ * Routes to the next step.
1421
+ *
1422
+ * @method next
1423
+ * @return {Boolean} Indicates whether the action executed
1424
+ **/
1425
+ $.fn.steps.next = function ()
1426
+ {
1427
+ return goToNextStep(this, getOptions(this), getState(this));
1428
+ };
1429
+
1430
+ /**
1431
+ * Routes to the previous step.
1432
+ *
1433
+ * @method previous
1434
+ * @return {Boolean} Indicates whether the action executed
1435
+ **/
1436
+ $.fn.steps.previous = function ()
1437
+ {
1438
+ return goToPreviousStep(this, getOptions(this), getState(this));
1439
+ };
1440
+
1441
+ /**
1442
+ * Removes a specific step by an given index.
1443
+ *
1444
+ * @method remove
1445
+ * @param index {Integer} The position (zero-based) of the step to remove
1446
+ * @return Indecates whether the item is removed.
1447
+ **/
1448
+ $.fn.steps.remove = function (index)
1449
+ {
1450
+ return removeStep(this, getOptions(this), getState(this), index);
1451
+ };
1452
+
1453
+ /**
1454
+ * Sets a specific step object by index.
1455
+ *
1456
+ * @method setStep
1457
+ * @param index {Integer} An integer that belongs to the position of a step
1458
+ * @param step {Object} The step object to change
1459
+ **/
1460
+ $.fn.steps.setStep = function (index, step)
1461
+ {
1462
+ throw new Error("Not yet implemented!");
1463
+ };
1464
+
1465
+ /**
1466
+ * Skips an certain amount of steps.
1467
+ *
1468
+ * @method skip
1469
+ * @param count {Integer} The amount of steps that should be skipped
1470
+ * @return {Boolean} Indicates whether the action executed
1471
+ **/
1472
+ $.fn.steps.skip = function (count)
1473
+ {
1474
+ throw new Error("Not yet implemented!");
1475
+ };
1476
+
1477
+ /**
1478
+ * An enum represents the different content types of a step and their loading mechanisms.
1479
+ *
1480
+ * @class contentMode
1481
+ * @for steps
1482
+ **/
1483
+ var contentMode = $.fn.steps.contentMode = {
1484
+ /**
1485
+ * HTML embedded content
1486
+ *
1487
+ * @readOnly
1488
+ * @property html
1489
+ * @type Integer
1490
+ * @for contentMode
1491
+ **/
1492
+ html: 0,
1493
+
1494
+ /**
1495
+ * IFrame embedded content
1496
+ *
1497
+ * @readOnly
1498
+ * @property iframe
1499
+ * @type Integer
1500
+ * @for contentMode
1501
+ **/
1502
+ iframe: 1,
1503
+
1504
+ /**
1505
+ * Async embedded content
1506
+ *
1507
+ * @readOnly
1508
+ * @property async
1509
+ * @type Integer
1510
+ * @for contentMode
1511
+ **/
1512
+ async: 2
1513
+ };
1514
+
1515
+ /**
1516
+ * An enum represents the orientation of the steps navigation.
1517
+ *
1518
+ * @class stepsOrientation
1519
+ * @for steps
1520
+ **/
1521
+ var stepsOrientation = $.fn.steps.stepsOrientation = {
1522
+ /**
1523
+ * Horizontal orientation
1524
+ *
1525
+ * @readOnly
1526
+ * @property horizontal
1527
+ * @type Integer
1528
+ * @for stepsOrientation
1529
+ **/
1530
+ horizontal: 0,
1531
+
1532
+ /**
1533
+ * Vertical orientation
1534
+ *
1535
+ * @readOnly
1536
+ * @property vertical
1537
+ * @type Integer
1538
+ * @for stepsOrientation
1539
+ **/
1540
+ vertical: 1
1541
+ };
1542
+
1543
+ /**
1544
+ * An enum that represents the various transition animations.
1545
+ *
1546
+ * @class transitionEffect
1547
+ * @for steps
1548
+ **/
1549
+ var transitionEffect = $.fn.steps.transitionEffect = {
1550
+ /**
1551
+ * No transition animation
1552
+ *
1553
+ * @readOnly
1554
+ * @property none
1555
+ * @type Integer
1556
+ * @for transitionEffect
1557
+ **/
1558
+ none: 0,
1559
+
1560
+ /**
1561
+ * Fade in transition
1562
+ *
1563
+ * @readOnly
1564
+ * @property fade
1565
+ * @type Integer
1566
+ * @for transitionEffect
1567
+ **/
1568
+ fade: 1,
1569
+
1570
+ /**
1571
+ * Slide up transition
1572
+ *
1573
+ * @readOnly
1574
+ * @property slide
1575
+ * @type Integer
1576
+ * @for transitionEffect
1577
+ **/
1578
+ slide: 2,
1579
+
1580
+ /**
1581
+ * Slide left transition
1582
+ *
1583
+ * @readOnly
1584
+ * @property slideLeft
1585
+ * @type Integer
1586
+ * @for transitionEffect
1587
+ **/
1588
+ slideLeft: 3
1589
+ };
1590
+
1591
+ var stepModel = $.fn.steps.stepModel = {
1592
+ title: "",
1593
+ content: "",
1594
+ contentUrl: "",
1595
+ contentMode: contentMode.html,
1596
+ contentLoaded: false
1597
+ };
1598
+
1599
+ /**
1600
+ * An object that represents the default settings.
1601
+ * There are two possibities to override the sub-properties.
1602
+ * Either by doing it generally (global) or on initialization.
1603
+ *
1604
+ * @static
1605
+ * @class defaults
1606
+ * @for steps
1607
+ * @example
1608
+ * // Global approach
1609
+ * $.steps.defaults.headerTag = "h3";
1610
+ * @example
1611
+ * // Initialization approach
1612
+ * $("#wizard").steps({ headerTag: "h3" });
1613
+ **/
1614
+ var defaults = $.fn.steps.defaults = {
1615
+ /**
1616
+ * The header tag is used to find the step button text within the declared wizard area.
1617
+ *
1618
+ * @property headerTag
1619
+ * @type String
1620
+ * @default "h1"
1621
+ * @for defaults
1622
+ **/
1623
+ headerTag: "h1",
1624
+
1625
+ /**
1626
+ * The body tag is used to find the step content within the declared wizard area.
1627
+ *
1628
+ * @property bodyTag
1629
+ * @type String
1630
+ * @default "div"
1631
+ * @for defaults
1632
+ **/
1633
+ bodyTag: "div",
1634
+
1635
+ /**
1636
+ * The content container tag which will be used to wrap all step contents.
1637
+ *
1638
+ * @property contentContainerTag
1639
+ * @type String
1640
+ * @default "div"
1641
+ * @for defaults
1642
+ **/
1643
+ contentContainerTag: "div",
1644
+
1645
+ /**
1646
+ * The action container tag which will be used to wrap the pagination navigation.
1647
+ *
1648
+ * @property actionContainerTag
1649
+ * @type String
1650
+ * @default "div"
1651
+ * @for defaults
1652
+ **/
1653
+ actionContainerTag: "div",
1654
+
1655
+ /**
1656
+ * The steps container tag which will be used to wrap the steps navigation.
1657
+ *
1658
+ * @property stepsContainerTag
1659
+ * @type String
1660
+ * @default "div"
1661
+ * @for defaults
1662
+ **/
1663
+ stepsContainerTag: "div",
1664
+
1665
+ /**
1666
+ * The css class which will be added to the outer component wrapper.
1667
+ *
1668
+ * @property cssClass
1669
+ * @type String
1670
+ * @default "wizard"
1671
+ * @for defaults
1672
+ * @example
1673
+ * <div class="wizard">
1674
+ * ...
1675
+ * </div>
1676
+ **/
1677
+ cssClass: "wizard",
1678
+
1679
+ /**
1680
+ * The css class which will be used for floating scenarios.
1681
+ *
1682
+ * @property clearFixCssClass
1683
+ * @type String
1684
+ * @default "clearfix"
1685
+ * @for defaults
1686
+ **/
1687
+ clearFixCssClass: "clearfix",
1688
+
1689
+ /**
1690
+ * Determines whether the steps are vertically or horizontally oriented.
1691
+ *
1692
+ * @property stepsOrientation
1693
+ * @type stepsOrientation
1694
+ * @default horizontal
1695
+ * @for defaults
1696
+ * @since 1.0.0
1697
+ **/
1698
+ stepsOrientation: stepsOrientation.horizontal,
1699
+
1700
+ /*
1701
+ * Tempplates
1702
+ */
1703
+
1704
+ /**
1705
+ * The title template which will be used to create a step button.
1706
+ *
1707
+ * @property titleTemplate
1708
+ * @type String
1709
+ * @default "<span class=\"number\">#index#.</span> #title#"
1710
+ * @for defaults
1711
+ **/
1712
+ titleTemplate: "<span class=\"number\">#index#.</span> #title#",
1713
+
1714
+ /**
1715
+ * The loading template which will be used to create the loading animation.
1716
+ *
1717
+ * @property loadingTemplate
1718
+ * @type String
1719
+ * @default "<span class=\"spinner\"></span> #text#"
1720
+ * @for defaults
1721
+ **/
1722
+ loadingTemplate: "<span class=\"spinner\"></span> #text#",
1723
+
1724
+ /*
1725
+ * Behaviour
1726
+ */
1727
+
1728
+ /**
1729
+ * Sets the focus to the first wizard instance in order to enable the key navigation from the begining if `true`.
1730
+ *
1731
+ * @property autoFocus
1732
+ * @type Boolean
1733
+ * @default false
1734
+ * @for defaults
1735
+ * @since 0.9.4
1736
+ **/
1737
+ autoFocus: false,
1738
+
1739
+ /**
1740
+ * Enables all steps from the begining if `true` (all steps are clickable).
1741
+ *
1742
+ * @property enableAllSteps
1743
+ * @type Boolean
1744
+ * @default false
1745
+ * @for defaults
1746
+ **/
1747
+ enableAllSteps: false,
1748
+
1749
+ /**
1750
+ * Enables keyboard navigation if `true` (arrow left and arrow right).
1751
+ *
1752
+ * @property enableKeyNavigation
1753
+ * @type Boolean
1754
+ * @default true
1755
+ * @for defaults
1756
+ **/
1757
+ enableKeyNavigation: true,
1758
+
1759
+ /**
1760
+ * Enables pagination if `true`.
1761
+ *
1762
+ * @property enablePagination
1763
+ * @type Boolean
1764
+ * @default true
1765
+ * @for defaults
1766
+ **/
1767
+ enablePagination: true,
1768
+
1769
+ /**
1770
+ * Suppresses pagination if a form field is focused.
1771
+ *
1772
+ * @property suppressPaginationOnFocus
1773
+ * @type Boolean
1774
+ * @default true
1775
+ * @for defaults
1776
+ **/
1777
+ suppressPaginationOnFocus: true,
1778
+
1779
+ /**
1780
+ * Enables cache for async loaded or iframe embedded content.
1781
+ *
1782
+ * @property enableContentCache
1783
+ * @type Boolean
1784
+ * @default true
1785
+ * @for defaults
1786
+ **/
1787
+ enableContentCache: true,
1788
+
1789
+ /**
1790
+ * Shows the cancel button if enabled.
1791
+ *
1792
+ * @property enableCancelButton
1793
+ * @type Boolean
1794
+ * @default false
1795
+ * @for defaults
1796
+ **/
1797
+ enableCancelButton: false,
1798
+
1799
+ /**
1800
+ * Shows the finish button if enabled.
1801
+ *
1802
+ * @property enableFinishButton
1803
+ * @type Boolean
1804
+ * @default true
1805
+ * @for defaults
1806
+ **/
1807
+ enableFinishButton: true,
1808
+
1809
+ /**
1810
+ * Not yet implemented.
1811
+ *
1812
+ * @property preloadContent
1813
+ * @type Boolean
1814
+ * @default false
1815
+ * @for defaults
1816
+ **/
1817
+ preloadContent: false,
1818
+
1819
+ /**
1820
+ * Shows the finish button always (on each step; right beside the next button) if `true`.
1821
+ * Otherwise the next button will be replaced by the finish button if the last step becomes active.
1822
+ *
1823
+ * @property showFinishButtonAlways
1824
+ * @type Boolean
1825
+ * @default false
1826
+ * @for defaults
1827
+ **/
1828
+ showFinishButtonAlways: false,
1829
+
1830
+ /**
1831
+ * Prevents jumping to a previous step.
1832
+ *
1833
+ * @property forceMoveForward
1834
+ * @type Boolean
1835
+ * @default false
1836
+ * @for defaults
1837
+ **/
1838
+ forceMoveForward: false,
1839
+
1840
+ /**
1841
+ * Saves the current state (step position) to a cookie.
1842
+ * By coming next time the last active step becomes activated.
1843
+ *
1844
+ * @property saveState
1845
+ * @type Boolean
1846
+ * @default false
1847
+ * @for defaults
1848
+ **/
1849
+ saveState: false,
1850
+
1851
+ /**
1852
+ * The position to start on (zero-based).
1853
+ *
1854
+ * @property startIndex
1855
+ * @type Integer
1856
+ * @default 0
1857
+ * @for defaults
1858
+ **/
1859
+ startIndex: 0,
1860
+
1861
+ /*
1862
+ * Animation Effect Configuration
1863
+ */
1864
+
1865
+ /**
1866
+ * The animation effect which will be used for step transitions.
1867
+ *
1868
+ * @property transitionEffect
1869
+ * @type transitionEffect
1870
+ * @default none
1871
+ * @for defaults
1872
+ **/
1873
+ transitionEffect: transitionEffect.none,
1874
+
1875
+ /**
1876
+ * Animation speed for step transitions (in milliseconds).
1877
+ *
1878
+ * @property transitionEffectSpeed
1879
+ * @type Integer
1880
+ * @default 200
1881
+ * @for defaults
1882
+ **/
1883
+ transitionEffectSpeed: 200,
1884
+
1885
+ /*
1886
+ * Events
1887
+ */
1888
+
1889
+ /**
1890
+ * Fires before the step changes and can be used to prevent step changing by returning `false`.
1891
+ * Very useful for form validation.
1892
+ *
1893
+ * @property onStepChanging
1894
+ * @type Event
1895
+ * @default function (event, currentIndex, newIndex) { return true; }
1896
+ * @for defaults
1897
+ **/
1898
+ onStepChanging: function (event, currentIndex, newIndex) { return true; },
1899
+
1900
+ /**
1901
+ * Fires after the step has change.
1902
+ *
1903
+ * @property onStepChanged
1904
+ * @type Event
1905
+ * @default function (event, currentIndex, priorIndex) { }
1906
+ * @for defaults
1907
+ **/
1908
+ onStepChanged: function (event, currentIndex, priorIndex) { },
1909
+
1910
+ /**
1911
+ * Fires after cancelation.
1912
+ *
1913
+ * @property onCanceled
1914
+ * @type Event
1915
+ * @default function (event) { }
1916
+ * @for defaults
1917
+ **/
1918
+ onCanceled: function (event) { },
1919
+
1920
+ /**
1921
+ * Fires before finishing and can be used to prevent completion by returning `false`.
1922
+ * Very useful for form validation.
1923
+ *
1924
+ * @property onFinishing
1925
+ * @type Event
1926
+ * @default function (event, currentIndex) { return true; }
1927
+ * @for defaults
1928
+ **/
1929
+ onFinishing: function (event, currentIndex) { return true; },
1930
+
1931
+ /**
1932
+ * Fires after completion.
1933
+ *
1934
+ * @property onFinished
1935
+ * @type Event
1936
+ * @default function (event, currentIndex) { }
1937
+ * @for defaults
1938
+ **/
1939
+ onFinished: function (event, currentIndex) { },
1940
+
1941
+ /**
1942
+ * Fires after async content is loaded.
1943
+ *
1944
+ * @property onContentLoaded
1945
+ * @type Event
1946
+ * @default function (event, index) { }
1947
+ * @for defaults
1948
+ **/
1949
+ onContentLoaded: function (event, currentIndex) { },
1950
+
1951
+ /**
1952
+ * Fires when the wizard is initialized.
1953
+ *
1954
+ * @property onInit
1955
+ * @type Event
1956
+ * @default function (event) { }
1957
+ * @for defaults
1958
+ **/
1959
+ onInit: function (event, currentIndex) { },
1960
+
1961
+ /**
1962
+ * Contains all labels.
1963
+ *
1964
+ * @property labels
1965
+ * @type Object
1966
+ * @for defaults
1967
+ **/
1968
+ labels: {
1969
+ /**
1970
+ * Label for the cancel button.
1971
+ *
1972
+ * @property cancel
1973
+ * @type String
1974
+ * @default "Cancel"
1975
+ * @for defaults
1976
+ **/
1977
+ cancel: "Cancel",
1978
+
1979
+ /**
1980
+ * This label is important for accessability reasons.
1981
+ * Indicates which step is activated.
1982
+ *
1983
+ * @property current
1984
+ * @type String
1985
+ * @default "current step:"
1986
+ * @for defaults
1987
+ **/
1988
+ current: "current step:",
1989
+
1990
+ /**
1991
+ * This label is important for accessability reasons and describes the kind of navigation.
1992
+ *
1993
+ * @property pagination
1994
+ * @type String
1995
+ * @default "Pagination"
1996
+ * @for defaults
1997
+ * @since 0.9.7
1998
+ **/
1999
+ pagination: "Pagination",
2000
+
2001
+ /**
2002
+ * Label for the finish button.
2003
+ *
2004
+ * @property finish
2005
+ * @type String
2006
+ * @default "Finish"
2007
+ * @for defaults
2008
+ **/
2009
+ finish: "Finish",
2010
+
2011
+ /**
2012
+ * Label for the next button.
2013
+ *
2014
+ * @property next
2015
+ * @type String
2016
+ * @default "Next"
2017
+ * @for defaults
2018
+ **/
2019
+ next: "Next",
2020
+
2021
+ /**
2022
+ * Label for the previous button.
2023
+ *
2024
+ * @property previous
2025
+ * @type String
2026
+ * @default "Previous"
2027
+ * @for defaults
2028
+ **/
2029
+ previous: "Previous",
2030
+
2031
+ /**
2032
+ * Label for the loading animation.
2033
+ *
2034
+ * @property loading
2035
+ * @type String
2036
+ * @default "Loading ..."
2037
+ * @for defaults
2038
+ **/
2039
+ loading: "Loading ..."
2040
+ }
2041
+ };
2042
+ })(jQuery);