348 lines
16 KiB
JavaScript
348 lines
16 KiB
JavaScript
|
|
/*
|
||
|
|
* SmartWizard 2.0 plugin
|
||
|
|
* jQuery Wizard control Plugin
|
||
|
|
* by Dipu
|
||
|
|
*
|
||
|
|
* http://www.techlaboratory.net
|
||
|
|
* http://tech-laboratory.blogspot.com
|
||
|
|
*/
|
||
|
|
|
||
|
|
(function($){
|
||
|
|
$.fn.smartWizard = function(action) {
|
||
|
|
var options = $.extend({}, $.fn.smartWizard.defaults, action);
|
||
|
|
var args = arguments;
|
||
|
|
|
||
|
|
return this.each(function(){
|
||
|
|
var obj = $(this);
|
||
|
|
var curStepIdx = options.selected;
|
||
|
|
var steps = $("ul > li > a[href^='#step-']", obj); // Get all anchors in this array
|
||
|
|
var contentWidth = 0;
|
||
|
|
var loader,msgBox,elmActionBar,elmStepContainer,btNext,btPrevious,btFinish;
|
||
|
|
|
||
|
|
elmActionBar = $('.actionBar',obj);
|
||
|
|
if(elmActionBar.length == 0){
|
||
|
|
elmActionBar = $('<div></div>').addClass("actionBar");
|
||
|
|
}
|
||
|
|
|
||
|
|
msgBox = $('.msgBox',obj);
|
||
|
|
if(msgBox.length == 0){
|
||
|
|
msgBox = $('<div class="msgBox"><div class="content"></div><a href="#" class="close">X</a></div>');
|
||
|
|
elmActionBar.append(msgBox);
|
||
|
|
}
|
||
|
|
|
||
|
|
$('.close',msgBox).click(function() {
|
||
|
|
msgBox.fadeOut("normal");
|
||
|
|
return false;
|
||
|
|
});
|
||
|
|
|
||
|
|
|
||
|
|
// Method calling logic
|
||
|
|
if (!action || action === 'init' || typeof action === 'object') {
|
||
|
|
init();
|
||
|
|
}else if (action === 'showMessage') {
|
||
|
|
//showMessage(Array.prototype.slice.call( args, 1 ));
|
||
|
|
var ar = Array.prototype.slice.call( args, 1 );
|
||
|
|
showMessage(ar[0]);
|
||
|
|
return true;
|
||
|
|
}else if (action === 'setError') {
|
||
|
|
var ar = Array.prototype.slice.call( args, 1 );
|
||
|
|
setError(ar[0].stepnum,ar[0].iserror);
|
||
|
|
return true;
|
||
|
|
} else {
|
||
|
|
$.error( 'Method ' + action + ' does not exist' );
|
||
|
|
}
|
||
|
|
|
||
|
|
function init(){
|
||
|
|
var allDivs =obj.children('div'); //$("div", obj);
|
||
|
|
obj.children('ul').addClass("anchor");
|
||
|
|
allDivs.addClass("content");
|
||
|
|
// Create Elements
|
||
|
|
loader = $('<div>Loading</div>').addClass("loader");
|
||
|
|
elmActionBar = $('<div></div>').addClass("actionBar");
|
||
|
|
elmStepContainer = $('<div></div>').addClass("stepContainer");
|
||
|
|
btNext = $('<a>'+options.labelNext+'</a>').attr("href","#").addClass("buttonNext");
|
||
|
|
btPrevious = $('<a>'+options.labelPrevious+'</a>').attr("href","#").addClass("buttonPrevious");
|
||
|
|
btFinish = $('<a>'+options.labelFinish+'</a>').attr("href","#").addClass("buttonFinish");
|
||
|
|
// highlight steps with errors
|
||
|
|
if(options.errorSteps && options.errorSteps.length>0){
|
||
|
|
$.each(options.errorSteps, function(i, n){
|
||
|
|
setError(n,true);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
elmStepContainer.append(allDivs);
|
||
|
|
elmActionBar.append(loader);
|
||
|
|
obj.append(elmStepContainer);
|
||
|
|
obj.append(elmActionBar);
|
||
|
|
if (options.includeFinishButton) {
|
||
|
|
elmActionBar.append(btFinish);
|
||
|
|
}
|
||
|
|
elmActionBar.append(btNext).append(btPrevious);
|
||
|
|
contentWidth = elmStepContainer.width();
|
||
|
|
|
||
|
|
$(btNext).click(function() {
|
||
|
|
if($(this).hasClass('buttonDisabled')){
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
if(checkDate(curStepIdx+1)){
|
||
|
|
doForwardProgress();
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
});
|
||
|
|
$(btPrevious).click(function() {
|
||
|
|
if($(this).hasClass('buttonDisabled')){
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
doBackwardProgress();
|
||
|
|
return false;
|
||
|
|
});
|
||
|
|
$(btFinish).click(function() {
|
||
|
|
if(!$(this).hasClass('buttonDisabled')){
|
||
|
|
if($.isFunction(options.onFinish)) {
|
||
|
|
if(!options.onFinish.call(this,$(steps))){
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}else{
|
||
|
|
var frm = obj.parents('form');
|
||
|
|
if(frm && frm.length){
|
||
|
|
frm.submit();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return false;
|
||
|
|
});
|
||
|
|
|
||
|
|
$(steps).bind("click", function(e){
|
||
|
|
if(steps.index(this) == curStepIdx){
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
var nextStepIdx = steps.index(this);
|
||
|
|
var isDone = steps.eq(nextStepIdx).attr("isDone") - 0;
|
||
|
|
if(isDone == 1){
|
||
|
|
LoadContent(nextStepIdx);
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
});
|
||
|
|
|
||
|
|
// Enable keyboard navigation
|
||
|
|
if(options.keyNavigation){
|
||
|
|
$(document).keyup(function(e){
|
||
|
|
if(e.which==39){ // Right Arrow
|
||
|
|
doForwardProgress();
|
||
|
|
}else if(e.which==37){ // Left Arrow
|
||
|
|
doBackwardProgress();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
// Prepare the steps
|
||
|
|
prepareSteps();
|
||
|
|
// Show the first slected step
|
||
|
|
LoadContent(curStepIdx);
|
||
|
|
}
|
||
|
|
|
||
|
|
function prepareSteps(){
|
||
|
|
if(!options.enableAllSteps){
|
||
|
|
$(steps, obj).removeClass("selected").removeClass("done").addClass("disabled");
|
||
|
|
$(steps, obj).attr("isDone",0);
|
||
|
|
}else{
|
||
|
|
$(steps, obj).removeClass("selected").removeClass("disabled").addClass("done");
|
||
|
|
$(steps, obj).attr("isDone",1);
|
||
|
|
}
|
||
|
|
|
||
|
|
$(steps, obj).each(function(i){
|
||
|
|
$($(this).attr("href"), obj).hide();
|
||
|
|
$(this).attr("rel",i+1);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
function LoadContent(stepIdx){
|
||
|
|
var selStep = steps.eq(stepIdx);
|
||
|
|
var ajaxurl = options.contentURL;
|
||
|
|
var hasContent = selStep.data('hasContent');
|
||
|
|
stepNum = stepIdx+1;
|
||
|
|
if(ajaxurl && ajaxurl.length>0){
|
||
|
|
if(options.contentCache && hasContent){
|
||
|
|
showStep(stepIdx);
|
||
|
|
}else{
|
||
|
|
$.ajax({
|
||
|
|
url: ajaxurl,
|
||
|
|
type: "POST",
|
||
|
|
data: ({step_number : stepNum}),
|
||
|
|
dataType: "text",
|
||
|
|
beforeSend: function(){ loader.show(); },
|
||
|
|
error: function(){loader.hide();},
|
||
|
|
success: function(res){
|
||
|
|
loader.hide();
|
||
|
|
if(res && res.length>0){
|
||
|
|
selStep.data('hasContent',true);
|
||
|
|
$($(selStep, obj).attr("href"), obj).html(res);
|
||
|
|
showStep(stepIdx);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}else{
|
||
|
|
showStep(stepIdx);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function showStep(stepIdx){
|
||
|
|
var selStep = steps.eq(stepIdx);
|
||
|
|
var curStep = steps.eq(curStepIdx);
|
||
|
|
if(stepIdx != curStepIdx){
|
||
|
|
if($.isFunction(options.onLeaveStep)) {
|
||
|
|
if(!options.onLeaveStep.call(this,$(curStep))){
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (options.updateHeight)
|
||
|
|
elmStepContainer.height($($(selStep, obj).attr("href"), obj).outerHeight());
|
||
|
|
if(options.transitionEffect == 'slide'){
|
||
|
|
$($(curStep, obj).attr("href"), obj).slideUp("fast",function(e){
|
||
|
|
$($(selStep, obj).attr("href"), obj).slideDown("fast");
|
||
|
|
curStepIdx = stepIdx;
|
||
|
|
SetupStep(curStep,selStep);
|
||
|
|
});
|
||
|
|
} else if(options.transitionEffect == 'fade'){
|
||
|
|
$($(curStep, obj).attr("href"), obj).fadeOut("fast",function(e){
|
||
|
|
$($(selStep, obj).attr("href"), obj).fadeIn("fast");
|
||
|
|
curStepIdx = stepIdx;
|
||
|
|
SetupStep(curStep,selStep);
|
||
|
|
});
|
||
|
|
} else if(options.transitionEffect == 'slideleft'){
|
||
|
|
var nextElmLeft = 0;
|
||
|
|
var curElementLeft = 0;
|
||
|
|
if(stepIdx > curStepIdx){
|
||
|
|
nextElmLeft1 = contentWidth + 10;
|
||
|
|
nextElmLeft2 = 0;
|
||
|
|
curElementLeft = 0 - $($(curStep, obj).attr("href"), obj).outerWidth();
|
||
|
|
} else {
|
||
|
|
nextElmLeft1 = 0 - $($(selStep, obj).attr("href"), obj).outerWidth() + 20;
|
||
|
|
nextElmLeft2 = 0;
|
||
|
|
curElementLeft = 10 + $($(curStep, obj).attr("href"), obj).outerWidth();
|
||
|
|
}
|
||
|
|
if(stepIdx == curStepIdx){
|
||
|
|
nextElmLeft1 = $($(selStep, obj).attr("href"), obj).outerWidth() + 20;
|
||
|
|
nextElmLeft2 = 0;
|
||
|
|
curElementLeft = 0 - $($(curStep, obj).attr("href"), obj).outerWidth();
|
||
|
|
}else{
|
||
|
|
$($(curStep, obj).attr("href"), obj).animate({left:curElementLeft},"fast",function(e){
|
||
|
|
$($(curStep, obj).attr("href"), obj).hide();
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
$($(selStep, obj).attr("href"), obj).css("left",nextElmLeft1);
|
||
|
|
$($(selStep, obj).attr("href"), obj).show();
|
||
|
|
$($(selStep, obj).attr("href"), obj).animate({left:nextElmLeft2},"fast",function(e){
|
||
|
|
curStepIdx = stepIdx;
|
||
|
|
SetupStep(curStep,selStep);
|
||
|
|
});
|
||
|
|
} else{
|
||
|
|
$($(curStep, obj).attr("href"), obj).hide();
|
||
|
|
$($(selStep, obj).attr("href"), obj).show();
|
||
|
|
curStepIdx = stepIdx;
|
||
|
|
SetupStep(curStep,selStep);
|
||
|
|
}
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
function SetupStep(curStep,selStep){
|
||
|
|
$(curStep, obj).removeClass("selected");
|
||
|
|
$(curStep, obj).addClass("done");
|
||
|
|
|
||
|
|
$(selStep, obj).removeClass("disabled");
|
||
|
|
$(selStep, obj).removeClass("done");
|
||
|
|
$(selStep, obj).addClass("selected");
|
||
|
|
$(selStep, obj).attr("isDone",1);
|
||
|
|
adjustButton();
|
||
|
|
if($.isFunction(options.onShowStep)) {
|
||
|
|
if(!options.onShowStep.call(this,$(selStep))){
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function doForwardProgress(){
|
||
|
|
var nextStepIdx = curStepIdx + 1;
|
||
|
|
if(steps.length <= nextStepIdx){
|
||
|
|
if(!options.cycleSteps){
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
nextStepIdx = 0;
|
||
|
|
}
|
||
|
|
LoadContent(nextStepIdx);
|
||
|
|
}
|
||
|
|
|
||
|
|
function doBackwardProgress(){
|
||
|
|
var nextStepIdx = curStepIdx-1;
|
||
|
|
if(0 > nextStepIdx){
|
||
|
|
if(!options.cycleSteps){
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
nextStepIdx = steps.length - 1;
|
||
|
|
}
|
||
|
|
LoadContent(nextStepIdx);
|
||
|
|
}
|
||
|
|
|
||
|
|
function adjustButton(){
|
||
|
|
if(!options.cycleSteps){
|
||
|
|
if(0 >= curStepIdx){
|
||
|
|
$(btPrevious).addClass("buttonDisabled");
|
||
|
|
}else{
|
||
|
|
$(btPrevious).removeClass("buttonDisabled");
|
||
|
|
}
|
||
|
|
if((steps.length-1) <= curStepIdx){
|
||
|
|
$(btNext).addClass("buttonDisabled");
|
||
|
|
}else{
|
||
|
|
$(btNext).removeClass("buttonDisabled");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
// Finish Button
|
||
|
|
if(!steps.hasClass('disabled') || options.enableFinishButton){
|
||
|
|
$(btFinish).removeClass("buttonDisabled");
|
||
|
|
}else{
|
||
|
|
$(btFinish).addClass("buttonDisabled");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function showMessage(msg){
|
||
|
|
$('.content',msgBox).html(msg);
|
||
|
|
msgBox.show();
|
||
|
|
}
|
||
|
|
|
||
|
|
function setError(stepnum,iserror){
|
||
|
|
if(iserror){
|
||
|
|
$(steps.eq(stepnum-1), obj).addClass('error')
|
||
|
|
}else{
|
||
|
|
$(steps.eq(stepnum-1), obj).removeClass("error");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
});
|
||
|
|
};
|
||
|
|
|
||
|
|
// Default Properties and Events
|
||
|
|
$.fn.smartWizard.defaults = {
|
||
|
|
selected: 0, // Selected Step, 0 = first step
|
||
|
|
keyNavigation: true, // Enable/Disable key navigation(left and right keys are used if enabled)
|
||
|
|
enableAllSteps: false,
|
||
|
|
updateHeight: true,
|
||
|
|
transitionEffect: 'fade', // Effect on navigation, none/fade/slide/slideleft
|
||
|
|
contentURL:null, // content url, Enables Ajax content loading
|
||
|
|
contentCache:true, // cache step contents, if false content is fetched always from ajax url
|
||
|
|
cycleSteps: false, // cycle step navigation
|
||
|
|
includeFinishButton: true, // whether to show a Finish button
|
||
|
|
enableFinishButton: false, // make finish button enabled always
|
||
|
|
errorSteps:[], // Array Steps with errors
|
||
|
|
labelNext:'下一步',
|
||
|
|
labelPrevious:'上一步',
|
||
|
|
labelFinish:'完成',
|
||
|
|
onLeaveStep: null, // triggers when leaving a step
|
||
|
|
onShowStep: null, // triggers when showing a step
|
||
|
|
onFinish: null // triggers when Finish button is clicked
|
||
|
|
};
|
||
|
|
|
||
|
|
})(jQuery);
|