Extendable JavaScript Validation Routines
Extendable Javascript validation routines.
Introduction
I posted my nice basic C# RegEx validator onto CodeProject to rave reviews (two people voted it 1 out of 5). Spurred on by this vote of confidence, I thought I'd publish a JavaScript validation system that I find handy. So here goes. We all know we should validate our controls client-side to save on post backs. This is easy for .NET, but becomes a little more cumbersome when using something like PHP.
The code
Firstly, here is the meat of the thing:
<script type="text/javascript" language=""javascript""
xsrc="validate.js" mce_src="validate.js" ></script>
<script type="text/javascript" language=""Javascript"">
<!-
//Create an array of ControlDetails that need validating.
//Format(elementid,required,maxlength,minlength,email,decimal,nonnegdecimal)
var controlsToValidate = new Array(
/* Name is required has no max must be longer than 3 characters*/
new ControlDetail('txtName',1,-1,3,0,0,0),
/* Age is not required but must be a non negative number */
new ControlDetail('txtAge',0,-1,-1,0,0,1),
/* IQ Required but can be negative */
new ControlDetail('txtIQ',1,-1,-1,0,1,0),
/* Email required must be under 20 characters */
new ControlDetail('txtEmail',1,20,-1,1,0,0)
)
//->
</script>
This sits in the head of your web page. The controlsToValidate
array is an array of the controls that you want to validate. Each item in the array is a ControlDetail
object which consists of:
elementid
required
maxlength
minlength
email
decimal
nonnegdecimal
This object is defined in the "validate.js" script file, which we'll get to later. As you can see, for nearly all of the attributes of the ControlDetail
object, you can set it to 1 for true and 0 for false, except the minlength
and maxlength
, which require -1 for ignore and a number to work. Anyway, the current controls are configured as their commented descriptions indicate.
So further down the HTML, we have our controls:
<form name="form1″ method="post" action=""
onSubmit="return Validate(controlsToValidate);"><div class="row">
<div class="label">Name:</div>
<div class="input"><input id="txtName" name="Name" type="text" size="30″>
</div>
</div>
<div class="row">
<div class="label">Age:</div>
<div class="input"><input id="txtAge" name="Age" type="text" size="5″ maxlength="5″>
</div>
</div>
<div class="row">
<div class="label">IQ:</div>
<div class="input"><input id="txtIQ" name="IQ" type="text" size="30″>
</div>
</div>
<div class="row">
<div class="label">Email Address:</div>
<div class="input"><input id="txtEmail" name="Email" type="text" size="30″>
</div>
</div>
<div class="row">
<div class="label">
<input type="submit" accesskey="s" class="submit" value="Save" title="Save Details">
</div>
</div>
</form>
You will notice that I've given them all an ID which is used later with document.getElementByID
, and a name which is also used later to describe the control in the error message. Also, there is the OnSubmit
function which calls our main validation routine and passes in the array we made earlier.
OK, so this is what the validator.js file looks like:
/*
This is the source code for the validation routines.
Please feel free to augment, fix, change,
use where-ever you want.***Do Not Delete***
File: validate.js
Author: Chris Davey
Version: 1.0
Email: chris.davey@chemlock.co.uk
Web: www.chemlock.co.uk
***End Do Not Delete***
Please visit my site for more info, examples and versions (www.chemlock.co.uk)
*/
//Controls that require validating can be put into this object
function ControlDetail ( elementid, required, maxlength,
minlength, email, decimal, nonnegdecimal, ipaddress)
{
this.elementid = elementid;
this.required = required;
this.maxlength = maxlength;
this.minlength = minlength;
this.email = email;
this.decimal = decimal;
this.nonnegdecimal = nonnegdecimal;
this.ipaddress = ipaddress;
}
//** All Validation Functions **
function ContainsValue(element)
{
return document.getElementById(element).value.length != 0;
}
function IsOverMaxLength(element,maxlength)
{
return document.getElementById(element).value.length > maxlength;
}
function IsUnderMinLength(element,minlength)
{
return document.getElementById(element).value.length < minlength;
}
function RegExTest(element,expression)
{
return element.value.match(expression) != null;
}
function IsEmail(element)
{
var emailRE = "([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]" +
"{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})";
return RegExTest(element,emailRE);
}
function IsDecimal(element)
{
var decimalRE = "^(\\+|-)?[0-9][0-9]*(\\.[0-9]*)?$";
return RegExTest(element,decimalRE);
}
function IsNonNegDecimal(element)
{
var nonnegdecimalRE = "^[0-9][0-9]*(\\.[0-9]*)?$";
return RegExTest(element,nonnegdecimalRE);
}
//** End All Validation Functions **
//** Main Validation Routine **
function Validate(controlsToValidate)
{
valid = true;
var message = "Warning:\n\n";
for(var i = 0;i < controlsToValidate.length;i++)
{
if(controlsToValidate[i].required == 1)
{
//Validate that a value has been entered
if(ContainsValue(controlsToValidate[i].elementid) == false)
{
valid = false;
message += document.getElementById(
controlsToValidate[i].elementid).name +
" is required.\n";
}
}
if(controlsToValidate[i].maxlength != -1)
{
//Validate that the value is not over max
if(IsOverMaxLength(controlsToValidate[i].elementid,
controlsToValidate[i].maxlength) == true)
{
valid = false;
message += document.getElementById(
controlsToValidate[i].elementid).name +
" is to long.\n";
}
}
if(controlsToValidate[i].minlength != -1)
{
//Validate that the value is not under min
if(IsUnderMinLength(controlsToValidate[i].elementid,
controlsToValidate[i].minlength) == true)
{
valid = false;
message += document.getElementById(
controlsToValidate[i].elementid).name +
" is to short.\n";
}
}
if(controlsToValidate[i].email == 1)
{
//Validate that the value is an email
if(IsEmail(document.getElementById(
controlsToValidate[i].elementid)) == false)
{
valid = false;
message += document.getElementById(
controlsToValidate[i].elementid).name +
" is not a valid email address.\n";
}
}
if(controlsToValidate[i].decimal == 1)
{
//Validate that the value is decimal
if(IsDecimal(document.getElementById(
controlsToValidate[i].elementid)) == false)
{
valid = false;
message += document.getElementById(
controlsToValidate[i].elementid).name +
" is not a decimal.\n";
}
}
if(controlsToValidate[i].nonnegdecimal == 1)
{
//Validate that the value is decimal
if(IsNonNegDecimal(document.getElementById(
controlsToValidate[i].elementid)) == false)
{
valid = false;
message += document.getElementById(
controlsToValidate[i].elementid).name +
" is not a positive decimal.\n";
}
}
if(controlsToValidate[i].ipaddress == 1)
{
//Validate that the value is decimal
if(IsIpAddress(document.getElementById(
controlsToValidate[i].elementid)) == false)
{
valid = false;
message += document.getElementById(
controlsToValidate[i].elementid).name +
" is not an IP Address.\n";
}
}
}
if (valid == false)
{
alert (message);
}
return valid;
}
//** END Main Validation Routine **
It's not as complicated as it looks, or if you have a fair understanding of JavaScript, it is as simple as it looks. Basically, the routine loops around the array and processes the element according to the validation you specified. Obviously, it's simple to add more validation routines to fit whatever your requirements are. At the top of this file, you can see the code for the ControlDetail
object. Maybe not the best name, but I was in a hurry, story of a developer's life. Let me know what you think. Improvements etc. I'm sure you will. Please remember to check out my blog / site: www.chemlock.co.uk.