For a web application I’m currently working on I’ve had to implement some input validation and thought others may find it of use. Although I have yet to add more, admittedly rather specific, validation it will be little more than enhancements of or additions to what I have so far, so here is what I have to date. All this code is in a file I call “functions.js”, which is loaded at the end of the HTML page. As mentioned in the previous post on this topic, I use jQuery in this application.
Although input validation of web pages is most commonly done when a form is submitted there are advantages to performing at least basic validation as data is input. Most notably, the rejection of unwanted characters. and ensure required fields have content. Let’s start with the basics, which builds on my previous post a little.
Each mandatory field has the class of “required” and each email field has the class of “email”.
// Validate all fields with the "required" class to ensure // they are not empty and fields with the "email" class // for valid email address form function validate() { var ok = true; $('.required').each(function() { if($(this).val() == '' && $(this).html() == '') { $(this).addClass('needed'); ok = false; } else { $(this).removeClass('needed'); } }); $('.email').each(function() { var str = $(this).val(); if(str.length > 0) { var reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/; if(reg.test(str) == false) { $(this).addClass('needed'); ok = false; } } }); return ok; }
The “needed” class highlights fields with errors. This highlighting can take any form you desire and is implemented in CSS. Mine makes the background of the field a light red and places a red border around it.
.needed { background-color: #FFE2E1; border: 1px solid red; }
When the reset button is pressed on a form the “needed” class is removed from all affected fields by calling clearValidation().
// Remove the "needed" class from all fields that have it function clearValidation() { $('.needed').each(function() { $(this).removeClass('needed'); }); }
It’s also nice to remove the “needed” class as data is entered, which is done with this bit of code.
// For all input and textarea fields, remove the "needed" class // if content has been entered $("input,textarea").live("keyup", function() { if($(this).val() != '' || $(this).html() != '') { $(this).removeClass('needed'); } });
Due to problems working with strings which contain double quotes they are disallowed, as are spaces at the start on an input, which simply don’t make sense and are normally the result of an unintended keypress.
// Prevent entry of a double quote // or a space as the first character $('input,textarea').bind('keypress',function(e){ var str = $(this).val(); var key = e.which; if(key == 34) { return false; }; if((key == 32) && (str.length < 1)) { return false; } return true; });
Now we get to some slightly fancier stuff. Email addresses have pretty strict requirements, so we take care of much of that by testing characters as they are entered.
// Validate email addresses for fields with the 'email' class $('.email').bind('keypress',function(e){ var str = $(this).val(); var key = e.which; var chr = String.fromCharCode(key); var prev = str.substring(str.length-1); var reg = /([A-Za-z0-9_\-\.\@])/; // Disallow illegal characters if(reg.test(chr) == false) { return false; } // Disallow multiple '@' or '@' as the first character if((key == 64) && ((str.indexOf('@') >= 0) || (str.length < 1))) { return false; } // Disallow two dots in sequence if((key == 46) && (chr == prev)) { return false; } return true; });
Phone (or fax) numbers need to be restricted also. Ours generally take the form of an option area code in brackets e.g. "(03)", followed by groups of digits, which may or may not be separated by spaces.
// Validate fields with the "phone" class $('.phone').bind('keypress',function(e){ var str = $(this).val(); var key = e.which; var chr = String.fromCharCode(key); var prev = str.substring(str.length-1); // Allow only numbers, spaces, "+" and "(" or ")" // but not multiple spaces in sequence if(((key != 32) && (key != 40) && (key != 41) && (key != 43) && ((key < 48) || (key > 57))) || ((key == 32) && (chr == prev))) { return false; } // "(" or "+" as the first character only if(((key == 40) || (key == 43)) && (str.length > 0)) { return false; } // Only one ")" and only after at least two characters, // with a "(" as the first character if((key == 41) && ((str.length < 2) || (str.indexOf(')') >= 0) || (str.indexOf('(') < 0))) { return false; } if((key == 64) && ((str.indexOf('@') >= 0) || (str.length < 1))) { return false; } return true; });
I hope you find at least some of the above useful. The code may not be the most elegant but it certainly works as intended. Hopefully the comments will help if you intend to expand or modify any of these routines.