// WebWiz Universal Form Validation Script - Version 2.0.003
//
// ©Copyright 2005-2009 WidaGroup Ltd - All Rights Reserved
// www.widagroup.com
//
//
// CUT BEGIN // CUT BEGIN // CUT BEGIN // CUT BEGIN // CUT BEGIN
//
//
// Developed intermittently between 30/05/2005 and 28/04/2009 by Matthew Ellis for Wida Group Ltd
//
//
// Features
//
// Deals with multiple check boxes, select boxes, and regular text fields/text areas.
// Colours and sets focus to fields that fail validation as well as alert box notification.
// Can define minimum and maximum length of data required as well as the type of data (i.e. Email address, post code).
// Deals with relationships between fields (i.e. Password retypes and groups of fields where one pass is enough).
// Highlight colour and message configuration.
// 
//
// Future Features... maybe...
//
// Error tolerance... because there is BARELY any now (i.e. It will ignore (without error) fields it can't find).
// Multiple forms per page functionality.
// Possibly advanced data type checks. Like for real dates and credit card numbers.
// Relationship where the value of one field alters the validation of another (i.e. check/radio box with text field).
//
//
// Q. How do I use this fabulous script?
//
//	A. 1. Include this file in the page
//
//		2. put the following in a JavaScript block in the page:
//			setvalidation(['fieldname1','fieldname2'],['validation,minlen,maxlen,rule','validation,minlen,maxlen,rule'],['Field 1','Field 2']);
//
//		3. put the following in your <form> tag:
//			onsubmit="return checkform(formname);"
//
//
// Q. But what does it all mean Holmes?
//
// A. 'validation' is what the field must contain if it contains anything at all. Such as an email address or post code.
//    Basically anything with a rigid recognisable structure.
//
//    'minlen' and 'maxlen' are the minimum and maximum lengths of the value that are allowed. Putting a minlen of 1 on an
//    email field is enough to force a proper email address while having a minlen of 0 would make the email optional.
//
//    'rule' is for everything else, often when fields interact. For example you could ensure fields are repeated (think
//    password retypes) or where you need only fill in one from a group of fields.
//
//
// Q. Your Validation rules suck. How do I add my own?
//
// A. Just run this function on the page where you want to use your custom Regular Expression:
//
//    settype('name of new validation',/regular expression/);
//
//
// Q. Config? Is that like ripping off fruit?
//
// A. You can alter some of the ways which the script provides feed back to the surfer as follows:
//
//    setconfig('pass colour','#ffdddd');
//
//    That would make fields that pass validation appear as a nice pink colour... if that's the kind of thing you like.
//
//    Here is a list of all the things you can change:
//
//    pass colour          colour of passed fields
//    fail colour          colour of failed fields
//    oneofmany colour     colour of 'oneofmany' fields where none have passed
//    failed message       message in the popup if any fields fail
//    oneofmany message    message to clarify 'oneofmany' fields
//    resubmit message     message to notify the user that the form has already been submitted
//
//
// CUT END // CUT END // CUT END // CUT END // CUT END //

var arrFieldName=new Array();
var arrFieldType=new Array();
var arrFieldDescription=new Array();
var blnFormSubmitted=false;
var reCheck=new Object();
var objConfig=new Object();

// assign default validation types
settype('number',/^[\d\s\(\)\-\,\.]*$/);
settype('email',/^[a-zA-Z\d][^\(\)\<\>\@\,\;\:\\\"\[\]]*\@[a-zA-Z\d][a-zA-Z\d\-\.]*\.[a-zA-Z]{2,6}$/); //"
settype('postcode',/^[a-zA-Z]{1,2}\d{1,2}[a-zA-Z]?\s\d[a-zA-Z]{2}$/);
settype('ipaddress',/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/);
settype('date',/^[0123]?\d[\\\/\-\.][01]?\d[\\\/\-\.]\d{2,4}$/);
settype('url',/^(ht|f)tp(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&amp;%\$#_]*)?$/); //'
settype('name',/^[a-zA-Z][a-zA-Z\-\s\'\.]*[a-zA-Z]$/); //'

// assign default config
setconfig('pass colour',''); // Leave me in - or you'll be soooorrieeeee...
setconfig('oneofmany colour','#eef5ff');
setconfig('fail colour','#ddeeff');
setconfig('oneofmany message','You need only fill in one of these details.');
setconfig('failed message','Please check the following details:');
setconfig('resubmit message','This form has already been submitted. Please reload the page and try again.');

// assign default validation
setvalidation([''],[''],['']);

function setvalidation(fieldnames,checktypes,fielddescription){arrFieldName=fieldnames;arrFieldType=checktypes;arrFieldDescription=fielddescription;}
function addvalidation(fieldnames,checktypes,fielddescription){arrFieldName.push(fieldnames);arrFieldType.push(checktypes);arrFieldDescription.push(fielddescription);}
function setconfig(strConfigName,strNewValue){objConfig[strConfigName.toLowerCase()]=strNewValue;}
function settype(strTypeName,strNewValue){reCheck[strTypeName]=strNewValue;}

function checkform(theForm){
	var arrFieldValues=new Array();
	var arrCheckTypeDatas=new Array();
	
	if(blnFormSubmitted){
		alert(objConfig['resubmit message'])
		return false;
	}else{
		var strMessage='';
		var blnOneOfManyPresent=false;
		
		for(n=0;n<arrFieldName.length;n++){
			var objField=theForm[arrFieldName[n]];
			
			if(typeof(objField)=='undefined'){
				arrFieldName.splice(n,1);
				arrFieldType.splice(n,1);
				arrFieldDescription.splice(n,1);
				n--;
			}else{
				if(objField.disabled){
					arrFieldName.splice(n,1);
					arrFieldType.splice(n,1);
					arrFieldDescription.splice(n,1);
					n--;
				}
			}
		}
		
		for(n=0;n<arrFieldName.length;n++){
			var objField=theForm[arrFieldName[n]];
			
			var blnFieldCollectionLength=objField.length?objField.length:0;

			arrFieldValues[n]='';
			arrCheckTypeDatas[n]=arrFieldType[n].split(',')

			if(blnFieldCollectionLength==0){
				if(objField.type=='checkbox'){
					arrFieldValues[n]=objField.checked?objField.value:'';
				}else{
					arrFieldValues[n]=objField.value;
				}
			}else{
				if(objField.options){
					arrFieldValues[n]=objField.options[objField.selectedIndex].value;
				}else{
					for(var i=0;i<blnFieldCollectionLength;i++){
						if(objField[i].checked){
							arrFieldValues[n]+=objField[i].value+',';
						}
					}
					arrFieldValues[n]=arrFieldValues[n].substr(0,arrFieldValues[n].length-1);
				}
			}
		}
		
		for(n=0;n<arrFieldName.length;n++){
			var objField=theForm[arrFieldName[n]];
			
			var intCheckResult=check_all(arrFieldValues,n,arrCheckTypeDatas);
			var blnFieldCollectionLength=objField.length?objField.length:0;
			
			switch(intCheckResult){
			case 0: // failed
				if(strMessage=='' && focus in objField){objField.focus();}
				
				strMessage+=' - '+arrFieldDescription[n]+'\n';
				
				setfieldcolour(objField,blnFieldCollectionLength,objConfig['fail colour']);
			break;
			case 1: // failed and is oneofmany where none passed
				if(strMessage=='' && focus in objField){objField.focus();}

				strMessage+=' - '+arrFieldDescription[n]+' *\n';
				blnOneOfManyPresent=true;
				
				setfieldcolour(objField,blnFieldCollectionLength,objConfig['oneofmany colour']);
			break;
			case 2: // passed or is one of many where one or more passed
				setfieldcolour(objField,blnFieldCollectionLength,objConfig['pass colour']);
			break;
			}
		}
		
		blnFormSubmitted=(strMessage=='');
		
		if(blnOneOfManyPresent){strMessage+='\n* '+objConfig['oneofmany message']}
		
		if(!blnFormSubmitted){alert(objConfig['failed message']+'\n\n'+strMessage);}
		
		return blnFormSubmitted;
	}
}

function setfieldcolour(strFieldName,blnFieldCollectionLength,strNewColour){
	if(blnFieldCollectionLength==0){
		strFieldName.style.backgroundColor=strNewColour;
	}else{
		if(strFieldName.options){
			strFieldName.style.backgroundColor=strNewColour;
			for(var i=0;i<blnFieldCollectionLength;i++){
				strFieldName.options[i].style.backgroundColor=strNewColour;
			}
		}else{
			for(var i=0;i<blnFieldCollectionLength;i++){
				strFieldName[i].style.backgroundColor=strNewColour;
			}
		}
	}
}

function check_all(arrFieldValues,n,arrCheckTypeDatas){
	var strTemp='';
	
	if(checkstringtype(arrFieldValues[n],arrCheckTypeDatas[n][0]) && checkstringlength(arrFieldValues[n],arrCheckTypeDatas[n][1],arrCheckTypeDatas[n][2])){
		if(arrCheckTypeDatas[n][3]=='repeat'){
			if (arrFieldValues[n]!=arrFieldValues[n-1]){
				return 0;
			}
		}
		return 2;
	}else{
		if(arrCheckTypeDatas[n][3]=='oneofmany'){
			for(var m=0;m<arrFieldName.length;m++){
				if(arrCheckTypeDatas[m][3]==arrCheckTypeDatas[n][3]){
					if(checkstringtype(arrFieldValues[m],arrCheckTypeDatas[m][0]) && checkstringlength(arrFieldValues[m],arrCheckTypeDatas[m][1],arrCheckTypeDatas[m][2])){
						return 2;
					}
				}
			}
			return 1;
		}
		return 0;
	}
}

function checkstringtype(strString,strCheckType){return (strCheckType=='' || strString=='' || reCheck[strCheckType].test(strString));}
function checkstringlength(strString,intMinimum,intMaximum){return (!intMinimum || strString.length>=intMinimum) && (!intMaximum || strString.length<=intMaximum);}

//End of Universal Form Validation Script
