/*
========================================================================
TITLE:		validate.js
------------------------------------------------------------------------
AUTHOR:		Mark Beaton
					mark@beaton.co.nz
------------------------------------------------------------------------
CREATED:	08 Jul 2002
------------------------------------------------------------------------
PARAMS:		Depend on validation function being used. See each function 
					for details
------------------------------------------------------------------------
NOTES:		Provides a range of validation functions. Needs to be used in 
					the following way:
					1)	Set form to validate by calling setValidateForm()
					2)	Add a validator (there is a list below) by using the 
							addValidator() function - you can apply multiple 
							validators to each input
					3)	On a form submission event, call the main validateForm() 
							which will return true if the form validates, and false 
							if not (as well as alerting the user to the problems).
					
					Example...
					Include this script:	
					<script type="text/javascript" src="validator.js"></script>
						
					Form which calls the main validateForm() when submitted: 
					<form action="myAction" onsubmit="return validateForm()">
						Email Address: <input type="text" name="email_addr">
						<input type="submit" value="Submit Form">
					</form>
					
					Set up validators (should be placed after the form(s) to 
					validate):
					<script type="text/javascript">
					setValidateForm('document.forms["myForm"]','#FFFF00'); 
					addValidator('isEmailAddress','email_address','Email Address');
					</script>
					
					Based on a concept by David Lowndes, re-written because I
					lost his script...
------------------------------------------------------------------------
MODIFIED:	13 Oct 2003 - Added new validators
					31 Oct 2003 - Added new validators, now re-initialises on each
						call to setValidateForm() (i.e. resets vArray)
========================================================================
*/

/*
========================================================================
AVAILABLE VALIDATORS (add to this as you please, but please document!)
------------------------------------------------------------------------
NOTES:		REQUIRED PARAMETERS
					There a 3 required parameters for each validator. These need 
					to be the first 3, in consecutive order. These are strings, 
					which will be eval()'d if necessary. They are:
					 - The name of the validator (case-sensitive)
					 - The name of the form input to validate (case-sensitive)
					 - A friendly name for the form input, for display in alerts
					For example:
						 addValidator("isEmailAddress","email","Email Address");
					
					OPTIONAL PARAMETERS
					These must be strings - it is up to each validator to eval() 
					into objects if necessary. They must also be passed in the 
					same order that the validator understands. There is no limit
					to how many optional parameters can be passed.
------------------------------------------------------------------------
isNotEmpty
Tests to see if form value contains at lease 1 non-whitespace character
Usage: addValidator("isNotEmpty","first_name","First Name");
------------------------------------------------------------------------
isEmailAddress
Tests to see if form value is a syntactically valid email address 
Usage: addValidator("isEmailAddress","email","Email Address");
------------------------------------------------------------------------
isLessThan
Tests to see if form value is less than a given number (to be passed as 
the fourth parameter) 
Usage:	addValidator("isLessThan","amount","Amount",1000);
------------------------------------------------------------------------
isSameValue
Tests to see if form value is equal to another form value (to be passed 
as the fourth parameter, description passed as fifth parameter) 
Usage: addValidator("isSameValue","pass2","Confirm","pass1","Password");
------------------------------------------------------------------------
isLessThanEqual
Tests to see if form value is less than or equal to a given number (to 
be passed as the fourth parameter) 
Usage: addValidator("isLessThanEqual","amount","Amount",1000);
------------------------------------------------------------------------
isGreaterThan
Tests to see if form value is greater than a given number (to be passed 
as the fourth parameter) 
Usage: addValidator("isGreaterThan","amount","Amount",1000);
------------------------------------------------------------------------
isGreaterThanEqual
Tests to see if form value is greater than or equal to a given number 
(to be passed as the fourth parameter) 
Usage: addValidator("isGreaterThanEqual","amount","Amount",1000);
------------------------------------------------------------------------
isBetween
Tests to see if form value is between two given numbers, inclusive of 
those numbers (to be passed as the 4th & 5th parameters in any order)
Usage: addValidator("isBetween","amount","Amount",10,20);
------------------------------------------------------------------------
isBetweenExclusive
Tests to see if form value is between two given numbers, exclusive of 
those numbers (to be passed as the 4th & 5th parameters in any order)
Usage: addValidator("isBetweenExclusive","amount","Amount",10,20);
------------------------------------------------------------------------
isValidChars
Tests to see if form value contains only the characters specified in 
the fourth parameter.
Usage: addValidator("isValidChars","hex","Colour","1234567890ABCDEF");
------------------------------------------------------------------------
isValidDate
Tests to see if form value can be parsed as a valid Date object.
Usage: addValidator("isValidDate","date","Date");
------------------------------------------------------------------------
isDateBefore
Tests to see if a Date is before another Date (to be passed as the 
fourth parameter, description passed as fifth parameter) 
Usage: addValidator("isDateBefore","date","Date","date2","Date 2");
------------------------------------------------------------------------
isDateBeforeEqual
Tests to see if a Date is before or equal to another Date (to be passed 
as the fourth parameter, description passed as fifth parameter) 
Usage: addValidator("isDateBefore","date","Date","date2","Date 2");
------------------------------------------------------------------------
isDateAfter
Tests to see if a Date is after another Date (to be passed as the 
fourth parameter, description passed as fifth parameter) 
Usage: addValidator("isDateAfter","date","Date","date2","Date 2");
------------------------------------------------------------------------
isDateAfterEqual
Tests to see if a Date is equal to or after another Date (to be passed 
as the fourth parameter, description passed as fifth parameter) 
Usage: addValidator("isDateAfter","date","Date","date2","Date 2");
------------------------------------------------------------------------
isDateEqual
Tests to see if a Date is euqal to another Date (to be passed as the 
fourth parameter, description passed as fifth parameter) 
Usage: addValidator("isDateEqual","date","Date","date2","Date 2");
------------------------------------------------------------------------
isLessChars
Tests to see if form value character count is less than the integer 
specified in the fourth parameter.
Usage: addValidator("isLessChars","password","Password",16);
------------------------------------------------------------------------
isLessEqualChars
Tests to see if form value character count is less than or equal to the 
integer specified in the fourth parameter.
Usage: addValidator("isLessEqualChars","password","Password",16);
------------------------------------------------------------------------
isMoreChars
Tests to see if form value character count is greater than the integer 
specified in the fourth parameter.
Usage: addValidator("isMoreChars","password","Password",16);
------------------------------------------------------------------------
isMoreEqualChars
Tests to see if form value character count is greater than or equal to 
the integer specified in the fourth parameter.
Usage: addValidator("isMoreEqualChars","password","Password",16);
------------------------------------------------------------------------
isEqualChars
Tests to see if form value character count is equal to the integer 
specified in the fourth parameter.
Usage: addValidator("isEqualChars","password","Password",16);
------------------------------------------------------------------------
isNumeric
Tests to see if form value is a valid number.
Usage: addValidator("isNumeric","length","Length");
------------------------------------------------------------------------
isInteger
Tests to see if form value is a valid integer.
Usage: addValidator("isInteger","num_people","Number of People");
------------------------------------------------------------------------
isRadioChecked
Tests to see if a radio button group has a selection.
Usage: addValidator("isRadioChecked","contact_method","Contact Method");
========================================================================
*/

/*
========================================================================
GLOBAL VARIABLES
========================================================================
*/
var isValid = false;
var vArray = new Array();
var vForm = null;
var eClr = null;
var errorArray = new Array();
	
/*
========================================================================
setValidateForm(formObjectAsString)
This is the init function that needs to be called (just once, unless 
you want to validate multiple forms) before each validator can be used.
Parameters:
 - formObjectAsString: The FORM object to apply the validation to, as a 
   string.
 - errorColour: The colour to apply to Form inputs that contain errors 
   (supported browsers only) in #RRGGBB format
Example:
  setValidateForm("document.forms['myForm']","#FFFF00"); 
========================================================================
*/
function setValidateForm(formObjectAsString,errorColour)
{
	vArray = new Array();
	// convert to object if passed as string
	vForm = formObjectAsString;
	// check form exists
	if(!vForm)
	{
		var temp = "The form object is not valid. Possible reasons:";
		temp += "\n  -  You are trying to reference a form object before it has loaded - move the script containing \n     the call to setValidateForm() after the form object";
		temp += "\n  -  If using the document.forms['myForm'] method, incorrect name supplied";
		temp += "\n  -  If using the document.forms[0] method, incorrect index supplied";
		temp += "\n  -  If using the document.getElementById('myForm') method, incorrect name supplied";
		temp += "\n  -  If using the document.getElementById(0) method, incorrect index supplied";
		temp += "\n  -  If your browser is Netscape 4.x and the form is nested in a <LAYER>, your object reference \n     could be wrong - check Netscape 4.x's DOM documentation for more info on this"
		alert(temp);
		return false;
	}
	eClr = errorColour;
}

/*
addValidator()
This builds up the validator array in memory - actually an array of 
arrays, with each sub-array holding the parameter information. The 
actual validation is not done until the main validateForm() is called, 
which then uses this array to perform the validation.
As the arguments passed vary depending on the validator used, we 
extract these values using the arguments property of the Function 
object.
*/
function addValidator()
{
	// arguments is an array itself, so append to main vArray
	vArray[vArray.length] = arguments;
}


/*
clearValidators()
If needed, this will clear the validator array (helpful when using in 
multiple forms on a page) 
*/
function clearValidator()
{
	vArray = new Array();
}


/*
validateForm()
This does the actual validation based on the contents of vArray & 
returns true|false depending on results.
Also, make each actual validator a function local to this, so we can 
avoid any possible global name conflicts, and make it hard to call the 
validators indivudually...
*/
function validateForm()
{
  /*
  ======================================================================
  BEGIN VALIDATION FUNCTIONS
  Add to this as you please, but please add a separating comment line 
  between each function to ease readability, and try to keep utility 
  functions nested within your main validator function, unless it is of 
  universal use (such as the trim() function) in which case add to the 
  "Handy Functions" section at the bottom.
  ======================================================================
  */

  /*
	======================================================================
	isNotEmpty() - Author: Mark Beaton, Added: 09 Jul 2002
	*/
	function isNotEmpty(ipt,txt)
	{
		ipt = eval(ipt);
		ipt.value = trim(ipt.value);
		if (!ipt.value)
		{
			errorArray[errorArray.length] = new Array("\"" + txt + "\" must contain a value",ipt);
		}
	}
  /*
	======================================================================
	isEmailAddress() - Author: Mark Beaton, Added: 08 Jul 2002
	*/
	function isEmailAddress(ipt,txt)
	{
		ipt = eval(ipt);
		ipt.value = trim(ipt.value);
		if (ipt.value.indexOf("@") == -1) errorArray[errorArray.length] = new Array("\"" + txt + "\" must contain the @ symbol (e.g. user@server.com)",ipt);
		else
		{
			var emailTemp = ipt.value.split("@");
			if (emailTemp.length > 2) errorArray[errorArray.length] = new Array("\"" + txt + "\" must contain only one @ symbol",ipt);
			else if (!emailTemp[0].length) errorArray[errorArray.length] = new Array("\"" + txt + "\" must contain something before the @ symbol (e.g. user@server.com)",ipt);
			else if (!validChars(emailTemp[0])) errorArray[errorArray.length] = new Array("\"" + txt + "\" must contain only valid characters before the @ symbol (a-z,A-Z,0-9,dash/hyphen,underscore,dot)",ipt);
			else if (!emailTemp[1].length) errorArray[errorArray.length] = new Array("\"" + txt + "\" must contain something after the @ symbol (e.g. user@server.com)",ipt);
			else if (emailTemp[1].indexOf(".") == -1) errorArray[errorArray.length] = new Array("\"" + txt + "\" must contain at least one dot (.) after the @ symbol (e.g. user@server.com)",ipt);
			else if (emailTemp[1].indexOf(".") == 0 || emailTemp[1].lastIndexOf(".") == emailTemp[1].length-1) errorArray[errorArray.length] = new Array("\"" + txt + "\" cannot contain the dot (.) as the first or last character after the @ symbol",ipt);
			else if (!validChars(emailTemp[1])) errorArray[errorArray.length] = new Array("\"" + txt + "\" must contain only valid characters after the @ symbol (a-z,A-Z,0-9,dash/hyphen,underscore,dot)",ipt);
			else if (emailTemp[1].indexOf("..") != -1) errorArray[errorArray.length] = new Array("\"" + txt + "\" cannot contain two adjacent dots (..) after the @ symbol",ipt);
		}
	}
  /*
	======================================================================
  isSameValue() - Author: Mark Beaton, Added: 14 Jul 2002
	*/
	function isSameValue(ipt,txt,ipt2,txt2)
	{
		ipt = eval(ipt);
		ipt.value = trim(ipt.value);
		ipt2 = eval(vForm + "." + ipt2);
		ipt2.value = trim(ipt2.value);
		if (ipt.value == "") errorArray[errorArray.length] = new Array("\"" + txt + "\" must contain a value ",ipt);
		else if (ipt.value != ipt2.value) errorArray[errorArray.length] = new Array("\"" + txt + "\" must be the same as \"" + txt2 + "\"",ipt);
	}
  /*
	======================================================================
  isLessThan() - Author: Mark Beaton, Added: 09 Jul 2002
	*/
	function isLessThan(ipt,txt,val)
	{
		ipt = eval(ipt);
		ipt.value = trim(ipt.value);
		if (isNaN(ipt.value) || ipt.value == "") errorArray[errorArray.length] = new Array("\"" + txt + "\" must be a valid number less than " + val,ipt);
		else if (parseFloat(ipt.value) >= val) errorArray[errorArray.length] = new Array("\"" + txt + "\" must be less than " + val,ipt);
		else ipt.value = parseFloat(ipt.value);
	}
  /*
	======================================================================
  isLessThanEqual() - Author: Mark Beaton, Added: 09 Jul 2002
	*/
	function isLessThanEqual(ipt,txt,val)
	{
		ipt = eval(ipt);
		ipt.value = trim(ipt.value);
		if (isNaN(ipt.value) || ipt.value == "") errorArray[errorArray.length] = new Array("\"" + txt + "\" must be a valid number less than or equal to " + val,ipt);
		else if (parseFloat(ipt.value) > val) errorArray[errorArray.length] = new Array("\"" + txt + "\" must be less than or equal to " + val,ipt);
		else ipt.value = parseFloat(ipt.value);
	}
  /*
	======================================================================
  isGreaterThan() - Author: Mark Beaton, Added: 09 Jul 2002
	*/
	function isGreaterThan(ipt,txt,val)
	{
		ipt = eval(ipt);
		ipt.value = trim(ipt.value);
		if (isNaN(ipt.value) || ipt.value == "") errorArray[errorArray.length] = new Array("\"" + txt + "\" must be a valid number greater than " + val,ipt);
		else if (parseFloat(ipt.value) <= val) errorArray[errorArray.length] = new Array("\"" + txt + "\" must be greater than " + val,ipt);
		else ipt.value = parseFloat(ipt.value);
	}
  /*
	======================================================================
  isGreaterThanEqual() - Author: Mark Beaton, Added: 09 Jul 2002
	*/
	function isGreaterThanEqual(ipt,txt,val)
	{
		ipt = eval(ipt);
		ipt.value = trim(ipt.value);
		if (isNaN(ipt.value) || ipt.value == "") errorArray[errorArray.length] = new Array("\"" + txt + "\" must be a valid number greater than or equal to " + val,ipt);
		else if (parseFloat(ipt.value) < val) errorArray[errorArray.length] = new Array("\"" + txt + "\" must be greater than or equal to " + val,ipt);
		else ipt.value = parseFloat(ipt.value);
	}
  /*
	======================================================================
  isBetween() - Author: Mark Beaton, Added: 09 Jul 2002
	*/
	function isBetween(ipt,txt,val1,val2)
	{
		ipt = eval(ipt);
		ipt.value = trim(ipt.value);
		var lower = (val1 < val2) ? val1:val2;
		var upper = (val1 < val2) ? val2:val1;
		if (isNaN(ipt.value) || ipt.value == "") errorArray[errorArray.length] = new Array("\"" + txt + "\" must be a valid number between " + lower + " & " + upper + " (inclusive)",ipt);
		else if (parseFloat(ipt.value) < lower || parseFloat(ipt.value) > upper) errorArray[errorArray.length] = new Array("\"" + txt + "\" must be between " + lower + " & " + upper + " (inclusive)",ipt);
		else ipt.value = parseFloat(ipt.value);
	}
  /*
	======================================================================
  isBetweenExclusive() - Author: Mark Beaton, Added: 09 Jul 2002
	*/
	function isBetweenExclusive(ipt,txt,val1,val2)
	{
		ipt = eval(ipt);
		ipt.value = trim(ipt.value);
		var lower = (val1 < val2) ? val1:val2;
		var upper = (val1 < val2) ? val2:val1;
		if (isNaN(ipt.value) || ipt.value == "") errorArray[errorArray.length] = new Array("\"" + txt + "\" must be a valid number between " + lower + " & " + upper + " (exclusive)",ipt);
		else if (parseFloat(ipt.value) <= lower || parseFloat(ipt.value) >= upper) errorArray[errorArray.length] = new Array("\"" + txt + "\" must be between " + lower + " & " + upper + " (exclusive)",ipt);
		else ipt.value = parseFloat(ipt.value);
	}
  /*
	======================================================================
  isValidChars() - Author: Mark Beaton, Added: 14 Jul 2002
	*/
	function isValidChars(ipt,txt,chars)
	{
		ipt = eval(ipt);
		ipt.value = trim(ipt.value);
		if (!validChars(ipt.value,chars)) errorArray[errorArray.length] = new Array("\"" + txt + "\" may only contain the following characters '" + chars + "'",ipt);
	}
  /*
	======================================================================
  isValidDate() - Author: Mark Beaton, Added: 13 Oct 2003
	*/
	function isValidDate(ipt,txt)
	{
		ipt = eval(ipt);
		ipt.value = trim(ipt.value);
		if (!ipt.value || !Date.parse(ipt.value)) errorArray[errorArray.length] = new Array("\"" + txt + "\" must be in a valid date format",ipt);
	}
  /*
	======================================================================
  isDateBefore() - Author: Mark Beaton, Added: 13 Oct 2003
	*/
	function isDateBefore(ipt,txt,testDate,testDateTxt)
	{
		ipt = eval(ipt);
		ipt.value = trim(ipt.value);
		if (Date.parse(ipt.value) >= Date.parse(testDate)) errorArray[errorArray.length] = new Array("\"" + txt + "\" must be earlier than \"" + testDateTxt + "\"",ipt);
	}
  /*
	======================================================================
  isDateBeforeEqual() - Author: Mark Beaton, Added: 21 Nov 2003
	*/
	function isDateBeforeEqual(ipt,txt,testDate,testDateTxt)
	{
		ipt = eval(ipt);
		ipt.value = trim(ipt.value);
		if (Date.parse(ipt.value) > Date.parse(testDate)) errorArray[errorArray.length] = new Array("\"" + txt + "\" must be earlier than or equal to \"" + testDateTxt + "\"",ipt);
	}
  /*
	======================================================================
  isDateAfter() - Author: Mark Beaton, Added: 13 Oct 2003
	*/
	function isDateAfter(ipt,txt,testDate,testDateTxt)
	{
		ipt = eval(ipt);
		ipt.value = trim(ipt.value);
		if (Date.parse(ipt.value) <= Date.parse(testDate)) errorArray[errorArray.length] = new Array("\"" + txt + "\" must be later than \"" + testDateTxt + "\"",ipt);
	}
  /*
	======================================================================
  isDateAfterEqual() - Author: Mark Beaton, Added: 13 Oct 2003
	*/
	function isDateAfterEqual(ipt,txt,testDate,testDateTxt)
	{
		ipt = eval(ipt);
		ipt.value = trim(ipt.value);
		if (Date.parse(ipt.value) < Date.parse(testDate)) errorArray[errorArray.length] = new Array("\"" + txt + "\" must be equal to or later than \"" + testDateTxt + "\"",ipt);
	}
  /*
	======================================================================
  isDateEqual() - Author: Mark Beaton, Added: 13 Oct 2003
	*/
	function isDateEqual(ipt,txt,testDate,testDateTxt)
	{
		ipt = eval(ipt);
		ipt.value = trim(ipt.value);
		if (Date.parse(ipt.value) != Date.parse(testDate)) errorArray[errorArray.length] = new Array("\"" + txt + "\" must be equal to \"" + testDateTxt + "\"",ipt);
	}
  /*
	======================================================================
  isLessChars() - Author: Mark Beaton, Added: 31 Oct 2003
	*/
	function isLessChars(ipt,txt,val)
	{
		ipt = eval(ipt);
		if (ipt.value.length >= val) errorArray[errorArray.length] = new Array("\"" + txt + "\" must be less than " + val + " characters in length",ipt);
	}
  /*
	======================================================================
  isLessEqualChars() - Author: Mark Beaton, Added: 31 Oct 2003
	*/
	function isLessEqualChars(ipt,txt,val)
	{
		ipt = eval(ipt);
		if (ipt.value.length > val) errorArray[errorArray.length] = new Array("\"" + txt + "\" must be less than or equal to " + val + " characters in length",ipt);
	}
  /*
	======================================================================
  isMoreChars() - Author: Mark Beaton, Added: 31 Oct 2003
	*/
	function isMoreChars(ipt,txt,val)
	{
		ipt = eval(ipt);
		if (ipt.value.length <= val) errorArray[errorArray.length] = new Array("\"" + txt + "\" must be more than " + val + " characters in length",ipt);
	}
  /*
	======================================================================
  isMoreEqualChars() - Author: Mark Beaton, Added: 31 Oct 2003
	*/
	function isMoreEqualChars(ipt,txt,val)
	{
		ipt = eval(ipt);
		if (ipt.value.length < val) errorArray[errorArray.length] = new Array("\"" + txt + "\" must be more than or equal to " + val + " characters in length",ipt);
	}
  /*
	======================================================================
  isEqualChars() - Author: Mark Beaton, Added: 31 Oct 2003
	*/
	function isEqualChars(ipt,txt,val)
	{
		ipt = eval(ipt);
		if (ipt.value.length != val) errorArray[errorArray.length] = new Array("\"" + txt + "\" must be " + val + " characters in length",ipt);
	}
  /*
	======================================================================
  isNumeric() - Author: Mark Beaton, Added: 13 Nov 2003
	*/
	function isNumeric(ipt,txt)
	{
		ipt = eval(ipt);
		ipt.value = trim(ipt.value);
		if (ipt.value.length == 0 || isNaN(ipt.value)) errorArray[errorArray.length] = new Array("\"" + txt + "\" must be a valid number",ipt);
	}
  /*
	======================================================================
  isInteger() - Author: Mark Beaton, Added: 13 Nov 2003
	*/
	function isInteger(ipt,txt)
	{
		ipt = eval(ipt);
		ipt.value = trim(ipt.value);
		if (ipt.value.length == 0 || isNaN(ipt.value) || ipt.value.indexOf(".") != -1) errorArray[errorArray.length] = new Array("\"" + txt + "\" must be a valid number",ipt);
	}
  /*
	======================================================================
  isChecked() - Author: Mark Beaton, Added: 17 Nov 2003
	*/
	function isRadioChecked(ipt,txt)
	{
		ipt = eval(ipt);
		var hasSelection = false;
		for (var i=0; i<ipt.length; i++)
		{
			if (ipt[i].checked)
			{
				hasSelection = true;
			}
		}
		if (hasSelection == false) errorArray[errorArray.length] = new Array("\"" + txt + "\" has not been selected",ipt);
	}
  /*
	======================================================================
	*/
	
  /*
  ======================================================================
  HANDY FUNCTIONS
  ======================================================================
  */
	
  /*
	======================================================================
  trim(theString) - Author: Mark Beaton, Added: 08 Jul 2002
	Trims whitespace from each end of the string passed as the 
	parameter, and returns clean version to caller
	*/
	function trim(theString)
	{
		var newString = theString;
		while (newString.charAt(0) == " " || newString.charCodeAt(0) == 10 || newString.charCodeAt(0) == 13 || newString.charCodeAt(0) == 9) {
			newString = newString.substring(1,newString.length);
		}
		while (newString.charAt(newString.length - 1) == " " || newString.charCodeAt(newString.length - 1) == 10 || newString.charCodeAt(newString.length - 1) == 13 || newString.charCodeAt(newString.length - 1) == 9) {
			newString = newString.substring(0,newString.length - 1);
		}
		return newString;
	}
  /*
	======================================================================
  validChars(theString,customChars) - Author: Mark Beaton, Added: 08 Jul 2002
	Returns true if the string contains only valid chars, false if not.
	The customChars param is used to override the default safeChars 
	*/
	function validChars(theString,customChars)
	{
		if (customChars) var safeChars = customChars;
		else var safeChars = "abcdefghijklmnopqrstuvwxyz0123456789-_.";
		for (var i=0; i<theString.length; i++)
		{
			if (safeChars.indexOf(theString.charAt(i).toLowerCase()) == -1)
			{
				return false;
			}
		}
		return true;
	}
  /*
	======================================================================
  setColour(theInput) - Author: Mark Beaton, Added: 08 Jul 2002
	Sets colour of form inputs, or maybe reset to defaults if flag passed
	*/
	function setColour(theInput,reset)
	{
		if (reset) var tempClr = "";
		else tempClr = eClr;
		if (tempInput.style)
		{
			switch (tempInput.type)
			{
				case "text" :
					tempInput.style.backgroundColor = tempClr;
					break;
				case "password" :
					tempInput.style.backgroundColor = tempClr;
					break;
				case "select" :
					tempInput.style.backgroundColor = tempClr;
					break;
				case "select-one" :
					tempInput.style.backgroundColor = tempClr;
					break;
				case "select-multiple" :
					tempInput.style.backgroundColor = tempClr;
					break;
				case "textarea" :
					tempInput.style.backgroundColor = tempClr;
					break;
			}
		}
	}
  /*
	======================================================================
	*/

  /*
  ======================================================================
  THE GUTS OF IT ALL
  ======================================================================
  */
	// Firstly, if this has already been called there maybe inputs whose 
	// value is now OK, so we'll reset each background colour to the 
	// defaults so we can start from a clean slate
	for (var i=0; i<vArray.length; i++)
	{
		var tempStr = "";
		var tempArray = vArray[i];
		tempInput = eval(vForm + "." + tempArray[1]);
		setColour(tempInput,1);
	}
	// For each vArray item (i.e. each validator), build & evaluate 
	// associated function
	for (var i=0; i<vArray.length; i++)
	{
		var tempStr = "";
		var tempArray = vArray[i];
		// Assign first 3 elements manually, as these are required params
		tempStr += tempArray[0] + "('" + vForm + "." + tempArray[1] + "','" + tempArray[2] + "'";
		// As the rest (if any) are optional params, loop & add to string
		for (var i2=3; i2<tempArray.length; i2++)
		{
			tempStr += ",'" + tempArray[i2] + "'";
		}
		// Finish of the string, ready for eval()
		tempStr += ");";
		// Righto. eval() away...
		eval(tempStr);
	}
	
	// check length of errorArray, alert if not empty, return true if all 
	// hunky-dory
	if (errorArray.length)
	{
		var tempStr = "";
		for (var i=0; i<errorArray.length; i++)
		{
			var tempError = errorArray[i];
			tempStr += "\n - " + tempError[0];
		}
		// Alert user to form problems
		alert("There " + ((errorArray.length==1)?"was a problem":"were problems") + " with the form submission:   \n" + tempStr);
		// Colour in form fields if supported
		for (var i=0; i<errorArray.length; i++)
		{
			var tempError = errorArray[i];
			tempInput = tempError[1];
			setColour(tempInput);
		}
		// Focus topmost error
		var tempError = errorArray[0];
		if (tempInput.type && tempInput.type != "hidden") tempInput.focus();
		// Reset error array
		errorArray = new Array();
		return false;
	}
	else return true;
}

