//==========================================================================================================================================
// form validation functions Ver 1.0
// Written by Silas Landricombe 2008
// Javascript 1.1
//==========================================================================================================================================
// Supports validation of the following fields:
// text - is the field empty?
// email - check for a vaild email address
// dropdown - ensures an option with a value has been selected also supports 'other' option - requires an additional input field on the form and it's ID passed as a 4th variable
// contactNo - e.g. phone, fax numbers - set VALID characters below
// numeric - checks for a valid numeric value
// antiSpam - can be used to match two fields - requires an additional, usually hidden, input field on the form and it's ID passed as a 4th variable
// userName - check if username is valid - set INVALID characters and maximum and minimum length below
// password - check if password is valid - set VALID characters and maximum and minimum length below - requires an additional input field on the form and it's ID passed as a 4th variable 
// date - check for a valid date - checks for three numerical values seperated by a character specified below
// fileType - check the extension of the file you are trying to upload against the editable list below
// radioButton - checks if anything from the specified group has been checked
//==========================================================================================================================================
// Validation settings - feel free to adjust these to suit your needs
var validFieldColour = "#ffffff"; // standard background colour of input fields
var invalidFieldColour = "#ffcc66"; // 'alert' background colour of input fields
var contactNoCharacters = "0123456789+()- "; // VALID characters for contact numbers
var userNameCharacters = " !*£$%^&()+=¬`\\<>/?|,;"; // INVALID characters for usernames
var userNameMaxLength = 10; // maximum characters for username validation
var userNameMinLength = 5; // minimum characters for username validation
var passwordCharacters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; // VALID characters for passwords
var passwordMaxLength = 10; // maximum characters for password validation
var passwordMinLength = 5; // minimum characters for password validation
var dateFormat = "dd/mm/yy"; // date format, validation will check for 2 - 3 numerical values in the format specified here e.g. may be dd/mm/yyyy, dd.mm.yy, yyyy-dd-mm, mm/yy etc
var fileTypes = "jpg,gif,jpeg"; // VALID file types, seperate with a comma - NOT case sensitive
//==========================================================================================================================================

//==========================================================================================================================================
// show alternative field - this can be used in conjunction with the 'dropdown' validation when and alternative option is offered
function showAlt(altField,thisSelect){
	var theContainer = document.getElementById(altField);
	var theList = document.getElementById(thisSelect);
	if (theList.options.selectedIndex==(theList.options.length-1)){
		theContainer.style.display = 'block';
	} else {
		theContainer.style.display = 'none';
	}
}

//==========================================================================================================================================

//==========================================================================================================================================
// ammend validated field
// This will change the validated fields background colour and focus on the field if it has been rejected

function reject(thisField){
	thisField.style.backgroundColor = invalidFieldColour;
	thisField.focus();
	if (thisField.tagName != 'SELECT'){thisField.select();}
	return false;
}

function accept(thisField){
	thisField.style.backgroundColor = validFieldColour;
}

//==========================================================================================================================================

//==========================================================================================================================================
// validate an email address

function validateEmail(theEmail) {
	var str = theEmail;
	var reg1 = /(@.*@)|(\.\.)|(@\.)|(\.@)|(^\.)/;
	var reg2 = /^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,3}|[0-9]{1,3})(\]?)$/;
	if (!reg1.test(str) && reg2.test(str)) {
		return true;
	}
}

//==========================================================================================================================================

//==========================================================================================================================================
// check against list of valid characters

function checkStringValid(string,validchars) {
	var charstovalidate = string.split('');
	for( var i=0; i < charstovalidate.length; i++){
		if (validchars.indexOf(charstovalidate[i]) == -1){ 
			return false;
		}
	}
	return true;
}

//==========================================================================================================================================

//==========================================================================================================================================
// check against list of invalid characters

function checkStringInvalid(string,invalidchars) {
	var charstovalidate = string.split('');
	for( var i=0; i < charstovalidate.length; i++){
		if (invalidchars.indexOf(charstovalidate[i]) != -1){ 
			return false;
		}
	}
	return true;
}

//==========================================================================================================================================

//==========================================================================================================================================
// validate a numerical value

function checkNumeric(string) {
	var goodNumeric=/(^-*\d+$)|(^-*\d+\.\d+$)/
	if (goodNumeric.test(string)) {
		return true;
	}
}

//==========================================================================================================================================

//==========================================================================================================================================
// validate date

function AdvancedCheckDateValid(string) {
	var seperatorOK = 0;
	var retrieveSeperator = dateFormat.replace(/[a-zA-Z0-9]/g, "") // returns //
	var checkSeperator = retrieveSeperator.split('');// returns [/][/]
	var seperator = checkSeperator[0];// returns /
	var checkReqDigits = dateFormat.split(seperator); //[dd][mm][yyyy]
	var noSeg = checkReqDigits.length;// returns 3
	
	var stringElements = string.split('');
	for( var e=0; e < stringElements.length; e++ ){
		if (stringElements[e] == seperator){ var seperatorOK = 1; }
	}

	if (seperatorOK == 1){
		var checkActDigits = string.split(seperator); //[0][0][0]
		for( var d=0; d < noSeg; d++ ){
			var whatSegment = d+1;
			var count = checkReqDigits[d].length; // returns 2,2,4
			var goodSegment=new RegExp("^\\d{"+count+"}$");
			if (!goodSegment.test(checkActDigits[d])) {
				return false;
			}
		}
		return true;
	} else { return false; }
	
}

//==========================================================================================================================================


function validateform(f) {
	var tempobj;
	var tempobj2;
	var teststring1;
	var teststring2;
		
	for (var i = 0; i < fieldstovalidate.length; i++) {
		
		tempobj=eval("f."+fieldstovalidate[i][0]);


//==========================================================================================================================================
// validate text fields

		if (fieldstovalidate[i][1] == 'text') {
			
			if (tempobj.value == '') {
				alert("Please fill out all required fields.\n The field '"+fieldstovalidate[i][2]+"' must be completed.");
				return reject(tempobj);
			} else { accept(tempobj); }
			
		}

//==========================================================================================================================================

//==========================================================================================================================================
// validate email fields

		if (fieldstovalidate[i][1] == 'email') {
			
			if(tempobj.value.length>0)
			{
				if(!validateEmail(tempobj.value))
				{
			 		alert("The email you have supplied appears not to be valid.\n Please ensure you supply a valid email for '"+fieldstovalidate[i][2]+"'.");
					return reject(tempobj);
			 	} else { accept(tempobj); }
			} else {
				alert("Please enter a valid email for '"+fieldstovalidate[i][2]+"'.");
				return reject(tempobj);
			}
			
		}

//==========================================================================================================================================

//==========================================================================================================================================
// validate dropdown menus

		if (fieldstovalidate[i][1] == 'dropdown') {
			
			if (tempobj.options.selectedIndex==0) {
				alert("Please make a selection from the '"+fieldstovalidate[i][2]+"' dropdown menu.");
				return reject(tempobj);
			} else { accept(tempobj); }
			
			if(fieldstovalidate[i][3])
			{
				tempobj2=eval("f."+fieldstovalidate[i][3]);
				if(tempobj.options.selectedIndex==(tempobj.options.length-1))
				{
					if(tempobj2.value=="")
					{
						alert("You have chosen an option not listed in the '"+fieldstovalidate[i][2]+"' dropdown menu.\n Please fill in the extra provided text field.");
						tempobj2.style.backgroundColor = '#ffcc66';
						tempobj2.focus();
						return false;
					}
				}
			}
			
		}

//==========================================================================================================================================

//==========================================================================================================================================
// validate number fields e.g. telephone numbers

		if (fieldstovalidate[i][1] == 'contactNo') {
			
			if (tempobj.value == '') {
				alert("Please enter '"+fieldstovalidate[i][2]+"' number.");
				return reject(tempobj);
			} else { 
			
				if(!checkStringValid(tempobj.value,contactNoCharacters)) {
					alert("Please enter a valid '"+fieldstovalidate[i][2]+"' number.");
					return reject(tempobj);
				} else { accept(tempobj); }
			
			}
			
		}

//==========================================================================================================================================

//==========================================================================================================================================
// validate numerical fields

		if (fieldstovalidate[i][1] == 'numeric') {
			if(!checkNumeric(tempobj.value)) {
				alert("Please enter a valid number for '"+fieldstovalidate[i][2]+"'.");
				return reject(tempobj);
			} else { accept(tempobj); }
			
		}

//==========================================================================================================================================

//==========================================================================================================================================
// validate anti spam code

		if (fieldstovalidate[i][1] == 'antiSpam') {
			tempobj2=eval("f."+fieldstovalidate[i][3]);
			if(tempobj.value != tempobj2.value) {
				alert("The '"+fieldstovalidate[i][2]+"' code you have entered does not appear to match.\n Please try again.");
				return reject(tempobj);
			} else { accept(tempobj); }
			
		}

//==========================================================================================================================================

//==========================================================================================================================================
// validate username

		if (fieldstovalidate[i][1] == 'userName') {
			
			if (tempobj.value.length < userNameMinLength){
				alert("The "+fieldstovalidate[i][2]+" you have entered is too short. Your "+fieldstovalidate[i][2]+" should be at least "+userNameMinLength+" characters.\n Please try again.");
				return reject(tempobj);
			} else if (tempobj.value.length > userNameMaxLength) {
				alert("The "+fieldstovalidate[i][2]+" you have entered is too long. Your "+fieldstovalidate[i][2]+" should be no more than "+userNameMaxLength+" characters.\n Please try again.");
				return reject(tempobj);
			} else {
				
				if(!checkStringInvalid(tempobj.value,userNameCharacters)) {
					alert("The "+fieldstovalidate[i][2]+" you have entered is invalid. Your "+fieldstovalidate[i][2]+" should NOT contain any of the following characters: "+userNameCharacters+".");
				return reject(tempobj);
				} else { accept(tempobj); }
				
			}
			
		}

//==========================================================================================================================================

//==========================================================================================================================================
// validate password

		if (fieldstovalidate[i][1] == 'password') {
			tempobj2=eval("f."+fieldstovalidate[i][3]);
			if (tempobj.value.length == ""){
				
				alert("Please enter a valid "+fieldstovalidate[i][2]+".");
				return reject(tempobj);
				
			} else if (tempobj2.value.length == "") {
				
				accept(tempobj);
				alert("You must repeat your "+fieldstovalidate[i][2]+".");
				return reject(tempobj2);
				
			} else if (tempobj.value == tempobj2.value){
				
				if (tempobj.value.length < passwordMinLength){
				alert("The "+fieldstovalidate[i][2]+" you have entered is too short. Your "+fieldstovalidate[i][2]+" should be at least "+passwordMinLength+" characters.\n Please try again.");
				return reject(tempobj);
				} else if (tempobj.value.length > passwordMaxLength) {
					alert("The "+fieldstovalidate[i][2]+" you have entered is too long. Your "+fieldstovalidate[i][2]+" should be no more than "+passwordMaxLength+" characters.\n Please try again.");
					return reject(tempobj);
				} else {
					
					if(!checkStringValid(tempobj.value,passwordCharacters)) {
						alert("The "+fieldstovalidate[i][2]+" you have entered is invalid. Your "+fieldstovalidate[i][2]+" must consist of only numbers and letters of the alphabet.");
						return reject(tempobj);
					} else { accept(tempobj); accept(tempobj2); }
					
				}
				
			} else {
				
				alert("The "+fieldstovalidate[i][2]+"s you have entered do no match.\n Please try again.");
				return reject(tempobj2);
				
			}
			
		}

//==========================================================================================================================================

//==========================================================================================================================================
// validate date fields

		if (fieldstovalidate[i][1] == 'date') {
			
			if (tempobj.value == '') {
				alert("Please enter a valid "+fieldstovalidate[i][2]+".");
				return reject(tempobj);
			} else { 
			
				if(!AdvancedCheckDateValid(tempobj.value)) {
					alert("Please enter a valid "+fieldstovalidate[i][2]+".\n You must use the following format: "+dateFormat+".");
					return reject(tempobj);
				} else { accept(tempobj); }
			
			}
			
		}

//==========================================================================================================================================

//==========================================================================================================================================
// validate file types

		if (fieldstovalidate[i][1] == 'fileType') {
			
			if(tempobj.value=="") {
				alert("Please select a file to upload. The field '"+fieldstovalidate[i][2]+"' must be completed");
				return reject(tempobj);
			} else {
				
				teststring1 = fileTypes.split(",");
				getExt = tempobj.value.split(".");
				teststring2 = getExt[getExt.length-1];
				
				var exfound=false;
				if(teststring2!="") {
					for(var p=0; p < teststring1.length; p++) {
						if(teststring1[p].toUpperCase()==teststring2.toUpperCase()) { exfound=true; }
					}
				}
				if(!exfound) {
					alert("The type of file you have selected to upload in the '"+fieldstovalidate[i][2]+"' field is not allowed by this server.\n\n The following types are supported: "+fileTypes+"");
					return reject(tempobj);
				} else { accept(tempobj); }
				
			}
			
		}

//==========================================================================================================================================

//==========================================================================================================================================
// validate radio buttons

		if (fieldstovalidate[i][1] == 'radioButton') {
			tempobj2 = tempobj.length;
			var theRadio = false;
			for (r = 0; r < tempobj2; r++) {
				if (tempobj[r].checked) { theRadio = tempobj[r].value; }
			}
			
			if (!theRadio){
				alert("Please select an option for '"+fieldstovalidate[i][2]+"'.");
				for (bc = 0; bc < tempobj.length; bc++) {
					tempobj[bc].style.backgroundColor = invalidFieldColour;
				}
				tempobj[0].focus();
				return false;
			} else {
				for (bc = 0; bc < tempobj.length; bc++) {
					tempobj[bc].style.backgroundColor = validFieldColour;
				}
			}
		} 

//==========================================================================================================================================
	}

	return true;
	
}