<!-- 
// Form Validation Script.  Version 2.0 *****************************************
//                                                                          	*
// Author:			Matthew O'Riordan.											*
//																				*
// -----------------------------------------------------------------------------*
//	Version History																*
// -----------------------------------------------------------------------------*
//	Unknown		:	Matthew O'Riordan	:	Created Script						*
//	13 Feb 02	:	Munsifali Rashid	:	Modified -- Notes below				*
// -----------------------------------------------------------------------------*
//                                                                          	*
// Modifications:																*
//																				*
// Version 1.1:		1.	Now shows which fields failed validation in the 		*
//						alert message shown to the user. 						*
//					2.	Improved stringContains function to use less code.		*
//					3.	Added extensive documentation.							*
//																				*
// Version 2.0a:	1.	Now object-orientated so multiple forms on one page 	*
//						can be validated (NEEDS IMPROVEMENT).					*
//																				*
// Notes:			The modified version of this script takes an extra			*
//					(4th) parameter for the frmItem.add() function, which 		*
//					is the field description.  If this is not specified,		*
//					the field title will be used (IE only, if defined),			*
//					otherwise, the field name will be used.	If that fails		*
//					"Unknown" will be used.										*
//*******************************************************************************
	
	
	
	// ** Configuration Constants **********************************************
	var frm_TEXT				=	1; 
	var frm_SELECT				=	2;
	var frm_EMAIL				=	4;
	var frm_NUMERIC				=	8;	
	var frm_PASSWORD			=	16;
	var frm_RADIO				=	32;
	var frm_NUMERIC_required	=	"0123456789.-";
	var frm_EMAIL_required		=	"@.";
	var frm_EMAIL_disallowed	=	"'%£$\"!^*";
	//**************************************************************************


	// ** Default Settings *****************************************************
	var sBadFields				=	"";
	var frmMessage				=	"Please note that we need all the fields \nmarked with an asterisk (*) to be completed \ncorrectly before you can proceed\n\nCheck the following fields\nBADFIELDS";
	var frmObject				=	"";
	//**************************************************************************

	// The form validation which serves as a wrapper for the functions.  objName is the name of the object (ie. var frm = new FormValidate("frm") )
	// This is not ideal, and the object name probably could be called using some long winded process, but it's not justified to double the file 
	// size for such little extra functionality.
	function formValidate(objName)
	{
		this.frmCheckArray	=	new Array();
		this.objName		=	objName;
		this.frmName		=	"";
		this.setFrmName		=	function (frmName) { this.frmName = frmName; }
		this.addHandler		=	addHandler;
		this.addItem		=	addItem;
		this.validate		=	validate;
		return this;
	}
	
	// This is a function to add items to the internal array of form elements to be validated (also noting their type and description).
	function addItem (name, type, extra, desc)
	{
		this.frmCheckArray[this.frmCheckArray.length]			=	new Object();
		this.frmCheckArray[this.frmCheckArray.length-1].name	=	name;
		this.frmCheckArray[this.frmCheckArray.length-1].type	=	type;
		this.frmCheckArray[this.frmCheckArray.length-1].extra	=	extra;
		this.frmCheckArray[this.frmCheckArray.length-1].desc	=	desc;
	}
	
	// This is the main function which does the actual validation checks, ensuring that each field matches it's validation check.  Fields which
	// fail are added to a list, and displayed to the user at the end of the validation (so they can see which fields failed).
	function validate()
	{
		var sBadFields	= "";
		var frmObject	= eval("document." + this.frmName);
		for (fieldI in this.frmCheckArray)
		{
			field = this.frmCheckArray[fieldI];
			if (!frmObject[field.name])
			{
				alert ('On initial search, the form element ' + field.name + ' (' + field.desc + ') ' + ' was not found');
				return false;
			}
			frmElement = frmObject[field.name];
			if (field.type == frm_TEXT)
			{
				if (String(frmElement.value).length == 0)
				{
					sBadFields	+=	field.desc + "\n";
				}
			}
			else if (field.type == frm_SELECT)
			{
				if ((!frmElement.options)||(frmElement.options.length == 0))
				{
					alert ('The form element ' + field.name + ' does not appear to be a select list or is empty');
					return (false);
				}
				else if (frmElement.options[frmElement.selectedIndex].value.length == 0)
				{
					sBadFields	+=	getFieldDescription(field, frmElement) + "\n";
				}
			}
			else if (field.type == frm_RADIO)
			{
				alert(field.name + "is a radio element");
			}
			else if (field.type == frm_EMAIL)
			{
				if (String(frmElement.value).length == 0)
				{
					sBadFields	+=	field.desc + "\n";
				}
				else if (!stringContains (frmElement.value, frm_EMAIL_required, true))
				{
					sBadFields	+=	field.desc + "\n";
				}
				else if (stringContains (frmElement.value, frm_EMAIL_disallowed, false))
				{
					sBadFields	+=	field.desc + "\n";
				}				
			}
			else if (field.type == frm_NUMERIC)
			{
				if (String(frmElement.value).length == 0)
				{
					sBadFields	+=	getFieldDescription(field, frmElement) + "\n";
				}
				else if (!stringContains (frmElement.value, frm_NUMERIC_required, false, true))
				{
					sBadFields	+=	getFieldDescription(field, frmElement) + "\n";
				}
			}
			else if (field.type == frm_PASSWORD)
			{
				if (String(frmElement.value).length < 5)
				{
					sBadFields	+=	getFieldDescription(field, frmElement) + " - minimum 5 characters\n";
				}
				else if (field.extra)
				{
					if (!frmObject[field.extra])
					{
						alert ('The password form element to compare against is missing !');
						return false;
					}
					if (String(frmElement.value) != String(frmObject[field.extra].value))
					{
						alert ('The passwords that have been entered are not the same!');
						return false;
					}
				}
			}
			else
			{
				alert ('The form element ' + field + ' does not have a type');
			}
		}
		if (sBadFields)
		{
			alert(frmMessage.replace("BADFIELDS", "-------------------------------------\n" + sBadFields));
			return false;
		}
		return true;
	}
	
	// Function to search one string for all, any or only the characters of another string.
	function stringContains(s, chars, all, only)
	{
		var matches = 0;
		if (only)
		{
			for (var i=0; i<s.length; i++) { if (chars.indexOf(s.charAt(i)) == -1) return false; }
			return true;
		}
		else
		{
			for (var i=0; i<chars.length; i++) { if (s.indexOf(chars.charAt(i)) != -1) matches++; }
			if (all && matches==chars.length) return true;
			if (!all && matches) return true;
		}
		return false;
	}

	// This function is used to get the field description, for the alert box if the form does not pass the validation check.
	// It first attempts to get the defined description.  If none is found, it tries to get the field title, then then name.
	// Failing all these, it returns "Unknown".
	function getFieldDescription(objField, frmField)
	{
		if (objField.desc) { return objField.desc; }
		else if (frmField.title) { return frmField.title; }
		else if (frmField.name) { return frmField.name; }
		else { return "Unknown"; }
	}	

	// This function adds the onsubmit handler to a form.  If there are multiple forms, this function must NOT be run in the <HEAD> area, 
	// but instead at the end of the page after the forms have loaded [into the browser].  Alternatively, the onSubmit="return frm.validate()" 
	// string can be hard coded into the form(s) (replacing 'frm' with the correct object name), removing the need to call this function.
	// Note: Must also not be used in the HEAD area if the window.onload handler is being used for something else.
	function addHandler()
	{
		var frmName	= this.frmName;
		var objName	= this.objName;
		if (document.forms[frmName]) { document.forms[frmName].onsubmit = function() { return eval(objName +".validate();") }  }
		else { window.onload	= function() { if (!document.forms[frmName]) { alert("Warning!\n\nThe form named \"" + frmName + "\" could not be found,\nand the handler has not been added.\n\nTHIS FORM WILL NOT BE VALIDATED"); } else { document.forms[frmName].onsubmit = function() { return eval(objName + ".validate();") } } } }
	}
	

	//***********************************************************************************************
	//	EXAMPLE OF USAGE																			*
	//																								*
	//	var frm1 		=	new formValidate("frm1");	// Initialise								*
	//	frm1.frmName	=	"myForm";					// Form to validate							*
	//	frm1.addHandler()								// Add onSubmit handler						*
	//***********************************************************************************************
	//						Field Name			Field Type		Extra			Description
	//-----------------------------------------------------------------------------------------------
	//	frm1.addItem		("sFullname",		frm_TEXT,		"",				"your name");
	//	frm1.addItem		("sEmailAddress",	frm_EMAIL,		"",				"email address");
	//	frm1.addItem		("sPassword",		frm_PASSWORD,	"passconf",		"password");
	//***********************************************************************************************

// -->
