|
1 | 1 | /*!
|
2 |
| - * jQuery Steps Plugin v0.9.4 - A powerful jQuery wizard plugin that supports accessibility and HTML5 |
| 2 | + * jQuery Steps Plugin v0.9.5 - A powerful jQuery wizard plugin that supports accessibility and HTML5 |
3 | 3 | * https://github.com/rstaib/jquery-steps
|
4 | 4 | *
|
5 | 5 | * Copyright (c) 2013 Rafael J. Staib
|
6 | 6 | * Released under the MIT license
|
7 | 7 | *
|
8 | 8 | * Follow me on twitter: https://twitter.com/@RafaelStaib
|
9 | 9 | *
|
10 |
| - * Tested with jQuery v1.4.4 and newer versions as well. |
| 10 | + * Requires jQuery version 1.4.4 or higher |
11 | 11 | * Please report issues at: https://github.com/rstaib/jquery-steps/issues
|
12 | 12 | */
|
13 | 13 |
|
|
618 | 618 | $(".body:eq(" + index + ")", contentContainer).remove();
|
619 | 619 | $(".steps > ol > li:eq(" + index + ")", wizard).remove();
|
620 | 620 |
|
| 621 | + // Reset state values |
| 622 | + if (state.currentIndex > index) |
| 623 | + { |
| 624 | + state.currentIndex = state.currentIndex - 1; |
| 625 | + } |
| 626 | + state.stepCount--; |
| 627 | + state.currentStep = getStepProperties(wizard, state.currentIndex); |
| 628 | + |
| 629 | + // Set the "first" class to the new first step button |
621 | 630 | if (index === 0)
|
622 | 631 | {
|
623 |
| - $(".title:first", contentContainer).addClass("first"); |
| 632 | + $(".steps > ol > li:first", wizard).addClass("first"); |
624 | 633 | }
|
625 | 634 |
|
626 |
| - // Reset state values |
627 |
| - if (state.currentIndex >= index) |
| 635 | + // Set the "last" class to the new last step button |
| 636 | + if (index === state.stepCount) |
628 | 637 | {
|
629 |
| - state.currentIndex = state.currentIndex + 1; |
| 638 | + $(".steps > ol > li:eq(" + index + ")", wizard).addClass("last"); |
630 | 639 | }
|
631 |
| - state.stepCount = $(".body", contentContainer).length; |
632 |
| - state.currentStep = getStepProperties(wizard, state.currentIndex); |
633 | 640 |
|
634 | 641 | updateSteps(wizard, index);
|
635 | 642 | refreshActionState(wizard);
|
|
678 | 685 | }
|
679 | 686 |
|
680 | 687 | var contentContainer = wizard.children(".content"),
|
681 |
| - header = $(document.createElement(options.headerTag)), |
682 |
| - body = $(document.createElement(options.bodyTag)); |
683 |
| - if (index === 0) |
684 |
| - { |
685 |
| - contentContainer.prepend(body).prepend(header); |
686 |
| - } |
687 |
| - else |
| 688 | + header = $(document.createElement(options.headerTag)).html(step.title), |
| 689 | + body = $(document.createElement(options.bodyTag)).addClass("body").hide(); |
| 690 | + |
| 691 | + if (step.contentMode == null || step.contentMode === $.fn.steps.contentMode.html) |
688 | 692 | {
|
689 |
| - $(".body:eq(" + (index - 1) + ")", contentContainer).after(body).after(header); |
| 693 | + body.html(step.content); |
690 | 694 | }
|
691 | 695 |
|
692 |
| - header.html(step.title); |
693 |
| - transformTitle(wizard, header, index); |
694 |
| - |
695 |
| - // Add click event |
696 |
| - $(".steps > ol > li:eq(" + index + ") > a", wizard).bind("click.steps", stepClickHandler); |
697 |
| - |
698 |
| - // Reset the current class |
699 | 696 | if (index === 0)
|
700 | 697 | {
|
701 |
| - $(".steps > ol > li", wizard).removeClass("first").eq(index).addClass("first"); |
| 698 | + contentContainer.prepend(body).prepend(header); |
702 | 699 | }
|
703 |
| - |
704 |
| - body.addClass("body").hide(); |
705 |
| - if (step.contentMode == null || step.contentMode === $.fn.steps.contentMode.html) |
| 700 | + else |
706 | 701 | {
|
707 |
| - body.html(step.content); |
| 702 | + $(".body:eq(" + (index - 1) + ")", contentContainer).after(body).after(header); |
708 | 703 | }
|
709 | 704 |
|
710 | 705 | // Reset state values
|
711 | 706 | if (state.currentIndex >= index)
|
712 | 707 | {
|
713 | 708 | state.currentIndex = state.currentIndex + 1;
|
714 | 709 | }
|
715 |
| - state.stepCount = contentContainer.children(".body").length; |
| 710 | + state.stepCount++; |
| 711 | + |
| 712 | + transformTitle(wizard, header, index); |
| 713 | + |
716 | 714 | state.currentStep = getStepProperties(wizard, state.currentIndex);
|
717 | 715 |
|
| 716 | + // Add click event |
| 717 | + $(".steps > ol > li:eq(" + index + ") > a", wizard).bind("click.steps", stepClickHandler); |
| 718 | + |
718 | 719 | updateSteps(wizard, index);
|
719 | 720 | refreshActionState(wizard);
|
720 | 721 |
|
|
781 | 782 | **/
|
782 | 783 | function actionClick(wizard, index)
|
783 | 784 | {
|
784 |
| - var options = wizard.data("options"); |
785 |
| - var state = wizard.data("state"); |
786 |
| - var oldIndex = state.currentIndex; |
| 785 | + var options = wizard.data("options"), |
| 786 | + state = wizard.data("state"), |
| 787 | + oldIndex = state.currentIndex; |
787 | 788 |
|
788 | 789 | if (index >= 0 && index < state.stepCount && !(options.forceMoveForward && index < state.currentIndex))
|
789 | 790 | {
|
790 |
| - var anchor = $(".steps a[href$='-" + index + "']", wizard); |
791 |
| - var isDisabled = anchor.parent().hasClass("disabled"); |
| 791 | + var anchor = $(".steps a[href$='-" + index + "']", wizard), |
| 792 | + isDisabled = anchor.parent().hasClass("disabled"); |
792 | 793 | // Remove the class to make the anchor clickable!
|
793 | 794 | anchor.parent().removeClass("disabled");
|
794 | 795 | anchor.click();
|
|
818 | 819 | **/
|
819 | 820 | function goToStep(wizard, index)
|
820 | 821 | {
|
821 |
| - var options = wizard.data("options"); |
822 |
| - var state = wizard.data("state"); |
| 822 | + var options = wizard.data("options"), |
| 823 | + state = wizard.data("state"); |
823 | 824 |
|
824 | 825 | if (index < 0 || index >= state.stepCount || state.stepCount === 0)
|
825 | 826 | {
|
|
834 | 835 | var oldIndex = state.currentIndex;
|
835 | 836 | if (wizard.triggerHandler("stepChanging", [state.currentIndex, index]))
|
836 | 837 | {
|
837 |
| - if (state.asyncRequest != null) |
838 |
| - { |
839 |
| - state.asyncRequest.abort(); |
840 |
| - } |
841 |
| - |
842 | 838 | // Save new state
|
843 | 839 | state.currentIndex = index;
|
844 | 840 | state.currentStep = getStepProperties(wizard, index);
|
845 | 841 |
|
846 | 842 | // Change visualisation
|
847 |
| - var steps = $(".steps li", wizard), |
848 |
| - currentInfo = $("a > .current-info", steps.eq(oldIndex)); |
849 |
| - steps.eq(oldIndex).addClass("done").removeClass("current error"); |
850 |
| - steps.eq(index).addClass("current").removeClass("disabled done") |
851 |
| - .children("a").prepend(currentInfo).focus(); |
| 843 | + updateStepClasses(wizard, index, oldIndex); |
852 | 844 |
|
853 | 845 | refreshActionState(wizard);
|
854 | 846 | loadAsyncContent(wizard);
|
|
916 | 908 | }
|
917 | 909 |
|
918 | 910 | /**
|
919 |
| - * Transforms the initial html structure/code. |
| 911 | + * Transforms the hardcoded html structure to a new more useful html structure. |
920 | 912 | *
|
921 | 913 | * @private
|
922 | 914 | * @method transform
|
|
932 | 924 | wizard.addClass("wizard").empty().append(contentWrapper);
|
933 | 925 |
|
934 | 926 | var stepTitles = contentWrapper.children(options.headerTag),
|
935 |
| - stepContents = contentWrapper.children(options.bodyTag).addClass("body"); |
| 927 | + stepContents = contentWrapper.children(options.bodyTag).addClass("body").hide(); |
936 | 928 |
|
937 |
| - // hides all contents except the defined start content |
938 |
| - stepContents.not(":eq(" + options.startIndex + ")").hide(); |
| 929 | + // Make the start step visible |
939 | 930 | stepContents.eq(options.startIndex).show();
|
940 | 931 |
|
941 | 932 | if (stepTitles.length > stepContents.length)
|
|
947 | 938 | throw new Error("One or more corresponding step titles are missing.");
|
948 | 939 | }
|
949 | 940 |
|
| 941 | + state.stepCount = stepContents.length; |
| 942 | + |
950 | 943 | var stepsWrapper = $(document.createElement(options.stepsContainerTag))
|
951 | 944 | .addClass("steps").append($(document.createElement("ol")));
|
952 | 945 | wizard.prepend(stepsWrapper);
|
953 | 946 |
|
954 | 947 | stepTitles.each(function (index)
|
955 | 948 | {
|
956 | 949 | transformTitle(wizard, $(this), index);
|
| 950 | + |
| 951 | + if (index < options.startIndex) |
| 952 | + { |
| 953 | + $(".steps > ol > li:eq(" + index + ")", wizard).addClass("done"); |
| 954 | + } |
| 955 | + |
| 956 | + if (index > options.startIndex && !options.enableAllSteps) |
| 957 | + { |
| 958 | + $(".steps > ol > li:eq(" + index + ")", wizard).addClass("disabled"); |
| 959 | + } |
957 | 960 | });
|
958 | 961 |
|
959 |
| - // Set state values |
960 |
| - state.stepCount = stepContents.length; |
| 962 | + updateStepClasses(wizard, options.startIndex); |
| 963 | + |
961 | 964 | state.currentStep = getStepProperties(wizard, state.currentIndex);
|
962 | 965 |
|
963 | 966 | if (options.enablePagination)
|
|
994 | 997 | */
|
995 | 998 | function transformTitle(wizard, header, index)
|
996 | 999 | {
|
997 |
| - // TODO: Some code for currentand so on! |
998 |
| - |
999 |
| - var options = wizard.data("options"); |
1000 |
| - |
1001 | 1000 | header.attr("id", getUniqueId(wizard) + "-" + index).attr("tabindex", "-1").addClass("title");
|
1002 | 1001 |
|
1003 |
| - var title = renderTemplate(options.titleTemplate, { |
| 1002 | + var options = wizard.data("options"), |
| 1003 | + state = wizard.data("state"), |
| 1004 | + stepCollection = $(".steps > ol", wizard), |
| 1005 | + title = renderTemplate(options.titleTemplate, { |
1004 | 1006 | index: index + 1,
|
1005 | 1007 | title: header.html()
|
1006 | 1008 | }),
|
1007 | 1009 | stepItem = $("<li></li>").html("<a href=\"#" + header.attr("id") + "\">" + title + "</a>");
|
1008 | 1010 |
|
1009 | 1011 | if (index === 0)
|
1010 | 1012 | {
|
1011 |
| - stepItem.addClass("first"); |
1012 |
| - } |
1013 |
| - |
1014 |
| - if (index === options.startIndex) |
1015 |
| - { |
1016 |
| - stepItem.addClass("current").children("a").prepend("<span class=\"current-info\">" + |
1017 |
| - options.labels.current + " </span>"); |
| 1013 | + stepCollection.prepend(stepItem); |
1018 | 1014 | }
|
1019 |
| - |
1020 |
| - if (index < options.startIndex) |
| 1015 | + else |
1021 | 1016 | {
|
1022 |
| - stepItem.addClass("done"); |
| 1017 | + $("li:eq(" + (index - 1) + ")", stepCollection).after(stepItem); |
1023 | 1018 | }
|
1024 | 1019 |
|
1025 |
| - if (index > options.startIndex && !options.enableAllSteps) |
1026 |
| - { |
1027 |
| - stepItem.addClass("disabled"); |
1028 |
| - } |
1029 |
| - |
1030 |
| - var stepCollection = $(".steps > ol", wizard); |
| 1020 | + // Set the "first" class to the new first step button |
1031 | 1021 | if (index === 0)
|
1032 | 1022 | {
|
1033 |
| - stepCollection.prepend(stepItem); |
| 1023 | + $("li", stepCollection).removeClass("first").eq(index).addClass("first"); |
1034 | 1024 | }
|
1035 |
| - else |
| 1025 | + |
| 1026 | + // Set the "last" class to the new last step button |
| 1027 | + if (index === (state.stepCount - 1)) |
1036 | 1028 | {
|
1037 |
| - $("li:eq(" + (index - 1) + ")", stepCollection).after(stepItem); |
| 1029 | + $("li", stepCollection).removeClass("last").eq(index).addClass("last"); |
1038 | 1030 | }
|
1039 | 1031 | }
|
1040 | 1032 |
|
|
1074 | 1066 | }
|
1075 | 1067 |
|
1076 | 1068 | /**
|
1077 |
| - * Updates step buttons and their related titles. |
| 1069 | + * Updates step buttons and their related titles beyond a certain position. |
1078 | 1070 | *
|
1079 | 1071 | * @private
|
1080 | 1072 | * @method updateSteps
|
|
1094 | 1086 | }
|
1095 | 1087 |
|
1096 | 1088 | /**
|
1097 |
| - * Refreshs the action navigation. |
| 1089 | + * Updates step button classes after initialization or step changing. |
| 1090 | + * |
| 1091 | + * @private |
| 1092 | + * @method updateStepClasses |
| 1093 | + * @param wizard {Object} A jQuery wizard object |
| 1094 | + * @param index {Integer} The index of the new current step |
| 1095 | + * @param [oldIndex] {Integer} The index of the prior step |
| 1096 | + */ |
| 1097 | + function updateStepClasses(wizard, index, oldIndex) |
| 1098 | + { |
| 1099 | + var options = wizard.data("options"), |
| 1100 | + steps = $(".steps li", wizard), |
| 1101 | + currentOrNewStep = steps.eq(index), |
| 1102 | + currentInfo = $("<span class=\"current-info\">" + options.labels.current + " </span>"); |
| 1103 | + |
| 1104 | + if (oldIndex != null) |
| 1105 | + { |
| 1106 | + var oldStep = steps.eq(oldIndex).addClass("done").removeClass("current error"); |
| 1107 | + currentInfo = $("a > .current-info", oldStep); |
| 1108 | + currentOrNewStep.focus(); |
| 1109 | + } |
| 1110 | + |
| 1111 | + currentOrNewStep.addClass("current").removeClass("disabled done").children("a").prepend(currentInfo); |
| 1112 | + } |
| 1113 | + |
| 1114 | + /** |
| 1115 | + * Refreshs the visualization for the complete action navigation. |
1098 | 1116 | *
|
1099 | 1117 | * @private
|
1100 | 1118 | * @method refreshActionState
|
|
1167 | 1185 | }
|
1168 | 1186 |
|
1169 | 1187 | /**
|
1170 |
| - * Renders a template and substitutes all placeholder. |
| 1188 | + * Renders a template and replaces all placeholder. |
1171 | 1189 | *
|
1172 | 1190 | * @private
|
1173 | 1191 | * @method renderTemplate
|
|
1223 | 1241 | header = $(".content > .title:eq(" + index + ")", wizard),
|
1224 | 1242 | content = header.next(".body"),
|
1225 | 1243 | mode = (content.data("mode") == null) ? $.fn.steps.contentMode.html :
|
1226 |
| - getValidEnumValue($.fn.steps.contentMode, (/^\s*$/.test(content.data("mode")) || isNaN(content.data("mode"))) ? |
1227 |
| - content.data("mode") : Number(content.data("mode"))), |
| 1244 | + getValidEnumValue($.fn.steps.contentMode, (/^\s*$/.test(content.data("mode")) || isNaN(content.data("mode"))) ? |
| 1245 | + content.data("mode") : Number(content.data("mode"))), |
1228 | 1246 | contentUrl = (mode === $.fn.steps.contentMode.html || content.data("url") === undefined) ?
|
1229 | 1247 | "" : content.data("url"),
|
1230 | 1248 | contentLoaded = (mode !== $.fn.steps.contentMode.html && content.data("loaded") === "1");
|
|
0 commit comments