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