/*********************************************************************************
 * The contents of this file are subject to the AMPT License Version 1.0 
 * ("License"); You may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at http://policies.ampt.co.za
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * See full license for requirements.
 *
 * Copyright (C) 2006 AMPT cc.;
 * All Rights Reserved.
 * Contributor(s): Rohland Lablache de Charmoy.
 ********************************************************************************/
/*********************************************************************************
 * Description:  Generic class for Validation of HTML forms using various input, 
 * select & textarea elements. (submit, reset and hidden inputs are ignored).
 *
 * Create: 2006-01-26
 *
 * Modifications:	Added textarea support
 *					2006-01-28
 *					Rohland Lablache de Charmoy
 *			Add CheckBox 'isticked' Support
 *					2006-02-02
 *					Rohland Lablache de Charmoy				
 *
 * TODO:	1. Convert the function from scanning a document to scanning a form 
 * 			object (i.e. add functionality for more than one form on a page)
 * 		2. Insert summary functionality so you can present this to the user 
 * 			when form validation fails  
 ********************************************************************************/

//---------------------------------------------------------------------------------------
// The following Cases are Taken into Account:
//---------------------------------------------------------------------------------------
//	1.	notnull		[text area and input fields]
//	2.	isnumeric
//	3.	integer
//	4.	email
//	5.	maxlength	[text area and input fields]
//	6.	minlength	[text area and input fields]
//	7.	date
//	8.	strongpassword
//	9.	fieldnot
//	10.	minselected	[only applies to select field]
//	11.	maxselected	[only applies to select field]
//	12.	filename
//	13.	isticked	[only applies to checkbox input]
//---------------------------------------------------------------------------------------
  
// --------------------------------------------------------------------------------------	
// The ValidateForm function runs through all input/select/textarea elements on a page			
// and looks for the 'validate' attribute. Once found the attribute value is scanned
// for validation keys. If the key is recognised the appropriate validation is fired.
// The action of a failed / passed validation can be changed generically using the
// PassField, FailField, PassFieldbyMsg,FailFieldByMsg functions.
// --------------------------------------------------------------------------------------
function ValidateForm()
{
	// Fetch all the <input> form objects
	objects = document.getElementsByTagName('input');
	
	// Initialise the validation flag to true. This value returns the result of the form validation function.
	var Validated = true;
	
	// Cycle through all the Input Elements on the current page
	for (i=0; i < objects.length; i++)
	{
		// Test for input elements which we do not care about
		if (objects[i].type == 'submit' || objects[i].type =='reset' || objects[i].type=='hidden')
		{
			/// These are the input buttons and we must ignore them
		}
		else
		{
			// Fetch the 'validate' attribute. This is compatible with Mozilla and IE
			var validateAttribute = objects[i].getAttribute('validate') ;
			
			// If the object does not have a validator then continue with the next element
			if (validateAttribute == null)  
				continue;
			
			// Fetch all the validation keys
			var valfunc = validateAttribute.split(';');
			
			// Fetch the value within the input element in question
			var value = objects[i].value;
			
			// the local validation variable is set to true, thereafter all specified validation keys are applied, if one fails then the global validation is set to false
			var localval = true;
			
			// Cycle through all the keys, if one of them fails then the field fails validation
			for (index = 0; index < valfunc.length; index++)
			{
				// We dont care about continuing if one of the keys has already failed
				if (localval == true)
				{
					// Find out which validation key we are looking at
					switch (valfunc[index])
					{
						// The isnumeric key ensures that the value is a number [decimal included]
						case 'isnumeric':
							var num = value.split('.');
							for (numindex = 0; numindex < num.length;numindex++)
							{
								if (!num[numindex].match(/^[\d]+$/) || num.length > 2)
								{
									localval = FailFieldByMsg(objects[i],"This field requires a numeric value.");
									objects[i].title = "This field requires a numeric value.";
									break;
								}
								else
									PassFieldbyMsg(objects[i]); 
							}
							break;
						// The integer key passes validation if the value entered is numeric with no decimal places
						case 'integer':
							if (!value.match(/^[\d]+$/)  && value.length > 0)
							{
								localval = FailFieldByMsg(objects[i],"This field requires an Integer value.");
								objects[i].title = "This field requires an Integer value.";
							}
							else
								PassFieldbyMsg(objects[i]); 
							break;
						// The notnull key ensures the value entered has a length > 0
						case 'notnull':
							if (value.length == 0  && localval==true)
							{
								localval = FailFieldByMsg(objects[i],"This field cannot be empty.");
								objects[i].title = "This field cannot be empty.";
							}
							else
								PassFieldbyMsg(objects[i]); 
							break;
						// the email key ensures the value entered represents an email address
						case 'email':
							if (!value.match(/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/))
							{
								localval = FailFieldByMsg(objects[i],"Please enter a valid email address format.");
								objects[i].title = "Please enter a valid email address format.";
							}
							else
								PassFieldbyMsg(objects[i]); 
							break;
						// The strongpassword key ensures that the password entered has a combination of Alphabetical and Non-Alphabetical characters
						case 'strongpassword':
							if (!value.match(/^[^a-zA-Z\s]+\S*$|^\S*[^a-zA-Z\s]+.*$/))
							{
								localval = FailFieldByMsg(objects[i],"Please enter a password with a mix of alphabetical and non-alphabetical characters.");
								objects[i].title = "Please enter a password with a mix of alphabetical and non-alphabetical characters.";
							}
							else
								PassFieldbyMsg(objects[i]); 
							break;
						// The date key ensures that the value entered is in the format DD/MM/CCYY | DD\MM\CCYY | DD-MM-CCYY
						case 'date':
							// Attempt to split with normal splitters
							var date;
							date = value.split('/');
							if (date.length != 3)
								date = value.split('\\');
							if (date.length != 3)
								date = value.split('-');
							if (date.length !=3)
							{
								localval = FailFieldByMsg(objects[i],"Please enter a date in the format: DD/MM/CCYY");
								objects[i].title = "Please enter a date in the format: DD/MM/CCYY";
							}
							else
							{
								// Make sure the day value is < 32 , the month value < 13 and the year value is 4 characters
								if (date[0] < 32&& date[1] < 13 && date[2].length ==4)
								{
									PassFieldbyMsg(objects[i]);
								}
								else
								{
									localval = FailFieldByMsg(objects[i],"Please enter a date in the format: DD/MM/CCYY");
									objects[i].title = "Please enter a date in the format: DD/MM/CCYY";
								}
							}
							break;
						// The isticked key ensures that the checkbox is ticked
						case 'isticked':
							if (!objects[i].checked)
							{
								localval = FailFieldByMsg(objects[i],"Please check this field to continue.");
							}
							else
							{
								PassFieldbyMsg(objects[i]);
							}
						break;
						// Here we parse for keys that require extra information 
						default:
							// If the string contains maxlength key then process it
							if (valfunc[index].indexOf('maxlength') != -1)		// Caught Maxlength
							{
								var mlength = valfunc[index].split(':');
								// If there is no ':' sign then something is wrong
								if (mlength.length != 2)
								{
									alert('Error in Max Length Parameter');
									return;
								}
								if (value.length > mlength[1])
								{
									localval = FailFieldByMsg(objects[i],"Please enter a value that has " + mlength[1] + " characters or less.");
									objects[i].title = "Please enter a value that has " + mlength[1] + " characters or less.";
								}
								else
									PassFieldbyMsg(objects[i]);
							}
							// If the string contains maxlength key then process it
							else if (valfunc[index].indexOf('minlength') != -1) // Caught minlength
							{
								var mlength = valfunc[index].split(':');
								// If there is no ':' sign then something is wrong
								if (mlength.length != 2)
								{
									alert('Error in Min Length Parameter');
									return;
								}
								if (value.length < mlength[1])
								{
									localval = FailFieldByMsg(objects[i],"Please enter a value that has " + mlength[1] + " characters or more.");
									objects[i].title = "Please enter a value that has " + mlength[1] + " characters or more.";
								}
								else
									PassFieldbyMsg(objects[i]);
							
							}
							// If the string contains fieldnot key then process it
							else if(valfunc[index].indexOf('fieldnot') != -1) // Caught Password Exclusions
							{
								var mlength = valfunc[index].split(':');
								// If there is no ':' sign then something is wrong
								if (mlength.length != 2)
								{
									alert('Error in Password Exclusion Parameter');
									return;
								}
								if (value.toLowerCase() == mlength[1].toLowerCase())
								{
									localval = FailFieldByMsg(objects[i],"Please enter a value not equal to: '" + mlength[1] + "'");
									objects[i].title = "Please enter a value not equal to: '" + mlength[1] + "'";
								}
								else
									PassFieldbyMsg(objects[i]);
							
							}
							// If the string contains filename key then process it
							else if(valfunc[index].indexOf('filename') != -1)
							{
								// Leave null string validation to notnull key
								if (value.length == 0)
								{
									continue;
								}
								var mlength = valfunc[index].split(':');
								// If there is no ':' sign then something is wrong
								if (mlength.length != 2)
								{
									alert('Error in Filename Exclusion Parameter');
									return;
								}
								var filename = value.split('.');
								// If the file has no extension then there is something wrong
								if (filename.length <= 1)
								{
									// The user must specify not null to create error when file null
									localval = FailFieldbyMsg(objects[i],"Please enter a valid filename");
									objects[i].title = "Please enter a valid filename";
								}
								else
								{
									// Parse through all the extension types the user wants to validate againt
									var ext = mlength[1].split('|');
									var countmismatch = 0;
									// Build up an error message as we parse through expected file types, this is only shown if none match the current values extension
									var errmsg = "Please enter a valid filename ";
									for (extindex = 0; extindex < ext.length; extindex++)
									{
										errmsg += (extindex == 0? "[*." + ext[extindex].toLowerCase() : "|*." + ext[extindex].toLowerCase());
										// Is there a match? If not we increment countmismatch
										if (ext[extindex].toLowerCase() != filename[filename.length-1].toLowerCase())
										{
											countmismatch++;
										}											
									}
									errmsg += "]";
									// If the mismatch count is the same as the number or validating extensions then none could have matched --> Error
									if (countmismatch == ext.length)
									{
										localval = FailField(objects[i]);
										objects[i].title = errmsg;
									}
									else
									{
										PassFieldbyMsg(objects[i]);
									}
								}
								
							}
							break;
							
					}
				}
			}
			// If the Validated value is false we want it to stay that way
			Validated = Validated && localval;
		}
	}
	
	// Need to Cycle through the Select Elements if there are any
	objects = document.getElementsByTagName('select');
	
	// Cycle through each select element
	for (i=0; i < objects.length; i++)
	{
		// Fetch the validate attribute object for the relevant element
		var validateAttribute = objects[i].getAttribute('validate') ;
		
		// We dont want to continue with this element if the validate attribute was not specified
		if (validateAttribute == null)
			continue;
			
		// Split all the validator keys up in order to process them
		var valfunc = validateAttribute.split(';');

		// parse the validate string to see what needs to be validated
		var localval = true;
		
		// Cylce through all the Validate keys
		for (index = 0; index < valfunc.length; index++)
		{
			// If this element already failed one of its validation keys then do not continue
			if (localval == true)
			{
				// The minselected key ensures that the number of items selected is greater than a user specified value
				if (valfunc[index].indexOf('minselected') != -1)
				{
					var mlength = valfunc[index].split(':');
					// There is something wrong if there is no ':' seperator
					if (mlength.length != 2)
					{
						alert('Error in Min Selected Parameter');
						return;
					}
					// Cycle Through Items and Count How Many items are Selected
					var count = 0;
					for (selindex = 0;selindex < objects[i].length; selindex++)
					{
						if ( objects[i][selindex].selected == true)
							count++;
					}
					// Test the selected item count agains the user specified value
					if (mlength[1] > count)
					{
						localval = FailFieldByMsg(objects[i],"Please select at least " +mlength[1] + " item/items.");
					}
					else
						PassFieldbyMsg(objects[i]);
					
				}
				// The maxselected key ensures that the number of items selected is less than a user specified value
				else if(valfunc[index].indexOf('maxselected') != -1)
				{
					var mlength = valfunc[index].split(':');
					// There is something wrong if there is no ':' seperator
					if (mlength.length != 2)
					{
						alert('Error in Max Selected Parameter');
						return;
					}
					
					// Cycle Through Items and Count How Many items are Selected
					var count = 0;
					for (selindex = 0;selindex < objects[i].length; selindex++)
					{
						if ( objects[i][selindex].selected == true)
							count++;
					}
					// Test the selected item count agains the user specified value
					if (mlength[1] < count)
					{
						localval = FailFieldByMsg(objects[i],"Please select at most " +mlength[1] + " item/items.");
					}
					else
						PassFieldbyMsg(objects[i]);
				}
			}
		}
		// If the Validated value is false we want it to stay that way
		Validated = Validated && localval;
	}
	
	
	// Need to Cycle through the Textarea Elements if there are any
	objects = document.getElementsByTagName('textarea');
	
	// Cycle through each select element
	for (i=0; i < objects.length; i++)
	{
		// Fetch the validate attribute object for the relevant element
		var validateAttribute = objects[i].getAttribute('validate') ;
		
		// We dont want to continue with this element if the validate attribute was not specified
		if (validateAttribute == null)
			continue;
			
		// Fetch the value within the input element in question
		var value = objects[i].value;
			
		// Split all the validator keys up in order to process them
		var valfunc = validateAttribute.split(';');

		// parse the validate string to see what needs to be validated
		var localval = true;
		
		// Cylce through all the Validate keys
		for (index = 0; index < valfunc.length; index++)
		{
			// If this element already failed one of its validation keys then do not continue
			if (localval == true)
			{
				// The minselected key ensures that the number of items selected is greater than a user specified value
				if (valfunc[index].indexOf('minlength') != -1)
				{
					var mlength = valfunc[index].split(':');
					// There is something wrong if there is no ':' seperator
					if (mlength.length != 2)
					{
						alert('Error in Min Length Parameter');
						return;
					}
					// Test the selected item count agains the user specified value
					if (mlength[1] > value.length)
					{
						localval = FailFieldByMsg(objects[i],"This field requires at least " +mlength[1] + " characters.");
					}
					else
						PassFieldbyMsg(objects[i]);
					
				}
				// The maxselected key ensures that the number of items selected is less than a user specified value
				else if(valfunc[index].indexOf('maxlength') != -1)
				{
					var mlength = valfunc[index].split(':');
					// There is something wrong if there is no ':' seperator
					if (mlength.length != 2)
					{
						alert('Error in Max Length Parameter');
						return;
					}
					
					// Cycle Through Items and Count How Many items are Selected
					// Test the selected item count agains the user specified value
					if (mlength[1] < value.length)
					{
						localval = FailFieldByMsg(objects[i],"This field requires no more than " +mlength[1] + " characters.");
					}
					else
						PassFieldbyMsg(objects[i]);
				}
				else if(valfunc[index].indexOf('notnull') != -1)
				{
					if (value.length == 0)
					{
						localval = FailFieldByMsg(objects[i],"This is a required field and cannot be left empty.");
					}
					else
						PassFieldbyMsg(objects[i]);
					
				}
			}
		}
		// If the Validated value is false we want it to stay that way
		Validated = Validated && localval;
	}

	// Custome feature that is used for testing, you can use this to display a message
	if (!Validated)
		alert('Unfortunately you cannot proceed until all required fields have been correctly entered.');
	return Validated;
}

// --------------------------------------------------------------------------------------
// Function Name: PassFieldbyMsg							|
// Arguments: Form Element Object							|
// This function is used to hide an error shown by a text message field.		|
//---------------------------------------------------------------------------------------
function PassFieldbyMsg(obj)
{
	obj.style.border = "#7f9db9 1px solid" ;
	// Fetch the Error ID and hide it if its showing
	msgobj = document.getElementById(obj.id + '_msg');
	if (msgobj != null)
	{
		msgobj.style.display = 'none';
	}
}

// --------------------------------------------------------------------------------------
// Function Name: FailFieldByMsg							|
// Arguments: Form Element Object; Custom string message				|
// This function is used to display a custom text error message			 	|
//---------------------------------------------------------------------------------------
function FailFieldByMsg(obj,msg)
{
	obj.style.border = "#FF0000 1px solid";
	// Display the custom message to the user
	msgobj = document.getElementById(obj.id + '_msg');
	if (msgobj != null)
	{
		// Display the Error msg in red font
		//msgobj.innerHTML = "<font style='color:#f00; font-size:9px;'>" + msg + "</font>";
		msgobj.style.display = 'block';
	}
	return false;
}

// --------------------------------------------------------------------------------------
// Function Name: PassField								|
// Arguments: Input Object								|
// This function is used to swap the border colour of an input field back to normal.	|
// The function is called when a field passes its validation criteria.			|
//---------------------------------------------------------------------------------------
function PassField(obj)
{
	obj.style.border = "#7f9db9 1px solid" ;
	return true;
}

// --------------------------------------------------------------------------------------
// Function Name: PassField								|
// Arguments: Input Object								|
// This function is used to swap the border colour of an input field back to a custom	|
// color (red). The function is called when a field fails its validation criteria.	|
//---------------------------------------------------------------------------------------
function FailField(obj)
{
	obj.style.border = "#FF0000 1px solid";
	return false;
}


 
// --------------------------------------------------------------------------------------	
// The ValidateOnBlur function runs through the relevant input/select/textarea element	|		
// and looks for the 'validate' attribute. Once found the attribute value is scanned	|
// for validation keys. If the key is recognised the appropriate validation is fired.	|
// The action of a failed / passed validation can be changed generically using the 	|
// PassField, FailField, PassFieldbyMsg,FailFieldByMsg functions.			|
// Argument: Element Object passed by 'this' parameter					|
// --------------------------------------------------------------------------------------
function ValidateOnBlur(elementobj)
{
	
	// Initialise the validation flag to true. This value returns the result of the form validation function.
	var Validated = true;
	
	// Test for input elements which we do not care about
	if (elementobj.type == 'submit' || elementobj.type =='reset' || elementobj.type=='hidden')
	{
		/// These are the input buttons and we must ignore them
	}
	else if (elementobj.type == 'select-multiple')
	{
		// Fetch the validate attribute object for the relevant element
		var validateAttribute = elementobj.getAttribute('validate') ;
		
		// We dont want to continue with this element if the validate attribute was not specified
		if (validateAttribute == null)
			return;
			
		// Split all the validator keys up in order to process them
		var valfunc = validateAttribute.split(';');

		// parse the validate string to see what needs to be validated
		var localval = true;
		
		// Cylce through all the Validate keys
		for (index = 0; index < valfunc.length; index++)
		{
			// If this element already failed one of its validation keys then do not continue
			if (localval == true)
			{
				// The minselected key ensures that the number of items selected is greater than a user specified value
				if (valfunc[index].indexOf('minselected') != -1)
				{
					var mlength = valfunc[index].split(':');
					// There is something wrong if there is no ':' seperator
					if (mlength.length != 2)
					{
						alert('Error in Min Selected Parameter');
						return;
					}
					// Cycle Through Items and Count How Many items are Selected
					var count = 0;
					for (selindex = 0;selindex < elementobj.length; selindex++)
					{
						if ( elementobj[selindex].selected == true)
							count++;
					}
					// Test the selected item count agains the user specified value
					if (mlength[1] > count)
					{
						localval = FailFieldByMsg(elementobj,"Please select at least " +mlength[1] + " item/items.");
					}
					else
						PassFieldbyMsg(elementobj);
					
				}
				// The maxselected key ensures that the number of items selected is less than a user specified value
				else if(valfunc[index].indexOf('maxselected') != -1)
				{
					var mlength = valfunc[index].split(':');
					// There is something wrong if there is no ':' seperator
					if (mlength.length != 2)
					{
						alert('Error in Max Selected Parameter');
						return;
					}
					
					// Cycle Through Items and Count How Many items are Selected
					var count = 0;
					for (selindex = 0;selindex < elementobj.length; selindex++)
					{
						if ( elementobj[selindex].selected == true)
							count++;
					}
					// Test the selected item count agains the user specified value
					if (mlength[1] < count)
					{
						localval = FailFieldByMsg(elementobj,"Please select at most " +mlength[1] + " item/items.");
					}
					else
						PassFieldbyMsg(elementobj);
				}
			}
		}
		// If the Validated value is false we want it to stay that way
		Validated = Validated && localval;
	}
	else if (elementobj.type == 'textarea')
	{
		// Fetch the validate attribute object for the relevant element
		var validateAttribute = elementobj.getAttribute('validate') ;
		
		// We dont want to continue with this element if the validate attribute was not specified
		if (validateAttribute == null)
			return;
			
		// Fetch the value within the input element in question
		var value = elementobj.value;
		
			
		// Split all the validator keys up in order to process them
		var valfunc = validateAttribute.split(';');

		// parse the validate string to see what needs to be validated
		var localval = true;
		
		// Cylce through all the Validate keys
		for (index = 0; index < valfunc.length; index++)
		{
			// If this element already failed one of its validation keys then do not continue
			if (localval == true)
			{
				// The minselected key ensures that the number of items selected is greater than a user specified value
				if (valfunc[index].indexOf('minlength') != -1)
				{
					var mlength = valfunc[index].split(':');
					// There is something wrong if there is no ':' seperator
					if (mlength.length != 2)
					{
						alert('Error in Min Length Parameter');
						return;
					}
					// Test the selected item count agains the user specified value
					if (mlength[1] > value.length)
					{
						localval = FailFieldByMsg(elementobj,"This field requires at least " +mlength[1] + " characters.");
					}
					else
						PassFieldbyMsg(elementobj);
					
				}
				// The maxselected key ensures that the number of items selected is less than a user specified value
				else if(valfunc[index].indexOf('maxlength') != -1)
				{
					var mlength = valfunc[index].split(':');
					// There is something wrong if there is no ':' seperator
					if (mlength.length != 2)
					{
						alert('Error in Max Length Parameter');
						return;
					}
					
					// Cycle Through Items and Count How Many items are Selected
					// Test the selected item count agains the user specified value
					if (mlength[1] < value.length)
					{
						localval = FailFieldByMsg(elementobj,"This field requires no more than " +mlength[1] + " characters.");
					}
					else
						PassFieldbyMsg(elementobj);
				}
				else if(valfunc[index].indexOf('notnull') != -1)
				{
					if (value.length == 0)
					{
						localval = FailFieldByMsg(elementobj,"This is a required field and cannot be left empty.");
					}
					else
						PassFieldbyMsg(elementobj);
					
				}
			}
		}
		// If the Validated value is false we want it to stay that way
		Validated = Validated && localval;
			

	}
	else
	{
		// Fetch the 'validate' attribute. This is compatible with Mozilla and IE
		var validateAttribute = elementobj.getAttribute('validate') ;
		
		// If the object does not have a validator then continue with the next element
		if (validateAttribute == null)  
			return;
		
		// Fetch all the validation keys
		var valfunc = validateAttribute.split(';');
		
		// Fetch the value within the input element in question
		var value = elementobj.value;
		
		// the local validation variable is set to true, thereafter all specified validation keys are applied, if one fails then the global validation is set to false
		var localval = true;
		
		// Cycle through all the keys, if one of them fails then the field fails validation
		for (index = 0; index < valfunc.length; index++)
		{
			// We dont care about continuing if one of the keys has already failed
			if (localval == true)
			{
				// Find out which validation key we are looking at
				switch (valfunc[index])
				{
					// The isnumeric key ensures that the value is a number [decimal included]
					case 'isnumeric':
						var num = value.split('.');
						for (numindex = 0; numindex < num.length;numindex++)
						{
							if (!num[numindex].match(/^[\d]+$/) || num.length > 2)
							{
								localval = FailField(elementobj);
								elementobj.title = "This field requires a numeric value.";
								break;
							}
							else
								PassField(elementobj); 
						}
						break;
					// The integer key passes validation if the value entered is numeric with no decimal places
					case 'integer':
						if (!value.match(/^[\d]+$/)  && value.length > 0)
						{
							localval = FailField(elementobj);
							elementobj.title = "This field requires an Integer value.";
						}
						else
							PassField(elementobj); 
						break;
					// The notnull key ensures the value entered has a length > 0
					case 'notnull':
						if (value.length == 0  && localval==true)
						{
							localval = FailField(elementobj);
							elementobj.title = "This field cannot be empty.";
						}
						else
							PassField(elementobj); 
						break;
					// the email key ensures the value entered represents an email address
					case 'email':
					//	if (!value.match(/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/))
						if (value.length == 0)
						{
							localval = FailField(elementobj);
							elementobj.title = "Please enter a valid email address format.";
						}
						else
							PassField(elementobj); 
						break;
					// The strongpassword key ensures that the password entered has a combination of Alphabetical and Non-Alphabetical characters
					case 'strongpassword':
						if (!value.match(/^[^a-zA-Z\s]+\S*$|^\S*[^a-zA-Z\s]+.*$/))
						{
							localval = FailField(elementobj);
							elementobj.title = "Please enter a password with a mix of alphabetical and non-alphabetical characters.";
						}
						else
							PassField(elementobj); 
						break;
					// The date key ensures that the value entered is in the format DD/MM/CCYY | DD\MM\CCYY | DD-MM-CCYY
					case 'date':
						// Attempt to split with normal splitters
						var date;
						date = value.split('/');
						if (date.length != 3)
							date = value.split('\\');
						if (date.length != 3)
							date = value.split('-');
						if (date.length !=3)
						{
							localval = FailField(elementobj);
							elementobj.title = "Please enter a date in the format: DD/MM/CCYY";
						}
						else
						{
							// Make sure the day value is < 32 , the month value < 13 and the year value is 4 characters
							if (date[0] < 32&& date[1] < 13 && date[2].length ==4)
							{
								PassField(elementobj);
							}
							else
							{
								localval = FailField(elementobj);
								elementobj.title = "Please enter a date in the format: DD/MM/CCYY";
							}
						}
						break;
					// The isticked key ensures that the checkbox is ticked
					case 'isticked':
						if (!elementobj.checked)
						{
							localval = FailFieldByMsg(elementobj,"Please check this field to continue.");
						}
						else
						{
							PassFieldbyMsg(elementobj);
						}
					break;
					// Here we parse for keys that require extra information 
					default:
						// If the string contains maxlength key then process it
						if (valfunc[index].indexOf('maxlength') != -1)		// Caught Maxlength
						{
							var mlength = valfunc[index].split(':');
							// If there is no ':' sign then something is wrong
							if (mlength.length != 2)
							{
								alert('Error in Max Length Parameter');
								return;
							}
							if (value.length > mlength[1])
							{
								localval = FailField(elementobj);
								elementobj.title = "Please enter a value that has " + mlength[1] + " characters or less.";
							}
							else
								PassField(elementobj);
						}
						// If the string contains maxlength key then process it
						else if (valfunc[index].indexOf('minlength') != -1) // Caught minlength
						{
							var mlength = valfunc[index].split(':');
							// If there is no ':' sign then something is wrong
							if (mlength.length != 2)
							{
								alert('Error in Min Length Parameter');
								return;
							}
							if (value.length < mlength[1])
							{
								localval = FailField(elementobj);
								elementobj.title = "Please enter a value that has " + mlength[1] + " characters or more.";
							}
							else
								PassField(elementobj);
						
						}
						// If the string contains fieldnot key then process it
						else if(valfunc[index].indexOf('fieldnot') != -1) // Caught Password Exclusions
						{
							var mlength = valfunc[index].split(':');
							// If there is no ':' sign then something is wrong
							if (mlength.length != 2)
							{
								alert('Error in Password Exclusion Parameter');
								return;
							}
							if (value.toLowerCase() == mlength[1].toLowerCase())
							{
								localval = FailField(elementobj);
								elementobj.title = "Please enter a value not equal to: '" + mlength[1] + "'";
							}
							else
								PassField(elementobj);
						
						}
						// If the string contains filename key then process it
						else if(valfunc[index].indexOf('filename') != -1)
						{
							var mlength = valfunc[index].split(':');
							// If there is no ':' sign then something is wrong
							if (mlength.length != 2)
							{
								alert('Error in Filename Exclusion Parameter');
								return;
							}
							// Leave null string validation to notnull key
							if (value.length == 0)
							{
								continue;
							}
							var filename = value.split('.');
							// If the file has no extension then there is something wrong
							if (filename.length <= 1)
							{
								localval = FailField(elementobj);
								elementobj.title = "Please enter a valid filename";
							}
							else
							{
								// Parse through all the extension types the user wants to validate againt
								var ext = mlength[1].split('|');
								var countmismatch = 0;
								// Build up an error message as we parse through expected file types, this is only shown if none match the current values extension
								var errmsg = "Please enter a valid filename ";
								for (extindex = 0; extindex < ext.length; extindex++)
								{
									errmsg += (extindex == 0? "[*." + ext[extindex].toLowerCase() : "|*." + ext[extindex].toLowerCase());
									// Is there a match? If not we increment countmismatch
									if (ext[extindex].toLowerCase() != filename[filename.length-1].toLowerCase())
									{
										countmismatch++;
									}											
								}
								errmsg += "]";
								// If the mismatch count is the same as the number or validating extensions then none could have matched --> Error
								if (countmismatch == ext.length)
								{
									localval = FailField(elementobj);
									elementobj.title = errmsg;
								}
								else
								{
									PassField(elementobj);
								}
							}
							
						}
						break;
						
				}
			}
		}
		// If the Validated value is false we want it to stay that way
		Validated = Validated && localval;
	}

	return Validated;
}