/***************************************************************************************************

*

*-- Form validation script by Peter Bailey copyright 2001-2002

*	Version 2.1b

*	Updated on July 24, 2002

*	www.peterbailey.net

*	me@peterbailey.net

*

*	IF YOU USE THIS SCRIPT, GIVE ME CREDIT PLEASE =)

*

*	Please contact me with any questions, comments, problems, or suggestions

*	This script has only been validated on various versions of Windows with IE4+

*

*	!!! For easiest reading of this document, set your text-editor's tab spacing to 4 !!!

*

*-- Table of Contents (More like an order of appearance for this document)

*	-- How to use it

*	-- Options

*	-- How it works

*	-- Validation Type List

*	-- Using bok

*	-- Additional Notes

*	-- Future Additions

*	-- Globals and Constants (for all functions expect Credit Card functions)

*	-- *** Source code for all functions except Credit Card functions ***

*	-- Documentation plus Globals and Constants for Credit Card functions

*	-- *** Source code for all Credit Card functions ***

*	-- EOD

*

*--	How to use it:

*

*	This function set will allow you to validate form input onSubmit very easily and efficiently.

*	Here is the process

*	

*		1)  Include the validate.js file to the page

*			Example: <script language="javascript" src="js/validate.js"></script>

*		2) 	add this event to any form you want validated:

*			[CODE]  onSubmit="return validateForm(this)  [/CODE]

*			Example: <form name="form1" action="" method="post" onSubmit="return validateForm(this)">

*		3)	Add 'alt' attributes with appropriate values to form objects you want validated

*

*		That's it!  Three easy steps!

*

*--	Options

*

*		1)	Add two parameters to the function validateForm.  The two optional parameters are bConfirm and bDisable

*			bConfirm, if set to 1, will prompt the user with a confirm just before submission.  The globla varaible

*			'confirmMsg' will be the text for the CONFIRM popup.

*			bDisable, if set to 1, will disable the submit button after a successful validation, thus preventing 

*			multiple submission of the same data.

*			Syntax:		validateForm(this[,bConfirm, bDisable]);

*						this		- object.  required.

*						bConfirm	- boolean.  optional

*						bDisable	- boolean.  optional

*			Example: 	<form name="form1" action="" method="post" onSubmit="return validateForm(this,1,1)">

*

*		2)  To enable 'error coloring', that is, where the form object that generates an error receives new style

*			properties via CSS, create a class in your CSS, enter it's name into the 'errorClass' constant and add the

*			onFocusOut event to the form calling the function clearStyle()

*			Example:	<style>

*						.errHilite {

*							background-color: #FFCCCC;

*						}

*						</style>

*						<form name="form1" action="" method="post" onSubmit="return validateForm(this)" onFocusOut="clearStyle(event.srcElement)">

*

*		3)	Sometimes more often than not, we want to validate user input format without requiring

*			the field entirely.  We just want to check it's format ONLY if they've acutally entered

*			data in.  By adding the optional parameter 'bok' to any validation type, you tell this 

*			script to validate the data, only if data has been entered.  Please see the section

*	

*

*-- How it works:

*

*	This function loops through each element in the form and checks for the existence of the alt

*	attribute.  If it exists, the data within the attribute is used the validate the associated

*	form object.  If you don't want an object validated, simply do not add any alt attribute!  

*	So, you can validate and entire form (like a credit app) in seconds! No hard-coding of form

*	names or any silly nonsense like that. Easy to add your own validation types (like checking

*	a promotional code format)

*

*	This system utilizes the pipe character '|' to separate parameters for the validation type.

*	All the required parameters are listed with each validation type below, but there is one 

*	optional parameter, 'bok'.  Please read the section at the bottom of the list titled "Using bok"

*

*	One of the optional functions you can use is clearStyle().  This script by default adds the 

*	className contained in the constant 'errorClass' to any object that requires input changes from 

*	the user.  So, by changing the value of 'errorClass' to the name of and CSS class you want to

*	use for error display, any of the rules you set in that class will be applied to the object.

*	The clearStyle() function, when properly assigned to the FORM object, will clear or reset the 

*   style only if it currently has the style set by 'errorClass'

*

*-- Validation type list

*

*  ------------------------------------------------------------------------------------------------	

*	blank

*	

*			Errors if:	Field is left blank

*			Syntax: 	<input type="text" name="First_Name" alt="blank" />

*			Use with: 	INPUT type=text, INPUT type=password, TEXTAREA

*  ------------------------------------------------------------------------------------------------			

*	length|min

*	

*			Errors if:	Field does not meet minimum length set

*			Syntax: 	<input type="password" name="Password" alt="length6" />

* 			Notes:		The number following the 'length' in the alt will be the

*		 				minimum required length. Do not add spaces or underscores.

*			Use with:	INPUT type=text, INPUT type=password, TEXTAREA

*  ------------------------------------------------------------------------------------------------	

*	number

*	

*			Errors if:	Field contains any character that are non-numeric (not 0-9)

*			Syntax: 	<input type="text" name="Age" alt="number" />

*			Use with:	INPUT type=text, INPUT type=password, TEXTAREA

*------------------------------------------------------------------------------------------------	

*	numberl|min

*	

*			Errors if:	Field contains any character that are non-numeric (not 0-9)

*						-AND- does not meet minimum length requirement

*			Syntax: 	<input type="text" name="ID_Number" alt="numberl4" />

*			Use with:	INPUT type=text, INPUT type=password, TEXTAREA

*  ------------------------------------------------------------------------------------------------

*	decimal|leftQuantity|rightQuantity

*	

*			Errors if:	Field data does not match decimal format specified

*			Syntax: 	<input type="text" name="Batting_Average" alt="decimal0|3" />

*			Notes:		Wildcards (*) can be used for either value

*			Examples:	decimal|*|2  matches '1234.12' -OR- '.34' -OR- '1234567890.00'

*						decimal|3|* matches '100.1' -OR- 123.987 -OR- '987.12345678'

*			Use with:	INPUT type=text, INPUT type=password, TEXTAREA

*  ------------------------------------------------------------------------------------------------

*	decimalr|leftMinimum|leftMaximum|rightMimimum|rightMaximum

*	

*			Errors if:	Field data does not match decimal format specified

*			Syntax: 	<input type="text" name="Radio_Station" alt="decimalr2/3|1\1" />

*			Notes:		Wildcards (*) can be used for any value

*			Examples:	decimalr3|*|2|3 matches '123.12' -OR- '12345678.12' -OR- '9876.123'

*						decimalr0|2|1|* matches '.1' -OR- '23.123456789' -OR- '1.98'

*			Use with:	INPUT type=text, INPUT type=password, TEXTAREA

*  ------------------------------------------------------------------------------------------------

*	money|flags

*			Errors if:	Field does not match money format specified

*			Syntax: 	<input type="text" name="Salary" alt="money&,." />

* 			Flags:		$ = Dollar sign required beginning of the string

*						, = Digit grouping must be applied (a comma between every 3rd digit)

*						. = The decimal plus 2 following digits is required at end of string

*			Notes:		The above flags can be used in any order and any combination.  If no flags

*						are set, then all rules become optional in the string.

*			Use with:	INPUT type=text, INPUT type=password, TEXTAREA

*  ------------------------------------------------------------------------------------------------	

*	zip	

*

*			Errors if:	Field does not match Zip or Zip+4 format

*			Syntax: 	<input type="text" name="Zip_Code" alt="zip" />

*			Formats:	12345

*						123451234

*						12345 1234

*						12345-1234

*			Use with:	INPUT type=text, INPUT type=password, TEXTAREA

*  ------------------------------------------------------------------------------------------------

*	phone

*

*			Errors if:	Field does not match phone format

*			Syntax: 	<input type="text" name="Phone" alt="phone" />

*			Formats:	Many different formats

*			Notes:		Knowledge of regular expression will let you modify the

*						validation scope to suit your needs

*			Use with:	INPUT type=text, INPUT type=password, TEXTAREA

*  ------------------------------------------------------------------------------------------------

*	email

*	

*			Errors if:	Field does not match email format

*			Syntax: 	<input type="text" name="Salary" alt="money" />

*			Formats:	user@domain.suffix				( john@internet.com )

*						user.sub@domain.suffix			( john.doe@internet.com )

*						user.sub@domain.subd.suffix		( john.doe@email.internet.com )

*						user@ip							( john@[192.168.1.1] )

*						And several combinations of the above formats

*			Use with:	INPUT type=text, INPUT type=password, TEXTAREA

*  ------------------------------------------------------------------------------------------------

*	select

*

*			Errors if:	Select object is selected at 0 index, indicating no selection made

*			Syntax: 	<select name="state" alt="select">[...options...]</select>

*			Use with:	SELECT (NOT for use with multiple select objects)

*  ------------------------------------------------------------------------------------------------

*	selecti|indexes

*

*			Errors if:	Select object is selected at any of the specified indexes

*			Syntax: 	<select name="Credit_Card_Type" alt="selecti|0,1,6">[...options...]</select>

*			Notes:		indexes must be a comma separated string with no spaces

*			Use with:	SELECT (NOT for use with multiple select objects)

*  ------------------------------------------------------------------------------------------------

*	selectm|min|max

*

*			Errors if:	Number of selections does not meet minimum/maximum bounds set

*			Syntax: 	<select name="Sandwich_Preferences" alt="selectm|1|3" multiple>

*						[...options...]

*						</select>

*			Notes:		For no minimum, enter 0.  For no maximum, enter 999

*						Example: alt="selectm0|999"

*			Use with:	SELECT (for use with multiple select objects)

*  ------------------------------------------------------------------------------------------------

*	checkbox|min|max

*

*			Errors if:	Number of checked boxes does not meet minimum/maximum bounds set

*			Syntax: 	<input type="checkbox" name="Subscribe_to" alt="checkbox|2|4" />

*						<input type="checkbox" name="Subscribe_to" />

*						<input type="checkbox" name="Subscribe_to" />

*						<input type="checkbox" name="Subscribe_to" />

*						<input type="checkbox" name="Subscribe_to" />

*			Notes:		All the names of the checkboxes to be included in the count must

*						be the same. Only add the 'alt' attribute to the first checkbox

*						in the array. For no minimum, enter 0.  For no maximum, enter 999

*						Example: alt="checkbox0|999"

*			Use with:	INPUT type=checkbox

*  ------------------------------------------------------------------------------------------------

*	radio

*

*			Errors if:	None of the radio boxes in the group are checked

*			Syntax: 	<input type="radio" name="Inline_Skating" value="Yes" alt="radio" />

*						<input type="radio" name="Inline_Skating" value="No" />

*			Notes:		All the names of the radio buttons to be included in the count must

*						be the same. Only add the 'alt' attribute to the first radio button

*						in the array. 

*			Use with:	INPUT type=radio

*  ------------------------------------------------------------------------------------------------

*	cc

*

*			Errors if:	Input does not validate against card rules spedified by the card type

*						-AND- does not satisfy the LUHN Checksum

*			Syntax: 	<input type="text" name="Credit_Card_Number" alt="cc" onBlur="this.value=cleanupCCNum(this.value)" />

*			Notes:		See documentation at bottom of this file for more information about

*						the credit card validation capabilities of this script

*			Use with:	INPUT type=text, INPUT type=password, TEXTAREA

*

*******************************************************************************************************

*-- Using bok

*

*		The optional parameter 'bok' can be added to ANY validation type that checks data on a text-

*		based input (INPUT type=text, INPUT type=password, TEXTAREA).  'bok' will allow the field to

*		be submitted blank, but validates it against it's normal rules if any data is entered.  For 

*		example, if you do not want to require the email address, but do want to receive valid email

*		address if the user choses to enter them, then add the 'bok' parameter with the pipe character

*

*			<input type="text" name="Email" alt="email|bok" />

*

*		The 'bok' parameter MUST ALWAYS be the last parameter.  If validating a decimal the syntax

*		would be as follows

*			

*			<input type="text" name="Batting_Average" alt="decimal|0|3|bok" />

*

*		'bok' should NOT be used with the 'blank' validation type

*

*--	Additional notes:

*

*		The function formatName at the bottom of this include strips form object names of their 

*		underscores. This is so that when the alert()s are used, the will not see the underscores.  

*		So, it is recommended that you name your fields accordingly for ease of reading to the user.

*		Example: 'First_Name' instead of 'fname' or 'Home_Phone' instead of 'HPhone'

*

*--	Future Additions

*

*		? Date validation

*		? Zip validation versus chosen State for geographical accuracy

*		? More specific control over validation format of Phone numbers and Postal codes

*

*******************************************************************************************************

*--	Constants and Globals

*		Global used for flagging the validateBlank() function within most other validation functions

*/		var blankOK = false;

/*		Global used for class switching.  Do not modify

*/		var revertClass = '';

/*		Change this to the classname you want for the error highlighting

*/		var errorClass = 'errHilite';

/*		If the bConfirm flag is set to true, the users will be prompted with CONFIRM box with this message

*/		var confirmMsg = 'Your Data is about to be sent.\nPlease click \'Ok\' to proceed or \'Cancel\' to abort.';

/*		If user cancels CONFIRM, then this message will be alerted.  If you don't want this alert to show, then

*		empty the variable (  var confirmAbortMsg = '';  )

*/		var confirmAbortMsg = 'Submission cancelled.  Data has not been sent.';

/*

*********** WARNING: DO NOT EDIT BELOW THIS LINE UNLESS YOU KNOW WHAT YOU ARE DOING! ****************/



function validateForm(Frm, bConfirm, bDisable)

	{

	var testOk;

	for (var i=0; i<Frm.elements.length; i++)						// Loops through all the form's elements

		{

		if (Frm.elements[i].alt)									// Gets the ALT text if it exists, starting the validation

			{

			var validateType = Frm.elements[i].alt;

			var validateObj = Frm.elements[i];

			testOk = false;			

			var params = validateType.split(/[|]/);					// Separates validation string into parameters

		

			if (params[0] == 'money')								// Sets flags for money syntax

				{

				var dollarsign	= (params[1].indexOf('$') != -1);

				var grouping	= (params[1].indexOf(',') != -1);

				var decimal		= (params[1].indexOf('.') != -1);

				}

			

			if (params[params.length-1] == 'bok')					// Sets flag if field is allowed to be blank

				blankOK = true;

				

			switch (params[0])										// Calls appropriate validation function based on type

				{

				case 'blank'	: if (validateBlank(validateObj)) testOk = true; break;

				case 'length'	: if (validateLength(validateObj, params[1])) testOk = true; break;

				case 'number'	: if (validateNumber(validateObj)) testOk = true; break;

				case 'numberl'	: if (validateNumberL(validateObj, params[1])) testOk = true; break;

				case 'decimal'	: if (validateDecimal(validateObj, params[1], params[2] )) testOk = true; break;

				case 'decimalr'	: if (validateDecimalR(validateObj, params[1], params[2], params[3], params[4] )) testOk = true; break;				

				case 'money'	: if (validateMoney(validateObj, dollarsign, grouping, decimal)) testOk = true; break;

				case 'zip'		: if (validateZip(validateObj)) testOk = true ;break;

				case 'phone'	: if (validatePhone(validateObj)) testOk = true; break;

				case 'email'	: if (validateEmail(validateObj)) testOk = true; break;

				case 'cc'		: if (validateCC(validateObj)) testOk = true; break;

				case 'select'	: if (validateSelect(validateObj)) testOk = true; break;

				case 'selectm'	: if (validateSelectM(validateObj, params[1], params[2])) testOk = true; break;

				case 'selecti'	: if (validateSelectI(validateObj, params[1])) testOk = true; break;

				case 'checkbox'	: if (validateCheckbox(validateObj, Frm.name, validateObj.name, params[1], params[2])) testOk = true; break;
				
				case 'checkboxindiv'	: if (validateCheckboxIndiv(validateObj, Frm.name, validateObj.name, params[1], params[2])) testOk = true; break;

				case 'radio'	: if (validateRadio(validateObj, Frm.name, validateObj.name)) testOk = true; break;

				// Add additional cases here

				default			: alert('Validation Type Not Found');

				}

			if (!testOk) return false;

			}		

		}

	if (typeof bConfirm == 'undefined') bConfirm = 0;				// Checks for submission flags

	if (typeof bDisable == 'undefined') bDisable = 0;	

	if (bConfirm)

		{

		if(!confirm(confirmMsg))

			{

			if (confirmAbortMsg != '') alert(confirmAbortMsg);		// Displays confim if requested

			return false;

			}

		}

	if (bDisable) Frm.Submit.disabled=true;							// Disables submit if requested

	return true;													// Form has been validated

	}



/***************************************************************************/

function validateBlank(formObj)

	{

	var objName = formatName(formObj.name);

	if (formObj.value == "")

		{

		alert('Please enter your '+objName);

		errorProcess(formObj,0,1);

		return false;

		}

	return true;

	}

	

/***************************************************************************/

function validateLength(formObj,len)

	{

	var objName = formatName(formObj.name);

	if (blankOK)

		{ blankOK=false; return true; }

	else if (!validateBlank(formObj)) 

		return false;

	

	if (formObj.value.length < parseInt(len))

		{

		alert('Your '+objName+' must be at least '+len+' characters long');

		errorProcess(formObj,1,1);

		return false;

		}		

	return true;

	}

	

/***************************************************************************/

function validateNumber(formObj)

	{

	var objName = formatName(formObj.name);

	if (blankOK)

		{ blankOK=false; return true; }

	else if (!validateBlank(formObj)) 

		return false;

	

	numReg = "^[0-9]*$"

	var regex = new RegExp(numReg);

	if (!regex.test(formObj.value))

		{

		window.alert('Only numeric values are valid for the '+objName);

		errorProcess(formObj,1,1);

		return false;

		}

	return true;

	}

/***************************************************************************/

function validateNumberL(formObj, len)

	{

	var objName = formatName(formObj.name);

	if (blankOK)

		{ blankOK=false; return true; }

	else if (!validateBlank(formObj)) 

		return false;

	

	numReg = "^[0-9]{"+parseInt(len)+",}$"

	var regex = new RegExp(numReg);

	if (!regex.test(formObj.value))

		{

		window.alert('A minimum of '+len+' numeric values are required for the '+objName);

		errorProcess(formObj,1,1);

		return false;

		}

	return true;

	}

/***************************************************************************/

function validateDecimal(formObj, lval, rval)

	{

	var objName = formatName(formObj.name);

	if (blankOK)

		{ blankOK=false; return true; }

	else if (!validateBlank(formObj)) 

		return false;

	

	(lval == '*')? lval = '*': lval = parseInt(lval);

	(rval == '*')? rval = '*': rval = parseInt(rval);

	var decReg = "";

	if (lval == 0)

		decReg = "^\\.[0-9]{"+rval+"}$";	

	else if (lval == '*')

		decReg = "^[0-9]"+lval+"\\.[0-9]{"+rval+"}$";

	else if (rval == '*')

		decReg = "^[0-9]{"+lval+"}\\.[0-9]"+rval+"$";

	else

		decReg = "^[0-9]{"+lval+"}\\.[0-9]{"+rval+"}$";

	var regex = new RegExp(decReg);

	if (!regex.test(formObj.value))

		{

		window.alert(formObj.value+' is not a valid '+objName+'.  Please re-enter the '+objName);

		errorProcess(formObj,1,1);

		return false;

		}

	return true;

	}

	

/***************************************************************************/

function validateDecimalR(formObj, lmin, lmax, rmin, rmax)

	{

	var objName = formatName(formObj.name);

	if (blankOK)

		{ blankOK=false; return true; }

	else if (!validateBlank(formObj)) 

		return false;

	

	(lmin == '*')? lmin = 0: lmin = parseInt(lmin);

	(lmax == '*')? lmax = '': lmax = parseInt(lmax);

	(rmin == '*')? rmin = 0: rmin = parseInt(rmin);

	(rmax == '*')? rmax = '': rmax = parseInt(rmax);

	var	decReg = "^[0-9]{"+lmin+","+lmax+"}\\.[0-9]{"+rmin+","+rmax+"}$"

	var regex = new RegExp(decReg);

	if (!regex.test(formObj.value))

		{

		window.alert(formObj.value+' is not a valid '+objName+'.  Please re-enter the '+objName);

		errorProcess(formObj,1,1);

		return false;

		}

	return true;

	}

	

/***************************************************************************/

function validateMoney(formObj, ds, grp, dml)

	{

	var objName = formatName(formObj.name);

	if (blankOK)

		{ blankOK=false; return true; }

	else if (!validateBlank(formObj)) 

		return false;

	

	var moneySyntax;

	if (ds && grp && dml)		// Dollar sign, grouping, and decimal

		{ moneyReg = "^\\$(?:(?:[0-9]{1,3},)(?:[0-9]{3},)*[0-9]{3}|[0-9]{1,3})(\\.[0-9]{2})$";	moneySyntax = "$XX,XXX.XX"; }

	if (ds && grp && !dml)		// Dollar sign and grouping

		{ moneyReg="^\\$(?:(?:[0-9]{1,3},)(?:[0-9]{3},)*[0-9]{3}|[0-9]{1,3})$"; moneySyntax="$XX,XXX"; }

	if (ds && !grp && dml)		// Dollar sign and decimal

		{ moneyReg="^\\$[0-9]*(\\.[0-9]{2})$"; moneySyntax="$XXXXX.XX"; }

	if (!ds && grp && dml)		// Grouping and decimal

		{ moneyReg="^(?:(?:[0-9]{1,3},)(?:[0-9]{3},)*[0-9]{3}|[0-9]{1,3})(\\.[0-9]{2})?$"; moneySyntax="XX,XXX.XX"; }

	if (ds && !grp && !dml)		// Dollar sign only

		{ moneyReg="^\\$[0-9]*$"; moneySyntax="$XXXXX"; }

	if (!ds && grp && !dml)		// Grouping only

		{ moneyReg="^(?:(?:[0-9]{1,3},)(?:[0-9]{3},)*[0-9]{3}|[0-9]{1,3})$"; moneySyntax="XX,XXX"; }

	if (!ds && !grp && dml)		// Decimal only

		{ moneyReg="^[0-9]*(\\.[0-9]{2})$"; moneySyntax="XXXXX.XX"; }

	if (!ds && !grp && !dml)	// No params set, all special chars become optional

		{ moneyReg="^\\$?(?:(?:[0-9]{1,3},?)(?:[0-9]{3},?)*[0-9]{3}|[0-9]{1,3})(\\.[0-9]{2})?$"; moneySyntax="[$]XX[,]XXX[.XX]"; }

	var regex = new RegExp(moneyReg);

	if (!regex.test(formObj.value))

		{

		window.alert(formObj.value+' does not match the required format of '+moneySyntax+' for '+objName+'.');

		errorProcess(formObj,1,1);

		return false;

		}

	return true;

	}



/***************************************************************************/

function validateSelect(formObj)

	{

	var objName = formatName(formObj.name);

	if (formObj.selectedIndex == 0)

		{

		alert('Please select the '+objName);

		errorProcess(formObj,0,1);

		return false;

		}

	return true;

	}

	

/***************************************************************************/

function validateSelectM(formObj, minS, maxS)

	{

	var objName = formatName(formObj.name);

	var selectCount = 0;

	if (maxS == 999) maxS = formObj.length;

	for (var i=0; i<formObj.length; i++)

		{

		if (formObj.options[i].selected)

			selectCount++; 

		}

	if (selectCount < minS || selectCount > maxS)

		{

		alert('Please select between '+minS+' and '+maxS+' '+objName+'.\nYou currently have '+selectCount+' selected');

		errorProcess(formObj,0,1);

		return false;

		}

	return true;

	}

	

/***************************************************************************/

function validateSelectI(formObj, indexes)

	{

	var objName = formatName(formObj.name);

	var arrIndexes =indexes.split(/[,]/);

	var selectOK = true;

	for (var i=0; i<arrIndexes.length; i++)

		{

		if (formObj.selectedIndex == arrIndexes[i])

			selectOK = false;

		}



	if (!selectOK)

		{

		alert('Please select a valid option for '+objName);

		errorProcess(formObj,0,1);

		return false;

		}

	return true;

	}

		

/***************************************************************************/

function validateZip(formObj)

	{

	var objName = formatName(formObj.name);

	if (blankOK)

		{ blankOK=false; return true; }

	else if (!validateBlank(formObj)) 

		return false;

	

	zipReg = "^[0-9]{5}(|[\- ]?[0-9]{4})$"

	var regex = new RegExp(zipReg);

	if (!regex.test(formObj.value))

		{

		window.alert("Please enter a valid 5 or 9 digit Zip code.    ");

		errorProcess(formObj,1,1);

		return false;

		}

	return true;

	}



/***************************************************************************/

function validateEmail(formObj)

	{	

	if (blankOK)

		{ blankOK=false; return true; }

	else if (!validateBlank(formObj)) 

		return false;



	var emailStr = formObj.value;

	var emailReg1 = /(@.*@)|(\.\.)|(@\.)|(\.@)|(^\.)/; // not valid

	var emailReg2 = /^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/; // valid

	if (!emailReg1.test(emailStr) && emailReg2.test(emailStr)) // if syntax is valid

		{

		return true;

		}

	else

		{

		window.alert("Please enter a valid Email address.");

		errorProcess(formObj,1,1);

		return false;

		}

	return true;

	}

	

/***************************************************************************/

function validatePhone(formObj)

	{

	var objName = formatName(formObj.name);

	if (blankOK)

		{ blankOK=false; return true; }

	else if (!validateBlank(formObj)) 

		return false;

	

	phoneReg = "^(?:[\(][0-9]{3}[\)]|[0-9]{3})[-. ]?[0-9]{3}[-. ]?[0-9]{4}$";

	var regex = new RegExp(phoneReg);

	if (regex.test(formObj.value))

		{

		return true;

		}

	else

		{

		window.alert("Please enter a valid Phone number plus Area Code.");

		errorProcess(formObj,1,1);

		return false;

		}

	return true;

	}

	

/***************************************************************************/

function validateCheckbox(formObj, FRM, chkbxName, minC, maxC)

	{

	var formObj = eval(FRM+'.'+chkbxName);

	var objName = chkbxName;

	var checkTotal = eval(FRM+'.'+chkbxName+'.length');

	var checkCount = 0;

	if (maxC == 999) maxC = checkTotal;

	for (var i=0; i<checkTotal; i++)

		{

		if (formObj[i].checked) checkCount++;

		}

	if (checkCount < minC || checkCount > maxC)

		{

		alert('Please select between '+minC+' and '+maxC+' options for '+objName+'.\nYou currently have '+checkCount+' selected');

		errorProcess(formObj[0],0,1);

		return false;

		}

	return true;

	}



/***************************************************************************/

function validateCheckboxIndiv(formObj, FRM, chkbxName, minC, maxC)

	{

	var formObj = eval(FRM+'.'+chkbxName);

	var objName = chkbxName;

	var checkTotal = eval(FRM+'.'+chkbxName+'.length');

	var checkCount = 0;

	if (maxC == 999) maxC = checkTotal;

	for (var i=0; i<checkTotal; i++)

		{

		if (formObj[i].checked) checkCount++;

		}

	if (checkCount < minC || checkCount > maxC)

		{

		alert('Please indicate your acceptance of '+objName+'.\n');

		errorProcess(formObj[0],0,1);

		return false;

		}

	return true;

	}



/***************************************************************************/	

function validateRadio(formObj, FRM, radioName)

	{	

	var radioLength = eval(FRM+'.'+radioName+'.length');

	var objName = formatName(formObj.name);

	var selectTotal = 0;

	for (i=0; i<radioLength; i++)

		{

		if (eval(FRM+'.'+radioName+'['+i+'].checked'))

			selectTotal++;	

		}

	if (selectTotal != 1)

		{

		alert('Please select an option for '+objName);

		errorProcess(formObj,0,1);

		return false;

		}		

	return true;

	}



/***************************************************************************/

function formatName(wStr)

	{

	wStr = wStr.replace(/_/g," ");

	return wStr;

	}

/***************************************************************************/	

function errorProcess(tempObj, sel, foc)

	{

	revertClass = tempObj.className;

	tempObj.className = errorClass;

	if (sel) tempObj.select();

	if (foc) tempObj.focus();

	}

/***************************************************************************/

function clearStyle(tempObj)

	{

	if (tempObj.className == errorClass) tempObj.className = revertClass;

	}



/****************************************** END EDIT WARNING ****************************************/	

	

/*****************************************************************************************************	

*	CREDIT CARD FUNCTIONS

*

*	If you want to use the credit card validating capabilities of this script, please read this

*	documentation before continuing

*

*--	Constants and Globals for Credit Card functions

*

*	Enter the DOM name of the SELECT object here. Make sure you pay attention to the values (CC Types)

*	used in the case statement for the function validateCC()

*/	var ccTypeObj = 'form1.Credit_Card_Type';

/*

*********** WARNING: DO NOT EDIT BELOW THIS LINE UNLESS YOU KNOW WHAT YOU ARE DOING! ****************/	



function cleanupCCNum(ccNum)

	{

	return ccNum.replace(/\D/g,'');

	}

	

/***************************************************************************/	

function validateCC(formObj)

	{

	var objName = formatName(formObj.name);

	if (blankOK)

		{ blankOK=false; return true; }

	else if (!validateBlank(formObj)) 

		return false;

	

	switch (eval(ccTypeObj).value)

		{

		case 'VISA'		: var ccReg = new RegExp(/^4\d{12}(\d{3})?$/); break;

		case 'MC'		: var ccReg = new RegExp(/^5[1-5]\d{14}$/); break;

		case 'DISC'		: var ccReg = new RegExp(/^6011\d{12}$/); break;

		case 'AMEX'		: var ccReg = new RegExp(/^6011\d{12}$/); break;		

		case 'DINERS'	: var ccReg = new RegExp(/^3[0|6|8]\d{12}$/); break;

		case 'ENROUTE'	: var ccReg = new RegExp(/^2[014|149]\d{11}$/); break;

		case 'JCB'		: var ccReg = new RegExp(/^3[088|096|112|158|337|528]\d{12}$/); break;

		// Add additonal card types here

		default			: alert('Error! Card Type not found!'); return false;

		}

	var formatOK = ccReg.test(formObj.value);

	var luhnOK = validateLUHN(formObj.value);	

	if (!formatOK || !luhnOK)

		{

		alert('The '+objName+' you entered is not valid. Please check again and re-enter');

		errorProcess(formObj,1,1);

		return false;

		}		

	return true;

	}

/***************************************************************************/	

function validateLUHN(ccString)

	{

	var odds = "";

	var evens = "";

	var i=1;

	for (i=0; i<ccString.length; i=i+2)

		{

		var digit = parseInt(ccString.charAt(i)) * 2;

		odds += digit+"";

		}

	for (i=1; i<ccString.length; i=i+2)

		evens += ccString.charAt(i);

	var luhnStr = odds + evens;

	var checkSum = 0;

	for (i=0; i<luhnStr.length; i++)

		checkSum += parseInt(luhnStr.charAt(i));

	var bool;

	(checkSum % 10 == 0)?bool=true:bool=false;

	return bool;

	}

	