3
\$\begingroup\$

I am doing a validation and I believe that there are many things that can be reduced or removed. I am still re-working this. But I am looking for some experts to look at my code and offer the very best approach for both individual and form submit error handling.

(function(){

    var calledIt = function (event, params) {

        $.each(params, function(i,element) {
           var prop = element.get(0).type;
           var value = null;
           switch(prop) {
            case "text" :
            case "select-one" :
                value = element.val();
            break;
            case "radio" :
            case "checkbox" :
                var name = element.prop('name');
                value = $("input[name='"+name+"']:checked").val();
            break;
           }
           if(!value) {
                element.focus();
                return false;
           }
        })
    }

    $(document).on('focusInitiate', calledIt); // sending to focus on invalid element focus on submit,

})();

var Validator = function (form) {

    this.form = form,
        this.elements = this.form.find(':input:not(button, input[type=submit])'),
        button = this.form.find('input[type=submit]'),
        that = this,
        this.submitIt = false;

    this.form.submit(function(e){
        e.preventDefault();
        var requiredElement = [];

        if(that.submitIt) {
            console.log('set a model');
        } else {
            console.log('don\'t set a model')
        }

        $.each(this.elements, function(i,element){
            var tagName = String(element.type).toUpperCase();

            switch(tagName) {
                case "TEXT" :
                case "TEXTAREA" :
                case "SELECT-ONE" :
                    that.inputHandler({tagName:tagName,element:$(this)});
                    requiredElement.push($(this));
                break;
                case "RADIO"      :
                case "CHECKBOX"   :
                    that.changeHandler({tagName:tagName,element:$(this)});
                    requiredElement.push($(this))
                break;
            }
            return requiredElement;
        })

        $.when.apply($, requiredElement).done(function(){
            $.event.trigger("focusInitiate", [requiredElement]);
        })
    })

    this.validate = function () {

        $.each(this.elements, function(i,element){

            var tagName = $(element).prop('type').toUpperCase();

            switch(tagName) {
                case "TEXT" :
                case "TEXTAREA" :
                case "SELECT-ONE" :
                    $(element).on('input focusout', {tagName:tagName,element:$(this)}, that.inputHandler);
                break;
                case "RADIO"      :
                case "CHECKBOX"   :
                    $(element).on('change focusout', {tagName:tagName,element:$(this)}, that.changeHandler);
                break;
            }

        });

    }


    this.handleElements = function (params,status) {

        var tagName = params.data ? params.data.tagName : params.tagName;
        var element = params.data ? params.data.element : params.element;

        if(status==="inputHandler") {
            var value = params.data ? params.data.element.val() : params.element.val();
            return {"tagName" :tagName,"element" : element, 'value' : value };
        }

        if(status==="changeHandler") {
            var name =   element.prop('name');
            var value = $("input[name='"+name+"']:checked").val()
            return {"tagName" :tagName,"element" : element, 'value' : value };
        }

    }

    this.inputHandler = function (params) {
        var processedParams = that.handleElements(params,"inputHandler");
        that.errorHandler(processedParams);
    }

    this.changeHandler = function (params) {
        var processedParams = that.handleElements(params,"changeHandler");
        that.errorHandler(processedParams);
    }

    this.errorHandler = function (params) {
        var actualValue = $.trim(params.value),
            tagName = params.tagName,
            target = params.element;


        switch(tagName) {

            case 'TEXT' :                
                if(!actualValue) {
                    $(target).next('.error').css('display','block');
                    that.submitIt = false;
                } else {
                    $(target).next('.error').css('display','none');
                    that.submitIt = true;
                }
                break;
            case "SELECT-ONE" : 
                if(actualValue === 'Select') {
                    $(target).next('.error').css('display','block');
                    that.submitIt = false;
                } else {
                    $(target).next('.error').css('display','none');
                    submitIt = true
                }
                break;
           case "RADIO" : 
           case "CHECKBOX" : 
                if(actualValue && actualValue !== 'undefined'){
                    $(target).siblings('.error').css('display','none');
                    that.submitIt = true;
                } else {
                    $(target).siblings('.error').css('display','block');
                    that.submitIt = false;
                }
                break;
        }

        return that.submitIt;
    }

}

var initiateValidate = function () {
    var form = $('form');
    form.find('*').off();
    var validator = new Validator(form);
    validator.validate();
}

initiateValidate();

Live Demo

\$\endgroup\$
  • \$\begingroup\$ In your title you mention memory-leak but not in the text of your question, are you sure there is such a problem ? \$\endgroup\$ – Marc-Andre Jun 19 '14 at 15:09
  • \$\begingroup\$ I did not find any problem. I am looking the feedback like you kind of people. with simplification. \$\endgroup\$ – 3gwebtrain Jun 20 '14 at 4:19
1
\$\begingroup\$

The design problems in this code bother me a lot more than the code problems.

  • Every single input type is mandatory, that seems not very useful, you should have a class or something other to identify which fields are mandatory
  • Your text input fields dont have the id attribute set
  • You are using span for labels instead of the label tag.
  • You predefine 1 single error per field, what if you need 2 validations with a different message

From a once over on the coding

  • var value = null; -> KISS -> var value;
  • var prop = element.get(0).type; <- Why prop, why not type?
  • This:

    $(target).next('.error').css('display','none');
    submitIt = true
    

    is copy pasted a ton of times, refactor this

  • This switch: switch(tagName) { is copy pasted a ton of times as well -> refactor

I think this needs some serious rethinking on your end.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.