//---------------------------------------------------------------------------------------
// Client Side Form Validation Written by: Rohland Lablache de Charmoy (www.ampt.co.za)	|
// Generic class for Validation of HTML forms using various input and select elements	|
// (submit, reset and hidden inputs are ignored).					|
//---------------------------------------------------------------------------------------
// Creation Date: 26/01/2006								|
//---------------------------------------------------------------------------------------
// Modifications:						|Date:			|
//*					Added RSA ID checking
//*					2009-09-25
//*					Richard Hodsdon
//---------------------------------------------------------------------------------------
// 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  								|
//---------------------------------------------------------------------------------------
  
  
//---------------------------------------------------------------------------------------
// This script cannot be used for commerical purposes without the authors permission.
//---------------------------------------------------------------------------------------


//---------------------------------------------------------------------------------------
// The following Cases are Taken into Account:					|
//---------------------------------------------------------------------------------------
//	1.	notnull									|
//	2.	isnumeric									|
//	3.	integer									|
//	4.	email										|
//	5.	maxlength									|
//	6.	minlength									|
//	7.	date										|
//	8.	strongpassword								|
//	9.	fieldnot									|
//	10.	minselected	[only applies to select field]				|
//	11.	maxselected	[only applies to select field]				|
//	12.	filename									|
//	13.	rsaid										|
//	14.	nottopselect:Text value to return					|
//---------------------------------------------------------------------------------------
  
// --------------------------------------------------------------------------------------	
// The ValidateForm function runs through all input and select 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, PassSelect,FailSelect 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.");
									break;
								}
								else
									PassField(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
								PassField(objects[i]); 
							break;
						// The notnull key ensures the value entered has a length > 0
						case 'notnull':
							if ((value.length == 0 || value.length == ' ') && localval==true)
							{
								localval = FailFieldByMsg(objects[i],"This field cannot be empty.");
								objects[i].title = "This field cannot be empty.";
							}
							else
								PassField(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
								PassField(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
								PassField(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)
								{
									PassField(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
							{
								PassField(objects[i]);
							}
						break;
						//The cellphone key ensures that a valid south african cell number is entered
						case 'cell':
							if (!value.match(/^([0]+[7-8])/))
							{
								localval = FailFieldByMsg(objects[i],"Please enter a valid cell number.");
								objects[i].title = "Please enter a valid cell number.";
							}
							else
								PassField(objects[i]); 
							break;
						//The rsaid key ensures that a valid south african identity number is entered
						case 'rsaid':
							if(value.length != 13)//added check to see if id number is 13 digits long
							{
								localval = FailFieldByMsg(objects[i],"Please enter a valid RSA ID number.");
								objects[i].title = "Please enter a valid RSA ID number.";
								break;
							}
							mm = value.substring(2,2);
							dd = value.substring(4,2);
							
							if((mm>12)||(dd>31))
							{
								localval = FailFieldByMsg(objects[i],"Please enter a valid RSA ID number.");
								objects[i].title = "Please enter a valid RSA ID number.";
								break;
							}
							
							if(value.indexOf('000000') != -1)
							{
								localval = FailFieldByMsg(objects[i],"Please enter a valid RSA ID number.");
								objects[i].title = "Please enter a valid RSA ID number.";
								break;		
							}
							
							ID = value.split('');
							val1 = parseInt(ID[0]) + parseInt(ID[2]) + parseInt(ID[4]) + parseInt(ID[6]) + parseInt(ID[8]) + parseInt(ID[10]);
							
							val2 = eval(ID[1]+ID[3]+ID[5]+ID[7]+ID[9]+ID[11]) * 2;
							val2 += "";
							arr = val2.split('');
							
							val3 = 0;
							for (var k = 0; k < arr.length; k++) {
								val3 += parseInt(arr[k]);
							}
							
							val4 = val1 + val3;
							val4 += "";
							arr = val4.split('');
							
							val5 = 10 - arr[1];
							
							if (val5 == 10)
								val5 = 0;
								
							if (val1==0 || val2==0)
							{
								localval = FailFieldByMsg(objects[i],"Please enter a valid RSA ID number.");
								objects[i].title = "Please enter a valid RSA ID number.";
								break;
							}
								
							if (val5 == ID[12])
								PassField(objects[i]); 
							else{
								localval = FailFieldByMsg(objects[i],"Please enter a valid RSA ID number.");
								objects[i].title = "Please enter a valid RSA ID number.";
							}
								
						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.");
								}
								else
									PassField(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.");
								}
								else
									PassField(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
									PassField(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 = FailFieldByMsg(objects[i],errmsg);
										objects[i].title = errmsg;
									}
									else
									{
										PassField(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 ensures that the dropdown is selected off the top item
				if (valfunc[index].indexOf('nottopselect') != -1)
				{
					var itemName = valfunc[index].split(':');
					if (objects[i].options[0].selected)
					{
						localval = FailFieldByMsg(objects[i],"Please Select a "+itemName[1]);
						objects[i].title = "Please Select a "+itemName[1];
					}
					else
						PassField(objects[i]); 
				}
				// 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 = FailSelect(objects[i],"Please select at least " +mlength[1] + " item/items.");
					}
					else
						PassSelect(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 = FailSelect(objects[i],"Please select at most " +mlength[1] + " item/items.");
					}
					else
						PassSelect(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('Validation Passed)');
	return Validated;
}


// --------------------------------------------------------------------------------------
// Function Name: setupBlurValidate								|
// Arguments: none								|
// This funciton is used to setup all onblur events for fields with the attribute of validate 	|
//---------------------------------------------------------------------------------------
function setupBlurValidate()
{
	// Fetch all the <input> form objects
	objects = document.getElementsByTagName('input');
	
	// 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;
		
			objects[i].onblur = function(){
				ValidateOnBlur(this);
			}
		}
	}
}

// --------------------------------------------------------------------------------------
// Function Name: setupBlurValidate								|
// Arguments: none								|
// This funciton is used to setup all onblur events for fields with the attribute of validate 	|
//---------------------------------------------------------------------------------------
function checkForBlurInit()
{
	// Fetch all the <input> form objects
	objects = document.getElementsByTagName('form');
	
	// Cycle through all the Input Elements on the current page
	for (i=0; i < objects.length; i++)
	{
		var validateAttribute = objects[i].getAttribute('onBlurValidate') ;
			
		// If the object does not have a validator then continue with the next element
		if (validateAttribute == null)  
			continue;
		setupBlurValidate();	
	}
}

// --------------------------------------------------------------------------------------
// Function Name: PassSelect								|
// Arguments: Select Object								|
// This function is used for Select Fields since the border colour of a select field 	|
// cannot be edited. Function hides custom error.					|
//---------------------------------------------------------------------------------------
function PassSelect(obj)
{
	// Fetch the Error ID and hide it if its showing
	document.getElementById(obj.id + 'msg').style.display = 'none';
}

// --------------------------------------------------------------------------------------
// Function Name: FailSelect								|
// Arguments: Select Object; Custom string message					|
// This function is used for Select Fields since the border colour of a select field 	|
// cannot be edited. Function displays custom error message.				|
//---------------------------------------------------------------------------------------
function FailSelect(obj,msg)
{
	// 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 color='red'>" + msg + "</font>";
		msgobj.style.display = '';
	}
	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)
{
	currentClass = obj.className
	
	if(currentClass.indexOf("valPassed") == -1){
		currentClass = currentClass.replace("valFailed" ,"");
		currentClass = currentClass+' valPassed';
		obj.className = currentClass;
	}
	msgobj = document.getElementById(obj.id + '_msg');
	if (msgobj != null)
	{
		msgobj.style.display = 'none';
	}
	//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)
{
	currentClass = obj.className
	if(currentClass.indexOf("valFailed") == -1){
		currentClass = currentClass.replace("valPassed" ,"");
		currentClass = currentClass+' valFailed';
		obj.className = currentClass;
	}
	//obj.style.border = "#FF0000 1px solid";
	
	return false;
}

function FailFieldByMsg(obj,msg)
{
	currentClass = obj.className
	if(currentClass.indexOf("valFailed") == -1){
		currentClass = currentClass.replace("valPassed" ,"");
		currentClass = currentClass+' valFailed';
		obj.className = currentClass;
	}
	// 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;
}

 
// --------------------------------------------------------------------------------------	
// The ValidateOnBlur function runs through the relevant input or select 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, PassSelect,FailSelect 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 ensures that the dropdown is selected off the top item
				if (valfunc[index].indexOf('nottopselect') != -1)
				{
					var itemName = valfunc[index].split(':');
					if (objects[i].options[0].selected)
					{
						localval = FailFieldByMsg(elementobj,"Please Select a "+itemName[1]);
						elementobj.title = "Please Select a "+itemName[1];
					}
					else
						PassField(elementobj); 
				}
				// 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 = FailSelect(elementobj,"Please select at least " +mlength[1] + " item/items.");
					}
					else
						PassSelect(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 = FailSelect(elementobj,"Please select at most " +mlength[1] + " item/items.");
					}
					else
						PassSelect(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})+$/))
						{
							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 = FailField(elementobj,"Please check this field to continue.");
						}
						else
						{
							PassField(elementobj);
						}
					break;
					//The rsaid key ensures that a valid south african identity number is entered
						case 'rsaid':
							if(value.length != 13)//added check to see if id number is 13 digits long
							{
								localval = FailFieldByMsg(elementobj,"Please enter a valid RSA ID number.");
								break;
							}
							mm = value.substring(2,2);
							dd = value.substring(4,2);
							
							if((mm>12)||(dd>31))
							{
								localval = FailFieldByMsg(elementobj,"Please enter a valid RSA ID number.");
								break;
							}
							
							if(value.indexOf('000000') != -1)
							{
								localval = FailFieldByMsg(elementobj,"Please enter a valid RSA ID number.");
								break;		
							}
							
							ID = value.split('');
							val1 = parseInt(ID[0]) + parseInt(ID[2]) + parseInt(ID[4]) + parseInt(ID[6]) + parseInt(ID[8]) + parseInt(ID[10]);
							
							val2 = eval(ID[1]+ID[3]+ID[5]+ID[7]+ID[9]+ID[11]) * 2;
							val2 += "";
							arr = val2.split('');
							
							val3 = 0;
							for (var v in arr)
							{
								val3 += v;
							}
							
							val4 = val1 + val3;
							
							arr = val4.split('');
							
							val5 = 10 - arr[1];
							
							if (val5 == 10)
								val5 = 0;
								
							if (val1==0 || val2==0)
							{
								localval = FailFieldByMsg(elementobj,"Please enter a valid RSA ID number.");
								break;
							}
								
							if (val5 == ID[12])
								PassField(elementobj); 
							else
								localval = FailFieldByMsg(elementobj,"Please enter a valid RSA ID number.");
								
								
						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;
}


window.onload = function(){
	checkForBlurInit();
}
