Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html>
    <head>
        <title>JavaScript Form Validation</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
        <div>
            <form method="post" action="" id="test-form" enctype="multipart/form-data">
                <p>
                    <label><strong>Full Name</strong>&nbsp;
                        <input type="text" name="fullname" id="fullname" value="" placeholder="Full Name" />
                    </label>
                </p>
                <p>
                    <label><strong>Date of Birth</strong>&nbsp;
                        <input type="text" name="date_of_birth" id="date_of_birth" value="" placeholder="2016-12-31" />
                    </label>
                </p>
                <p>
                    <label><strong>Age</strong>&nbsp;
                        <input type="text" name="age" id="age" value="" placeholder="25" />
                    </label>
                </p>
                <p>
                    <label><strong>Height</strong>&nbsp;
                        <input type="text" name="height" id="height" value="" placeholder="6.5" />
                    </label>
                </p>
                <p>
                    <label><strong>Email</strong>&nbsp;
                        <input type="text" name="email" id="email" value="" placeholder="test@example.com" />
                    </label>
                </p>
                <p>
                   <label><strong>Password</strong>&nbsp;
                        <input type="password" name="password" id="password" value="" />
                    </label> 
                </p>
                <p>
                   <label><strong>Confirm Password</strong>&nbsp;
                        <input type="password" name="rpt_password" id="rpt_password" value="" />
                    </label> 
                </p>
                <p>
                    <label><strong>Message</strong>&nbsp;
                        <textarea name="message" id="message" placeholder="Message"></textarea>
                    </label>
                </p>
                <p>
                    <label><strong>Photo</strong>&nbsp;
                        <input type="file" name="photo" id="photo" />
                    </label>
                </p>
                <p>
                    <label><strong>Gender</strong>&nbsp;
                        <input type="radio" name="gender" id="male" value="male" /> Male
                        <input type="radio" name="gender" id="female" value="female" /> Female
                    </label>
                </p>
                <p>
                    <strong>Color</strong>&nbsp;
                        <input type="checkbox" name="color[]" id="red" value="red" /> Red
                        <input type="checkbox" name="color[]" id="green" value="green" /> Green
                        <input type="checkbox" name="color[]" id="blue" value="blue" /> Blue
                        <input type="checkbox" name="color[]" id="white" value="white" /> White
                        <input type="checkbox" name="color[]" id="black" value="black" /> Black
                </p>
                <p>
                    <label><strong>Country</strong>&nbsp;
                        <select name="country" id="country">
                            <option value="">Select Country</option>
                            <option value="uganda">Uganda</option>
                            <option value="kenya">Kenya</option>
                            <option value="tanzania">Tanzania</option>
                            <option value="rwanda">Rwanda</option>
                            <option value="burundi">Burundi</option>
                            <option value="south_sudan">South Sudan</option>
                        </select>
                    </label>
                </p>
                <p>
                    <input type="submit" name="submit" id="submit" value="Submit" />
                </p>
            </form>
        </div>
    </body>
</html>
 
function trim( val ) {
    'use strict';
    if ( typeof String.prototype.trim === 'function' ) {
        return String(val).trim();
    } else {
        return String(val).replace(/^\s+|\s+$/g, '');
    }
}
function addEvent( obj, type, fn ) {
    'use strict';
    if (obj.attachEvent) {
        obj['e' + type + fn] = fn;
        obj[type + fn] = function () {
            obj['e' + type + fn](window.event);
        };
        obj.attachEvent('on' + type, obj[type + fn]);
    } else {
        obj.addEventListener(type, fn, false);
    }
}
function removeEvent( obj, type, fn ) {
    'use strict';
    if (obj.detachEvent) {
        obj.detachEvent('on' + type, obj[type + fn]);
        obj[type + fn] = null;
    } else {
        obj.removeEventListener(type, fn, false);
    }
}
function isEmpty( obj ) {
    'use strict';
    var count = 0;
    obj = obj || {};
    for ( var prop in obj ) {
        if ( {}.hasOwnProperty.call(obj, prop) ) {
            count += 1;
        }
    }
    return ( count === 0 ) ? true : false;
}
function Validation( items ) {
    'use strict';
    this.items  = items || {};
    this.errors = {};
    this.data = {};
    this.success = false;
}
Validation.prototype.check = function( form ) {
    'use strict';
    for ( var elem in (this.items) ) {
        if ( {}.hasOwnProperty.call(this.items, elem) ) {
            var rules = this.items[elem];
            var formElement = form[elem];
            // Is it an instance of radionodelist or not
            // As in is a radio or checkbox
            if ( 'tagName' in formElement ) {
                switch ( formElement.tagName.toLowerCase() ) {
                    case 'select':
                        this.validateSelect( elem, rules, formElement, form, this.items );
                        break;
                    case 'input':
                    case 'textarea':
                    default:
                        this.validateInput( elem, rules, formElement, form, this.items );
                        break;
                }
            } else {
                var firstNode = formElement[0]; // FormElement contains a RadioNodeList Object
                switch ( firstNode.getAttribute('type').toLowerCase() ) {
                    case 'radio':
                        this.validateRadio( elem, rules, formElement, form, this.items );
                        break;
                    case 'checkbox':
                        this.validateCheckBox( elem, rules, formElement, form, this.items );
                        break;
                }
            }
        }
    }
    
    if ( isEmpty(this.errors) ) {
        this.success = true;
    }
    
    return this;
};
// Validate provided value, if any
Validation.prototype.validateValue = function( value, elem, rules, form, items ) {
    'use strict';
    var error = false;
            
    if ( 'required' in rules ) {
        if ( value.length === 0 ) {
            this.errors[elem] = rules['name'] + ' is required';
            error = true;
        }
    }
    
    if ( (value.length !== 0) && !(error) ) {
        if ( 'min' in rules ) {
            if ( rules['expected'].toLowerCase() === 'integer' ) {
                // Check if a valid number or integer is provided
                if ( isNaN(Number(value)) ) {
                    this.errors[elem] = rules['name'] + ' is not a valid number';
                    error = true;
                }
            }
            
            if ( !(error) ) {
                if ( this.checkMin(value, rules['min'], rules['expected']) ) {
                    this.errors[elem] = this.getMinMessage( 
                            rules['name'], rules['min'], rules['expected'] 
                    );
                    error = true;
                }
            }
        }
    }
    
    if ( (value.length !== 0) && !(error) ) {
        if ( 'max' in rules ) {
            if ( rules['expected'].toLowerCase() === 'integer' ) {
                // Check if a valid number or integer is provided
                if ( isNaN(Number(value)) ) {
                    this.errors[elem] = rules['name'] + ' is not a valid number';
                    error = true;
                }
            }
            
            if ( !(error) ) {
                if ( this.checkMax(value, rules['max'], rules['expected']) ) {
                    this.errors[elem] = this.getMaxMessage( 
                            rules['name'], rules['max'], rules['expected'] 
                    );
                    error = true;
                }
            }
        }
    }
    
    if ( (value.length !== 0) && !(error) ) {
        if ( 'matches' in rules ) {
            var compareValue = form[rules['matches']].value;
            if ( value !== compareValue ) {
                var compareName = items[ rules['matches'] ];
                compareName = compareName['name'];
                this.errors[elem] = rules['name'] + ' does not match ' + compareName;
                error = true;
            }
        }
    }
    
    if ( (value.length !== 0) && !(error) ) {
        if ( 'email' in rules ) {
            if ( !(this.checkEmail(value)) ) {
                this.errors[elem] = rules['name'] + ' is not valid';
                error = true;
            }
        }
    }
    
    if ( (value.length !== 0) && !(error) ) {
        if ( 'date' in rules ) {
            if ( !(this.checkDate(value)) ) {
                this.errors[elem] = rules['name'] + ' is not a valid date';
                error = true;
            }
        }
    }
    
    if ( (value.length !== 0) && !(error) ) {
        if ( 'permitted' in rules ) {
            if ( value.indexOf('fakepath') !== -1 && value.indexOf('\\') !== -1 ) {
                value = value.split('\\').pop();
            } else if ( value.indexOf('fakepath') !== -1 && value.indexOf('/') !== -1 ) {
                value = value.split('/').pop();
            }
            
            var permitted = rules['permitted'];
            var checkValue = value.split('.').pop().toLowerCase();
            if ( permitted.indexOf(checkValue) === -1 ) {
                this.errors[elem] = rules['name'] + ' is not permitted';
                error = true;
            }
        }
    }
    
    if ( (value.length !== 0) && !(error) ) {
        if ( 'pattern' in rules ) {
            var regex = rules['pattern'];
            if ( !(regex.test(value)) ) {
                this.errors[elem] = rules['name'] + ' is not in the required format';
                error = true;
            }
        }
    }
    
    // Finally, if no error add to data collection
    if ( !(error) ) {
        this.data[elem] = value;
    }
};
// Validate Select Menu
Validation.prototype.validateSelect = function( elem, rules, formElement, form, items ) {
    'use strict';
    var value = '';
    if ( formElement.hasAttribute('multiple') ) {
        value = [];
        for ( var i = 0, len = formElement.options.length; i < len; i += 1 ) {
            if ( formElement.options[i].selected ) {
                value.push( trim(formElement.options[i].value) );
            }
        }
    } else {
        value = trim( formElement.value );
    }
    this.validateValue( value, elem, rules, form, items );
}; 
// Validate Textarea or Input of type text, password, 
// date, search, email etc 
Validation.prototype.validateInput = function( elem, rules, formElement, form, items ) {
    'use strict';
    var value = '';
    
    if ( formElement.hasAttribute('type') ) {
        if ( formElement.getAttribute('type').toLowerCase() === 'password' ) {
            value = formElement.value;
        } else {
            value = trim( formElement.value );
        }
    } else {
        // Textarea value
        value = trim( formElement.value );
    }  
    
    this.validateValue( value, elem, rules, form, items );
};
// Validate Radio Buttons
Validation.prototype.validateRadio = function( elem, rules, nodeList, form, items ) {
    'use strict';
    var value = '';
    for ( var i = 0, len = nodeList.length; i < len; i += 1 ) {
        if ( nodeList[i].checked ) {
            value = trim( nodeList[i].value );
            break;
        }
    }
    this.validateValue( value, elem, rules, form, items );
};
// Validate Checkboxes
Validation.prototype.validateCheckBox = function( elem, rules, nodeList, form, items ) {
    'use strict';
    var values = [];
    for ( var i = 0, len = nodeList.length; i < len; i += 1 ) {
        if ( nodeList[i].checked ) {
            values.push( trim(nodeList[i].value) );
        }
    }
    this.validateValue( values, elem, rules, form, items );
};
Validation.prototype.getMinMessage = function( name, minValue, expected ) {
    'use strict';
    expected = expected || '';
    switch ( expected.toLowerCase() ) {
        case 'integer':
            return name + ' cannot be less than ' + minValue;
            break;
        case 'string':
            return name + ' must be a minimum of ' + minValue + ' characters';
            break;
        default:
            return 'You must select at least ' + minValue + ' ' + name;
            break;
    }
};
Validation.prototype.getMaxMessage = function( name, maxValue, expected ) {
    'use strict';
    expected = expected || '';
    switch ( expected.toLowerCase() ) {
        case 'integer':
            return name + ' cannot be greater than ' + maxValue;
            break;
        case 'string':
            return name + ' must be a maximum of ' + maxValue + ' characters';
            break;
        default:
            return 'You must select a maximum of ' + maxValue + ' ' + name;
            break;
    }
};
// Check Minimum value
Validation.prototype.checkMin = function( value, minValue, expected ) {
    'use strict';
    expected = expected || '';
    switch ( expected.toLowerCase() ) {
        case 'integer':
            return Number(value) < minValue;
            break;
        case 'string':
            return String(value).length < minValue;
            break;
        default:
            return value.length < minValue;
            break;
    }
};
// Check Maximum value
Validation.prototype.checkMax = function( value, maxValue, expected ) {
    'use strict';
    expected = expected || '';
    switch ( expected.toLowerCase() ) {
        case 'integer':
            return Number(value) > maxValue;
            break;
        case 'string':
            return String(value).length > maxValue;
            break;
        default:
            return value.length > maxValue;
            break;
    }
};
// Check email value
Validation.prototype.checkDate = function( value ) {
    'use strict';
    var date = new Date( value );
    return ( isNaN(date.getDate()) ) ? false : true;
};
// Check email value
Validation.prototype.checkEmail = function( value ) {
    'use strict';
    var emailRegex = /^[\w.%+\-]+@[\w.\-]+\.[A-za-z]{2,}$/;
    return emailRegex.test( value );
};
Validation.prototype.getErrors = function() {
    'use strict';
    return this.errors;
};
Validation.prototype.getData = function() {
    'use strict';
    return this.data;
};
Validation.prototype.passed = function() {
    'use strict';
    return this.success;
};
function validateForm(e) {
    'use strict';
    var submitForm = false;
    var formItems = {};
    formItems['fullname'] = {
        required: true, name: 'Full Name', min: 3,
        max: 50, expected: 'string', pattern: /^([a-z ]|[^\d.\-])+$/i
    };
    formItems['date_of_birth'] = {
        required: true, name: 'Date of Birth', expected: 'string', date: true
    };
    formItems['age'] = {
        required: true, name: 'Age', min: 1,
        max: 100, expected: 'integer', pattern: /^(-?[0-9]+)$/
    };
    formItems['height'] = {
        required: true, name: 'Height', min: 1,
        max: 12, expected: 'integer', pattern: /^(-?[0-9]+\.[0-9]+)$/
    };
    formItems['email'] = {
        required: true, name: 'Email', email: true
    };
    formItems['password'] = {
        required: true, name: 'Password', min: 8, expected: 'string'
    };
    formItems['rpt_password'] = {
        required: true, name: 'Confirm Password', matches: 'password'
    };
    formItems['message'] = {
        required: true, name: 'Message'
    };
    formItems['photo'] = {
        required: true, name: 'Photo', permitted: [ 'jpg', 'png' ]
    };
    formItems['gender'] = {
        required: true, name: 'Gender', expected: 'string'
    };
    formItems['color[]'] = {
        required: true, name: 'Color(s)', min: 2
    };
    formItems['country'] = {
        required: true, name: 'Country'
    };
    e = e || window.event;
    var targetForm = e.target || e.srcElement;
    var validation = new Validation( formItems );
    validation = validation.check( targetForm );
    if ( document.getElementById('list') ) {
        var list = document.getElementById('list');
        list.parentNode.removeChild( list );
        var formElements = targetForm.getElementsByTagName('*');
        formElements = [].slice.call(formElements);
        formElements.forEach(function(val){
            if ( !(val instanceof RadioNodeList) ) { 
                val.classList.remove('border-warning');
            }
        });
    }
    if ( validation.passed() ) {
        var data = validation.getData();
        console.log( JSON.stringify(data) );
    } else {
        var errors = validation.getErrors();
        if ( !(isEmpty(errors)) ) {
            var ul = document.createElement( 'ul' );
            ul.setAttribute( 'id', 'list' );
            ul.setAttribute( 'class', 'error' );
            var li;
            for ( var error in errors ) {
                if ( {}.hasOwnProperty.call( errors, error ) ) {
                    li = document.createElement('li');
                    li.appendChild( document.createTextNode(errors[error]) );
                    ul.appendChild( li );
                    if ( !(targetForm[error] instanceof RadioNodeList) ) { 
                        targetForm[error].classList.add('border-warning');
                    }
                }
            }
            targetForm.parentNode.insertBefore( ul, targetForm );
        }
    }
    // Prevent the form's submission:
    if (e.preventDefault) {
        e.preventDefault();
    } else {
        e.returnValue = false;
    }
    return submitForm;
}
addEvent( window, 'load', function(){
    'use strict';
    var form = document.getElementById( 'test-form' );
    if ( !(form) ) { return; }
    addEvent( form, 'submit', validateForm );
});
Output

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
kellyjoe256pro
0viewers