14 function SmartWizard(target, options) {
16 this.options = options;
17 this.curStepIdx = options.selected;
18 this.steps = $(target).children(
"ul").children(
"li").children(
"a");
19 this.contentWidth = 0;
20 this.msgBox = $(
'<div class="msgBox"><div class="content"></div><a href="#" class="close">X</a></div>');
21 this.elmStepContainer = $(
'<div></div>').addClass(
"stepContainer");
22 this.loader = $(
'<div>Loading</div>').addClass(
"loader");
24 next : $(
'<a>'+options.labelNext+
'</a>').attr(
"href",
"#").addClass(
"btn btn-success"),
25 previous : $(
'<a>'+options.labelPrevious+
'</a>').attr(
"href",
"#").addClass(
"btn btn-primary"),
26 finish : $(
'<a>'+options.labelFinish+
'</a>').attr(
"href",
"#").addClass(
"btn btn-default")
33 var _init =
function($this) {
34 var elmActionBar = $(
'<div></div>').addClass(
"actionBar");
36 $(
'.close',$this.msgBox).click(
function() {
37 $this.msgBox.fadeOut(
"normal");
41 var allDivs = $this.target.children(
'div');
43 if($this.target.children(
'ul').length == 0 ){
48 allDivs.each(
function(i,e){
49 var title = $(e).first().children(
".StepTitle").text();
50 var s = $(e).attr(
"id")
56 var span = $(
"<span/>").addClass(
"stepDesc").text(title);
57 var li = $(
"<li></li>").append($(
"<a></a>").attr(
"href",
"#" + s).append($(
"<label></label>").addClass(
"stepNumber").text(i + 1)).append(span));
61 $this.steps = $(target).children(
"ul").children(
"li").children(
"a");
63 $this.target.children(
'ul').addClass(
"anchor");
64 allDivs.addClass(
"wizard_content");
67 if($this.options.errorSteps && $this.options.errorSteps.length>0){
68 $.each($this.options.errorSteps,
function(i, n){
69 $this.setError({ stepnum: n, iserror:
true });
73 $this.elmStepContainer.append(allDivs);
75 $this.target.append($this.elmStepContainer);
77 if ($this.options.includeFinishButton){
78 elmActionBar.append($this.buttons.finish)
81 elmActionBar.append($this.buttons.next)
82 .append($this.buttons.previous);
83 $this.target.append(elmActionBar);
84 this.contentWidth = $this.elmStepContainer.width();
86 $($this.buttons.next).click(
function() {
90 $($this.buttons.previous).click(
function() {
94 $($this.buttons.finish).click(
function() {
95 if(!$(
this).hasClass(
'buttonDisabled')){
96 if($.isFunction($this.options.onFinish)) {
97 var context = { fromStep: $this.curStepIdx + 1 };
98 if(!$this.options.onFinish.call(
this,$($this.steps), context)){
102 var frm = $this.target.parents(
'form');
103 if(frm && frm.length){
111 $($this.steps).bind(
"click",
function(e){
112 if($this.steps.index(
this) == $this.curStepIdx){
115 var nextStepIdx = $this.steps.index(
this);
116 var isDone = $this.steps.eq(nextStepIdx).attr(
"isDone") - 0;
118 _loadContent($this, nextStepIdx);
124 if($this.options.keyNavigation){
125 $(document).keyup(
function(e){
128 }
else if(e.which==37){
134 _prepareSteps($this);
136 _loadContent($this, $this.curStepIdx);
139 var _prepareSteps =
function($this) {
140 if(! $this.options.enableAllSteps){
141 $($this.steps, $this.target).removeClass(
"selected").removeClass(
"done").addClass(
"disabled");
142 $($this.steps, $this.target).attr(
"isDone",0);
144 $($this.steps, $this.target).removeClass(
"selected").removeClass(
"disabled").addClass(
"done");
145 $($this.steps, $this.target).attr(
"isDone",1);
148 $($this.steps, $this.target).each(
function(i){
149 $($(
this).attr(
"href").replace(/^.+#/,
'#'), $this.target).hide();
150 $(
this).attr(
"rel",i+1);
154 var _step =
function ($this, selStep) {
156 $(selStep, $this.target).attr(
"href").replace(/^.+#/,
'#'),
161 var _loadContent =
function($this, stepIdx) {
162 var selStep = $this.steps.eq(stepIdx);
163 var ajaxurl = $this.options.contentURL;
164 var ajaxurl_data = $this.options.contentURLData;
165 var hasContent = selStep.data(
'hasContent');
166 var stepNum = stepIdx+1;
167 if (ajaxurl && ajaxurl.length>0) {
168 if ($this.options.contentCache && hasContent) {
169 _showStep($this, stepIdx);
173 type: $this.options.ajaxType,
174 data: ({step_number : stepNum}),
176 beforeSend:
function(){
182 success:
function(res){
184 if(res && res.length>0){
185 selStep.data(
'hasContent',
true);
186 _step($this, selStep).html(res);
187 _showStep($this, stepIdx);
192 ajax_args = $.extend(ajax_args, ajaxurl_data(stepNum));
197 _showStep($this,stepIdx);
201 var _showStep =
function($this, stepIdx) {
202 var selStep = $this.steps.eq(stepIdx);
203 var curStep = $this.steps.eq($this.curStepIdx);
204 if(stepIdx != $this.curStepIdx){
205 if($.isFunction($this.options.onLeaveStep)) {
206 var context = { fromStep: $this.curStepIdx+1, toStep: stepIdx+1 };
207 if (! $this.options.onLeaveStep.call($this,$(curStep), context)){
213 var prevCurStepIdx = $this.curStepIdx;
214 $this.curStepIdx = stepIdx;
215 if ($this.options.transitionEffect ==
'slide'){
216 _step($this, curStep).slideUp(
"fast",
function(e){
217 _step($this, selStep).slideDown(
"fast");
218 _setupStep($this,curStep,selStep);
220 }
else if ($this.options.transitionEffect ==
'fade'){
221 _step($this, curStep).fadeOut(
"fast",
function(e){
222 _step($this, selStep).fadeIn(
"fast");
223 _setupStep($this,curStep,selStep);
225 }
else if ($this.options.transitionEffect ==
'slideleft'){
227 var nextElmLeft1 = null;
228 var nextElmLeft = null;
229 var curElementLeft = 0;
230 if(stepIdx > prevCurStepIdx){
231 nextElmLeft1 = $this.elmStepContainer.width() + 10;
233 curElementLeft = 0 - _step($this, curStep).outerWidth();
235 nextElmLeft1 = 0 - _step($this, selStep).outerWidth() + 20;
237 curElementLeft = 10 + _step($this, curStep).outerWidth();
239 if (stepIdx == prevCurStepIdx) {
240 nextElmLeft1 = $($(selStep, $this.target).attr(
"href"), $this.target).outerWidth() + 20;
242 curElementLeft = 0 - $($(curStep, $this.target).attr(
"href"), $this.target).outerWidth();
244 $($(curStep, $this.target).attr(
"href"), $this.target).animate({left:curElementLeft},
"fast",
function(e){
245 $($(curStep, $this.target).attr(
"href"), $this.target).hide();
249 _step($this, selStep).css(
"left",nextElmLeft1).show().animate({left:nextElmLeft2},
"fast",
function(e){
250 _setupStep($this,curStep,selStep);
253 _step($this, curStep).hide();
254 _step($this, selStep).show();
255 _setupStep($this,curStep,selStep);
260 var _setupStep =
function($this, curStep, selStep) {
261 $(curStep, $this.target).removeClass(
"selected");
262 $(curStep, $this.target).addClass(
"done");
264 $(selStep, $this.target).removeClass(
"disabled");
265 $(selStep, $this.target).removeClass(
"done");
266 $(selStep, $this.target).addClass(
"selected");
268 $(selStep, $this.target).attr(
"isDone",1);
270 _adjustButton($this);
272 if($.isFunction($this.options.onShowStep)) {
273 var context = { fromStep: parseInt($(curStep).attr(
'rel')), toStep: parseInt($(selStep).attr(
'rel')) };
274 if(! $this.options.onShowStep.call(
this,$(selStep),context)){
278 if ($this.options.noForwardJumping) {
280 for (var i = $this.curStepIdx + 2; i <= $this.steps.length; i++) {
281 $this.disableStep(i);
286 var _adjustButton =
function($this) {
287 if (! $this.options.cycleSteps){
288 if (0 >= $this.curStepIdx) {
289 $($this.buttons.previous).addClass(
"buttonDisabled");
290 if ($this.options.hideButtonsOnDisabled) {
291 $($this.buttons.previous).hide();
294 $($this.buttons.previous).removeClass(
"buttonDisabled");
295 if ($this.options.hideButtonsOnDisabled) {
296 $($this.buttons.previous).show();
299 if (($this.steps.length-1) <= $this.curStepIdx){
300 $($this.buttons.next).addClass(
"buttonDisabled");
301 if ($this.options.hideButtonsOnDisabled) {
302 $($this.buttons.next).hide();
305 $($this.buttons.next).removeClass(
"buttonDisabled");
306 if ($this.options.hideButtonsOnDisabled) {
307 $($this.buttons.next).show();
312 $this.enableFinish($this.options.enableFinishButton);
319 SmartWizard.prototype.goForward =
function(){
320 var nextStepIdx = this.curStepIdx + 1;
321 if (this.steps.length <= nextStepIdx){
322 if (! this.options.cycleSteps){
327 _loadContent(
this, nextStepIdx);
330 SmartWizard.prototype.goBackward =
function(){
331 var nextStepIdx = this.curStepIdx-1;
332 if (0 > nextStepIdx){
333 if (! this.options.cycleSteps){
336 nextStepIdx = this.steps.length - 1;
338 _loadContent(
this, nextStepIdx);
341 SmartWizard.prototype.goToStep =
function(stepNum){
342 var stepIdx = stepNum - 1;
343 if (stepIdx >= 0 && stepIdx < this.steps.length) {
344 _loadContent(
this, stepIdx);
347 SmartWizard.prototype.enableStep =
function(stepNum) {
348 var stepIdx = stepNum - 1;
349 if (stepIdx == this.curStepIdx || stepIdx < 0 || stepIdx >= this.steps.length) {
352 var step = this.steps.eq(stepIdx);
353 $(step, this.target).attr(
"isDone",1);
354 $(step, this.target).removeClass(
"disabled").removeClass(
"selected").addClass(
"done");
356 SmartWizard.prototype.disableStep =
function(stepNum) {
357 var stepIdx = stepNum - 1;
358 if (stepIdx == this.curStepIdx || stepIdx < 0 || stepIdx >= this.steps.length) {
361 var step = this.steps.eq(stepIdx);
362 $(step, this.target).attr(
"isDone",0);
363 $(step, this.target).removeClass(
"done").removeClass(
"selected").addClass(
"disabled");
365 SmartWizard.prototype.currentStep =
function() {
366 return this.curStepIdx + 1;
369 SmartWizard.prototype.showMessage =
function (msg) {
370 $(
'.content', this.msgBox).html(msg);
374 SmartWizard.prototype.enableFinish =
function (enable) {
377 this.options.enableFinishButton = enable;
378 if (this.options.includeFinishButton){
379 if (!this.steps.hasClass(
'disabled') || this.options.enableFinishButton){
380 $(this.buttons.finish).removeClass(
"buttonDisabled");
381 if (this.options.hideButtonsOnDisabled) {
382 $(this.buttons.finish).show();
385 $(this.buttons.finish).addClass(
"buttonDisabled");
386 if (this.options.hideButtonsOnDisabled) {
387 $(this.buttons.finish).hide();
391 return this.options.enableFinishButton;
394 SmartWizard.prototype.hideMessage =
function () {
395 this.msgBox.fadeOut(
"normal");
397 SmartWizard.prototype.showError =
function(stepnum) {
398 this.setError(stepnum,
true);
400 SmartWizard.prototype.hideError =
function(stepnum) {
401 this.setError(stepnum,
false);
403 SmartWizard.prototype.setError =
function(stepnum,iserror) {
404 if (typeof stepnum ==
"object") {
405 iserror = stepnum.iserror;
406 stepnum = stepnum.stepnum;
410 $(this.steps.eq(stepnum-1), this.target).addClass(
'error')
412 $(this.steps.eq(stepnum-1), this.target).removeClass(
"error");
416 SmartWizard.prototype.fixHeight =
function(){
419 var selStep = this.steps.eq(this.curStepIdx);
420 var stepContainer = _step(
this, selStep);
421 stepContainer.children().each(
function() {
422 if($(
this).is(
':visible')) {
423 height += $(
this).outerHeight(
true);
428 stepContainer.height(height + 5);
429 this.elmStepContainer.height(height + 20);
439 $.fn.smartWizard =
function(method) {
440 var args = arguments;
442 var allObjs = this.each(
function() {
443 var wiz = $(
this).data(
'smartWizard');
444 if (typeof method ==
'object' || ! method || ! wiz) {
445 var options = $.extend({}, $.fn.smartWizard.defaults, method || {});
447 wiz =
new SmartWizard($(
this), options);
448 $(
this).data(
'smartWizard', wiz);
451 if (typeof SmartWizard.prototype[method] ==
"function") {
452 rv = SmartWizard.prototype[method].apply(wiz, Array.prototype.slice.call(args, 1));
455 $.error(
'Method ' + method +
' does not exist on jQuery.smartWizard');
459 if (rv === undefined) {
467 $.fn.smartWizard.defaults = {
470 enableAllSteps:
false,
471 transitionEffect:
'fade',
475 enableFinishButton:
false,
476 hideButtonsOnDisabled:
false,
479 labelPrevious:
'Previous',
480 labelFinish:
'Finish',
481 noForwardJumping:
false,
486 includeFinishButton :
true