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 46if (!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 **/ 69var _uniqueId = 0; 70 71/** 72 * The plugin prefix for cookies. 73 * 74 * @final 75 * @private 76 * @property _cookiePrefix 77 * @type String 78 **/ 79var _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 **/ 90var _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 **/ 101var _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 **/ 112var _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 **/ 122var _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 **/ 132var _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 **/ 143function addStepToCache(wizard, step) 144{ 145 getSteps(wizard).push(step); 146} 147 148function 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 **/ 211function cancel(wizard) 212{ 213 wizard.triggerHandler("canceled"); 214} 215 216function 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 **/ 229function 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 **/ 278function 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 */ 302function 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 315function getStepAnchor(wizard, index) 316{ 317 var uniqueId = getUniqueId(wizard); 318 319 return wizard.find("#" + uniqueId + _tabSuffix + index); 320} 321 322function getStepPanel(wizard, index) 323{ 324 var uniqueId = getUniqueId(wizard); 325 326 return wizard.find("#" + uniqueId + _tabpanelSuffix + index); 327} 328 329function getStepTitle(wizard, index) 330{ 331 var uniqueId = getUniqueId(wizard); 332 333 return wizard.find("#" + uniqueId + _titleSuffix + index); 334} 335 336function getOptions(wizard) 337{ 338 return wizard.data("options"); 339} 340 341function getState(wizard) 342{ 343 return wizard.data("state"); 344} 345 346function 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 **/ 360function 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 */ 381function 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 */ 410function 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 **/ 457function 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 **/ 473function 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 **/ 490function 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 526function 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 **/ 539function 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 **/ 593function 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 **/ 652function 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 */ 665function 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 */ 700function 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 **/ 744function 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 */ 780function 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 */ 820function 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 */ 858function 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 */ 888function 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 907function 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 **/ 939function 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 978function 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 **/ 993function 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 */ 1033function 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 */ 1053function 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 */ 1096function 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 */ 1128function 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 */ 1186function saveCurrentStateToCookie(wizard, options, state) 1187{ 1188 if (options.saveState && $.cookie) 1189 { 1190 $.cookie(_cookiePrefix + getUniqueId(wizard), state.currentIndex); 1191 } 1192} 1193 1194function 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 */ 1252function 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 1278function 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 */ 1297function 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 **/ 1483var 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 **/ 1521var 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 **/ 1549var 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 1591var 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 **/ 1614var 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);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.