I wrote a relatively simple and intuitive form validation script for a client, which they kindly allowed me to release into the open-source community.
Contents
The Objective
The Basics
Including The JavaScript
Explaining The Code
Core Functions
Expanded Functions
Options
HTML
Examples
Download
License
To-Do’s
Change-log
The Objective
The aim was to develop a simple JavaScript form validator plugin to be:
- JQuery based
- Fast and efficient
- Automated (via CSS Classes)
- Adjustable (via option settings)
- Easily expandable
The Basics
From a simplistic overview, the plugin loops around any form with a submit button and validates input elements based on its CSS classes.
The standard CSS classes it works on are:
required – if an input is marked as ‘required’ it simply makes sure the field is not empty.
email – it does a simple regex check to ensure the format is correct.
digit – it checks whether the field only contains numbers 0 to 9.
alpha – checks if the field contains characters a to z and A to Z.
Including the JavaScript
First include JQuery, supports 1.3.2 – 1.4.2:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
Then include our script:
<script type="text/javascript" src="options.validate-form.js"></script>
<script type="text/javascript" src="validate-form.js"></script>
Explaining the Code
Attaching the code automatically to all Forms is carried out by:
$().ready(function() {
//attach plugin to all forms with a submit button (except for ignored forms)
$('form:not('+ formsToIgnore() +')').submit(function() {
var formId = $(this).attr('id');
var matchingElements = $('form#'+ formId +' input[type=text], form#'+ formId +' textarea, form#'+ formId +' input[type=checkbox]');
if (!matchingElements == "") {
var formError = validateForm(formId, matchingElements);
if (formError == true) {
return false
} else {
return true;
}
}
});
});
If you need eager validation (it annoys me, but some people seem to love it #shake-head), set the options variable eagerValidation=true (see script options or examples), or if you don’t need it, remove it.
//check whether to eagerly validate each field
if (eagerValidation == true) {
$('form input[type=text], form textarea, form input[type=checkbox]').focusout(function() {
var fieldId = $(this).attr('id');
var formId = $('#'+fieldId).parents('form').attr('id');
if (validateField(formId, fieldId) == false) {
removeFieldError(formId, fieldId);
}
removeFormError(formId);
addFormError(formId);
});
}
Core Functions
function validateField(formId, fieldId) {
if (fieldId) {
removeFieldError(formId, fieldId);
var element = buildElement(formId, fieldId);
var fieldValue = jQuery.trim(jQuery(element).val());
var fieldLength = fieldValue.length;
var fieldErrorMessage = "";
if ($(element).hasClass('text')) {
if ($(element).hasClass('alpha') && fieldLength > 0) { // from string start to end, only contains '-' "whitespace" or 'aA'-'zZ'
if (validateAlpha(fieldValue) == false) {
fieldErrorMessage = alphaFieldError;
}
} else if ($(element).hasClass('digit') && fieldLength > 0) {
if (validateDigit(fieldValue) == false) {
fieldErrorMessage = digitFieldError;
}
} else if ($(element).hasClass('email') && fieldLength > 0) {
if (validateEmail(fieldValue) == false) {
fieldErrorMessage = emailFieldError;
}
} else if ($(element).hasClass('required') && fieldLength == 0) {
fieldErrorMessage = requiredTextError;
}
} else if ($(element).is('.textarea.required') && fieldLength == 0) {
fieldErrorMessage = requiredTextareaError;
} else if ($(element).is('.checkbox.required') && !$(element).is(':checked')) {
fieldErrorMessage = requiredCheckboxError;
}
if (!fieldErrorMessage) {
return false;
} else {
if (customErrorSelectors.length > 0) {
for (i=0;i<customErrorSelectors.length;i++) { //check for overrides
if (customErrorSelectors[i] == element) {
fieldErrorMessage = customErrorMessages[i];
}
}
}
addFieldError(formId, fieldId, fieldErrorMessage);
return true;
}
}
}
function validateForm(formId, matchingElements) {
removeAllErrors(formId);
matchingElements.each(function(index) {
var elementId = $(this).attr('id');
var fieldErrorStatus = validateField(formId, elementId);
});
if (countFormErrors(formId) > 0) {
if (focusFirstError == true) {
focusOnFirstError(formId);
}
if (errorSummary == true) {
addFormError(formId);
}
return true;
} else {
if (errorSummary == true) {
removeFormError(formId);
}
return false;
}
}
Expanded Functions
function buildElement(formId, fieldId) {
var element = "form#"+formId+" #"+fieldId;
return element;
}
function focusOnFirstError(formId) {
$('form#'+formId+' input.'+inputErrorClass+':first').focus();
}
function formsToIgnore() { //check for forms to ignore
var formIgnoreItems = "";
for (i=0;i<ignoreForms.length;i++) {
if (i>0) {
formIgnoreItems += ", ";
}
formIgnoreItems += ignoreForms[i];
}
return formIgnoreItems;
}
function countFormErrors(formId) {
var errorCounter = $('form#'+formId+' '+inputWrapper+'.'+inputWrapperErrorClass).size();
return errorCounter;
}
function addFormError(formId) {
var formSelector = 'form#'+formId;
var errorMessageSelector = formSelector+' p.error-summary';
var errorCounter = countFormErrors(formId);
if (errorCounter > 0) {
if ($(errorMessageSelector).length) {
$(errorMessageSelector).html(errorCounter + ' field(s) are invalid.');
} else {
$(formSelector).prepend('<p class=\"error-summary\">' + errorCounter + ' field(s) are invalid.</p>');
}
}
}
function removeAllErrors(formId) {
removeFormError(formId);
removeAllFieldErrors(formId);
}
function removeFormError(formId) {
$('form#'+formId+' p.error-summary').remove();
}
function removeAllFieldErrors(formId) {
var formSelector = 'form#'+formId;
$(formSelector+' '+inputWrapper).removeClass(inputWrapperErrorClass);
$(formSelector+' input[type=text], '+formSelector+' textarea, '+formSelector+' input[type=checkbox]').removeClass(inputErrorClass);
$(formSelector+' '+inputWrapper+' p.error-message').remove();
}
function addFieldError(formId, fieldId, fieldErrorMessage) {
var element = buildElement(formId, fieldId);
$(element).addClass(inputErrorClass)
.parents(inputWrapper).addClass(inputWrapperErrorClass)
.append('<p class=\"error-message\">>' + fieldErrorMessage + '</p>');
}
function removeFieldError(formId, fieldId) {
var element = buildElement(formId, fieldId);
$(element).removeClass(inputErrorClass)
.parents(inputWrapper).removeClass(inputWrapperErrorClass);
$(element).parents(inputWrapper).children('p.error-message').remove();
}
function validateAlpha(alpha) {
var regex = /^[-\sa-zA-Z]+$/
return regex.test(alpha);
}
function validateDigit(digit) {
var regex = /^[0-9]+$/
return regex.test(digit);
}
function validateEmail(email) {
var regex = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
return regex.test(email);
}
Options
//Validator options
var eagerValidation = false; //true/false if set to true, form will eagerly validate each field. False will validate only ever on form submission
var errorSummary = true; //true/false if set to true will show error summary at the top of the form
var focusFirstError = true; //true/false if set to true will refocus user input to first error field on form submission
var inputErrorClass = "error"; //set the class name that will be appended to the form input/textarea when an error is detected
var inputWrapper = "p"; //set the element type that is used to wrap the form input/textarea in your forms
var inputWrapperErrorClass = "err"; //set the class name that will be appended to the wrapper of the input/textarea when an error is detected
//Error Messages
var requiredTextError = "cannot be empty"; //Textbox error
var requiredTextareaError = "cannot be empty"; //Textarea error
var requiredCheckboxError = "needs to be ticked"; //Checkbox error
var alphaFieldError = "characters only, no numbers"; //Alpha Textbox error
var digitFieldError = "numbers only, no characters"; //Numeric Textbox error
var emailFieldError = "valid email address only"; //email Textbox error
var ignoreForms = ['#search-form']; //add any forms you need want the form to ignore, e.g search forms, etc. This can be ignored as long as none of the form inputs have 'required' or other validation classes attached
var customErrorSelectors = ['form#testform #el_0','form#testform #el_2']; //include form Id and element Id!
var customErrorMessages = ['this is an error message override, as specified in the config options','this is another error message override']; //Relates directly to customErrorSelectors
HTML
The script assumes an element wrapper is used, and must be included in the options under inputWrapper, the default is <p>. See the examples included for the structure of HTML compatible.
Examples
Simple Example
More Complex Example
Download
Options script – required for validation script to work
Download everything in 1 zipped package
License
Released under MIT License.
To Do’s
- Improve the efficiency of the code execution.
- Add min-length class options for fields.
Change-log
2010/05/20: v0.2 released





