drhenner/ror_ecommerce

View on GitHub
app/assets/javascripts/jqwizard/jquery.form.wizard.js

Summary

Maintainability
C
1 day
Test Coverage
/*
 * jQuery wizard plug-in 3.0.5
 *
 *
 * Copyright (c) 2011 Jan Sundman (jan.sundman[at]aland.net)
 *
 * http://www.thecodemine.org
 *
 * Licensed under the MIT licens:
 *   http://www.opensource.org/licenses/mit-license.php
 *
 */


(function($){
    $.widget("ui.formwizard", {

        _init: function() {

            var wizard = this;
            var formOptionsSuccess = this.options.formOptions.success;
            var formOptionsComplete = this.options.formOptions.complete;
            var formOptionsBeforeSend = this.options.formOptions.beforeSend;
            var formOptionsBeforeSubmit = this.options.formOptions.beforeSubmit;
            var formOptionsBeforeSerialize = this.options.formOptions.beforeSerialize;
            this.options.formOptions = $.extend(this.options.formOptions,{
                success    : function(responseText, textStatus, xhr){
                    if(formOptionsSuccess){
                        formOptionsSuccess(responseText, textStatus, xhr);
                    }
                    if(wizard.options.formOptions && wizard.options.formOptions.resetForm || !wizard.options.formOptions){
                        wizard._reset();
                    }
                },
                complete : function(xhr, textStatus){
                    if(formOptionsComplete){
                        formOptionsComplete(xhr, textStatus);
                    }
                    wizard._enableNavigation();
                },
                beforeSubmit : function(arr, theForm, options) {
                    if(formOptionsBeforeSubmit){
                        var shouldSubmit = formOptionsBeforeSubmit(arr, theForm, options);
                        if(!shouldSubmit)
                            wizard._enableNavigation();
                        return shouldSubmit;
                    }
                },
                beforeSend : function(xhr) {
                    if(formOptionsBeforeSend){
                        var shouldSubmit = formOptionsBeforeSend(xhr);
                        if(!shouldSubmit)
                            wizard._enableNavigation();
                        return shouldSubmit;
                    }
                },
                beforeSerialize: function(form, options) {
                    if(formOptionsBeforeSerialize){
                        var shouldSubmit = formOptionsBeforeSerialize(form, options);
                        if(!shouldSubmit)
                            wizard._enableNavigation();
                        return shouldSubmit;
                    }
                }
            });

            this.steps = this.element.find(".step").hide();

            this.firstStep = this.steps.eq(0).attr("id");
            this.activatedSteps = new Array();
            this.isLastStep = false;
            this.previousStep = undefined;
            this.currentStep = this.steps.eq(0).attr("id");
            this.nextButton    = this.element.find(this.options.next)
                    .click(function() {
                        return wizard._next();
                    });

            this.nextButtonInitinalValue = this.nextButton.val();
            this.nextButton.val(this.options.textNext);

                this.backButton    = this.element.find(this.options.back)
                    .click(function() {
                        wizard._back();return false;
                    });

                this.backButtonInitinalValue = this.backButton.val();
                this.backButton.val(this.options.textBack);

            if(this.options.validationEnabled && jQuery().validate  == undefined){
                this.options.validationEnabled = false;
                if( (window['console'] !== undefined) ){
                    console.log("%s", "validationEnabled option set, but the validation plugin is not included");
                }
            }else if(this.options.validationEnabled){
                this.element.validate(this.options.validationOptions);
            }
            if(this.options.formPluginEnabled && jQuery().ajaxSubmit == undefined){
                this.options.formPluginEnabled = false;
                if( (window['console'] !== undefined) ){
                    console.log("%s", "formPluginEnabled option set but the form plugin is not included");
                }
            }

            if(this.options.disableInputFields == true){
                $(this.steps).find(":input:not('.wizard-ignore')").attr("disabled","disabled");
            }

            if(this.options.historyEnabled){
                $(window).bind('hashchange', undefined, function(event){
                    var hashStep = event.getState( "_" + $(wizard.element).attr( 'id' )) || wizard.firstStep;
                    if(hashStep !== wizard.currentStep){
                        if(wizard.options.validationEnabled && hashStep === wizard._navigate(wizard.currentStep)){
                            if(!wizard.element.valid()){
                                wizard._updateHistory(wizard.currentStep);
                                wizard.element.validate().focusInvalid();

                                return false;
                            }
                        }
                        if(hashStep !== wizard.currentStep)
                            wizard._show(hashStep);
                    }
                });
            }

            this.element.addClass("ui-formwizard");
            this.element.find(":input").addClass("ui-wizard-content");
            this.steps.addClass("ui-formwizard-content");
            this.backButton.addClass("ui-formwizard-button ui-wizard-content");
            this.nextButton.addClass("ui-formwizard-button ui-wizard-content");

            if(!this.options.disableUIStyles){
                this.element.addClass("ui-helper-reset ui-widget ui-widget-content ui-helper-reset ui-corner-all");
                this.element.find(":input").addClass("ui-helper-reset ui-state-default");
                this.steps.addClass("ui-helper-reset ui-corner-all");
                this.backButton.addClass("ui-helper-reset ui-state-default");
                this.nextButton.addClass("ui-helper-reset ui-state-default");
            }
            this._show(undefined);
            return $(this);
        },

        _next : function(){
            if(this.options.validationEnabled){
                if(!this.element.valid()){
                    this.element.validate().focusInvalid();
                    return false;
                }
            }

            if(this.options.remoteAjax != undefined){
                var options = this.options.remoteAjax[this.currentStep];
                var wizard = this;
                if(options !== undefined){
                    var success = options.success;
                    var beforeSend = options.beforeSend;
                    var complete = options.complete;

                    options = $.extend({},options,{
                        success: function(data, statusText){
                            if((success !== undefined && success(data, statusText)) || (success == undefined)){
                                wizard._continueToNextStep();
                            }
                        },
                        beforeSend : function(xhr){
                            wizard._disableNavigation();
                            if(beforeSend !== undefined)
                                beforeSend(xhr);
                            $(wizard.element).trigger('before_remote_ajax', {"currentStep" : wizard.currentStep});
                        },
                        complete : function(xhr, statusText){
                            if(complete !== undefined)
                                complete(xhr, statusText);
                            $(wizard.element).trigger('after_remote_ajax', {"currentStep" : wizard.currentStep});
                            wizard._enableNavigation();
                        }
                    })
                    this.element.ajaxSubmit(options);
                    return false;
                }
            }

            return this._continueToNextStep();
        },

        _back : function(){
            if(this.activatedSteps.length > 0){
                if(this.options.historyEnabled){
                    this._updateHistory(this.activatedSteps[this.activatedSteps.length - 2]);
                }else{
                    this._show(this.activatedSteps[this.activatedSteps.length - 2], true);
                }
            }
            return false;
        },

        _continueToNextStep : function(){
            if(this.isLastStep){
                for(var i = 0; i < this.activatedSteps.length; i++){
                    this.steps.filter("#" + this.activatedSteps[i]).find(":input").not(".wizard-ignore").removeAttr("disabled");
                }
                if(!this.options.formPluginEnabled){
                    return true;
                }else{
                    this._disableNavigation();
                    this.element.ajaxSubmit(this.options.formOptions);
                    return false;
                }
            }

            var step = this._navigate(this.currentStep);
            if(step == this.currentStep){
                return false;
            }
            if(this.options.historyEnabled){
                this._updateHistory(step);
            }else{
                this._show(step, true);
            }
            return false;
        },

        _updateHistory : function(step){
            var state = {};
            state["_" + $(this.element).attr('id')] = step;
            $.bbq.pushState(state);
        },

        _disableNavigation : function(){
            this.nextButton.attr("disabled","disabled");
            this.backButton.attr("disabled","disabled");
            if(!this.options.disableUIStyles){
                this.nextButton.removeClass("ui-state-active").addClass("ui-state-disabled");
                this.backButton.removeClass("ui-state-active").addClass("ui-state-disabled");
            }
        },

        _enableNavigation : function(){
            if(this.isLastStep){
                this.nextButton.val(this.options.textSubmit);
            }else{
                this.nextButton.val(this.options.textNext);
            }

            if($.trim(this.currentStep) !== this.steps.eq(0).attr("id")){
                this.backButton.removeAttr("disabled");
                if(!this.options.disableUIStyles){
                    this.backButton.removeClass("ui-state-disabled").addClass("ui-state-active");
                }
            }

            this.nextButton.removeAttr("disabled");
            if(!this.options.disableUIStyles){
                this.nextButton.removeClass("ui-state-disabled").addClass("ui-state-active");
            }
        },

        _animate : function(oldStep, newStep, stepShownCallback){
            this._disableNavigation();
            var old = this.steps.filter("#" + oldStep);
            var current = this.steps.filter("#" + newStep);
            old.find(":input").not(".wizard-ignore").attr("disabled","disabled");
            current.find(":input").not(".wizard-ignore").removeAttr("disabled");
            var wizard = this;
            old.animate(wizard.options.outAnimation, wizard.options.outDuration, wizard.options.easing, function(){
                current.animate(wizard.options.inAnimation, wizard.options.inDuration, wizard.options.easing, function(){
                    if(wizard.options.focusFirstInput)
                        current.find(":input:first").focus();
                    wizard._enableNavigation();

                    stepShownCallback.apply(wizard);
                });
                return;
            });
        },

        _checkIflastStep : function(step){
            this.isLastStep = false;
            if($("#" + step).hasClass(this.options.submitStepClass) || this.steps.filter(":last").attr("id") == step){
                this.isLastStep = true;
            }
        },

        _getLink : function(step){
            var link = undefined;
            var links = this.steps.filter("#" + step).find(this.options.linkClass);

            if(links != undefined){
                if(links.filter(":radio,:checkbox").size() > 0){
                    link = links.filter(this.options.linkClass + ":checked").val();
                }else{
                    link = $(links).val();
                }
            }
            return link;
        },

        _navigate : function(step){
            var link = this._getLink(step);
            if(link != undefined){
                if((link != "" && link != null && link != undefined) && this.steps.filter("#" + link).attr("id") != undefined){
                    return link;
                }
                return this.currentStep;
            }else if(link == undefined && !this.isLastStep){
                var step1 =  this.steps.filter("#" + step).next().attr("id");
                return step1;
            }
        },

        _show : function(step){
            var backwards = false;
            var triggerStepShown = step !== undefined;
            if(step == undefined || step == ""){
                    this.activatedSteps.pop();
                    step = this.firstStep;
                    this.activatedSteps.push(step);
            }else{
                if($.inArray(step, this.activatedSteps) > -1){
                    backwards = true;
                    this.activatedSteps.pop();
                }else {
                    this.activatedSteps.push(step);
                }
            }

            if(this.currentStep !== step || step === this.firstStep){
                this.previousStep = this.currentStep;
                this._checkIflastStep(step);
                this.currentStep = step;
                var stepShownCallback = function(){if(triggerStepShown)$(this.element).trigger('step_shown', $.extend({"isBackNavigation" : backwards},this._state()));};
                this._animate(this.previousStep, step, stepShownCallback);
            };


        },

       _reset : function(){
            this.element.resetForm()
            $("label,:input,textarea",this).removeClass("error");
            for(var i = 0; i < this.activatedSteps.length; i++){
                this.steps.filter("#" + this.activatedSteps[i]).hide().find(":input").attr("disabled","disabled");
            }
            this.activatedSteps = new Array();
            this.previousStep = undefined;
            this.isLastStep = false;
            if(this.options.historyEnabled){
                this._updateHistory(this.firstStep);
            }else{
                this._show(this.firstStep);
            }

        },

        _state : function(state){
            var currentState = { "settings" : this.options,
                "activatedSteps" : this.activatedSteps,
                "isLastStep" : this.isLastStep,
                "isFirstStep" : this.currentStep === this.firstStep,
                "previousStep" : this.previousStep,
                "currentStep" : this.currentStep,
                "backButton" : this.backButton,
                "nextButton" : this.nextButton,
                "steps" : this.steps,
                "firstStep" : this.firstStep
            }

            if(state !== undefined)
                return currentState[state];

            return currentState;
        },

      /*Methods*/

        show : function(step){
            if(this.options.historyEnabled){
                this._updateHistory(step);
            }else{
                this._show(step);
            }
        },

        state : function(state){
            return this._state(state);
        },

        reset : function(){
            this._reset();
        },

        next : function(){
            this._next();
        },

        back : function(){
            this._back();
        },

        destroy: function() {
            this.element.find("*").removeAttr("disabled").show();
            this.nextButton.unbind("click").val(this.nextButtonInitinalValue).removeClass("ui-state-disabled").addClass("ui-state-active");
            this.backButton.unbind("click").val(this.backButtonInitinalValue).removeClass("ui-state-disabled").addClass("ui-state-active");
            this.backButtonInitinalValue = undefined;
            this.nextButtonInitinalValue = undefined;
            this.activatedSteps = undefined;
            this.previousStep = undefined;
            this.currentStep = undefined;
            this.isLastStep = undefined;
            this.options = undefined;
            this.nextButton = undefined;
            this.backButton = undefined;
            this.formwizard = undefined;
            this.element = undefined;
            this.steps = undefined;
            this.firstStep = undefined;
        },

        update_steps : function(){
            this.steps = this.element.find(".step").addClass("ui-formwizard-content");
            this.steps.not("#" + this.currentStep).hide().find(":input").addClass("ui-wizard-content").attr("disabled","disabled");
            this._checkIflastStep(this.currentStep);
            this._enableNavigation();
            if(!this.options.disableUIStyles){
                this.steps.addClass("ui-helper-reset ui-corner-all");
                this.steps.find(":input").addClass("ui-helper-reset ui-state-default");
            }
        },

        options: {
               historyEnabled    : false,
            validationEnabled : false,
            validationOptions : undefined,
            formPluginEnabled : false,
            linkClass    : ".link",
            submitStepClass : "submit_step",
            back : ":reset",
            next : ":submit",
            textSubmit : 'Submit',
            textNext : 'Next',
            textBack : 'Back',
            remoteAjax : undefined,
            inAnimation : {opacity: 'show'},
            outAnimation: {opacity: 'hide'},
            inDuration : 400,
            outDuration: 400,
            easing: 'swing',
            focusFirstInput : false,
            disableInputFields : true,
            formOptions : { reset: true, success: function(data) { if( (window['console'] !== undefined) ){console.log("%s", "form submit successful");}},
            disableUIStyles : false
        }
   }
 });
})(jQuery);