﻿// JavaScript Document
//
//	To Validate with Event Handlers:-
//
//		<input ... .. onChange="validateMe(this, '<req>', '<type>');">
//	
//		this = reference to calling object
//		<req> & <type> see codes below, must be inside single quotes
//	
//	To Validate onSubmit
//
//		<form ... ... onSubmit="return validateForm();">
//	
//		make sure each form field that requires validating is named thus:-
//	
//		<input ... ... name="V _ _ __ <name of field>" ... >
//	
//		V followed by 2 letters, followed by a double underscore, followed by the field name
//
//	2nd letter or <req> for input fields and select lists
//		O = Optional value
//		R = Required value
//
//	2nd letter for checkbox's
//		R = requires 1 box or more checked
//		<number> = any number means exactly that amount of boxes checked
//		** note that if there is only one checkbox, R will validate to the effect that the checkbox must be checked
//		but a number will be ignored
//	
//	3rd letter or <type>
//		A = IP Address
//		B =
//		C = Checkbox - used to validate checkbox's
//		D = Date - reformats to long date
//		E = Email - removes leading spaces
//		F = Float - to 2dec. places (can be used for pounds and pence), removes spaces
//		4 = Float - to any dec. places, removes spaces
//		3 = Float - to 3 dec. places, removes spaces - modded by skv
//		G =
//		H =
//		I = Integer - removes all spaces in string
//		J =
//		K =
//		L =
//		M = Money - pounds and pence, removes comma's & spaces
//		N = Month in number format - 1 or 2 digits
//		O =
//		P = Postcode in UK format
//		Q =
//		R =
//		S =
//		T = Time - converts to 24hr format
//		U =
//		V = Value - anything, removes leading spaces
//		W = Whole Number either + or -
//		X =
//		Y = Year in 4 digit format, upto current year
//		Z =

var months = new Array("","January","February","March","April","May","June","July","August","September","October","November","December");

// this function moves focus to the specified field
function initial(field) {
	setTimeout('document.form1.elements[\'' + field + '\'].focus()', 25);
	setTimeout('document.form1.elements[\'' + field + '\'].select()', 25);
}
	
// this function removes leading spaces and can check for data in a field
function validateValue(obj, req) {
	str = obj.value;
	if(req) {
		re_val = /^(.+\n*)+$/;
		if (!(re_val.test(str))) {
			alert("Please enter relevant information\nor `select` relevant option!");
			highlight(obj, 0);
			setTimeout('document.form1.elements[\'' + obj.name + '\'].focus()', 25);
			setTimeout('document.form1.elements[\'' + obj.name + '\'].select()', 25);
			return false;
		}
		else {
			obj.value = str.replace(/\s*/,"");
			highlight(obj, 1);
			return true;
		}
	}
	else {
		obj.value = str.replace(/\s*/,"");
		return true;
	}
}

// this function checks for an integer value
function validateInteger(obj, req) {
	str = obj.value;
	if(req)
		re_val = /^(\s*\d+\s*)+$/;
	else
		re_val = /^(\s*\d+\s*)*$/;
	if (!(re_val.test(str))) {
		alert("Please enter numbers (only)!");
		highlight(obj, 0);
		setTimeout('document.form1.elements[\'' + obj.name + '\'].focus()', 25);
		setTimeout('document.form1.elements[\'' + obj.name + '\'].select()', 25);
		return false;
	}
	else {
		obj.value = str.replace(/\s*/g,"");
		highlight(obj, 1);
		return true;
	}
}

// this function checks for an integer value
function validateWholeNumber(obj, req) {
	str = obj.value;
	if(req)
		re_val = /^([-]*\s*\d+\s*)+$/;
	else
		re_val = /^([-]*\s*\d+\s*)*$/;
	if (!(re_val.test(str))) {
		alert("Please enter numbers (only)!");
		highlight(obj, 0);
		setTimeout('document.form1.elements[\'' + obj.name + '\'].focus()', 25);
		setTimeout('document.form1.elements[\'' + obj.name + '\'].select()', 25);
		return false;
	}
	else {
		obj.value = str.replace(/\s*/g,"");
		highlight(obj, 1);
		return true;
	}
}

//checks for a valid month in number format
function validateMonth(obj, req) {
	if(validateInteger(obj, req)) {
		if(month_OK(parseInt(obj.value.replace(/[0]*/,""))))
			return true
		else {
			highlight(obj, 0);
			setTimeout('document.form1.elements[\'' + obj.name + '\'].focus()', 25);
			setTimeout('document.form1.elements[\'' + obj.name + '\'].select()', 25);
			return false;
		}
	}
}

//checks for a valid year in 4 digit format, upto and including the current year
function validateYear(obj, req) {
	if(validateInteger(obj, 1)) {
		str = obj.value;
		now = new Date();
		yr_now = now.getYear();
		re_val = /^([1-2]){1}(\d){3}$/;
		if ((re_val.test(str)) && (str <= yr_now) && (str > 1919)) {
			obj.value = str.replace(/\s*/g,"");
			highlight(obj, 1);
			return true;
		}
		else {
			alert("Please enter a valid year in 4 digit format (between 1920 and " + yr_now + ")");
			highlight(obj, 0);
			setTimeout('document.form1.elements[\'' + obj.name + '\'].focus()', 25);
			setTimeout('document.form1.elements[\'' + obj.name + '\'].select()', 25);
			return false;
		}
	}
}

// this function checks for a valid postcode
function validatePostcode(obj, req) {
	str = obj.value;
	if(req)
		re_val = /^([a-zA-Z]{1,2}[0-9]{1}[0-9a-zA-Z]?\s{1}[0-9]{1}[a-zA-Z]{2}){1}$/;
	else
		re_val = /^([a-zA-Z]{1,2}[0-9]{1}[0-9a-zA-Z]?\s{1}[0-9]{1}[a-zA-Z]{2})?$/;
	if (!(re_val.test(str))) {
		alert("Please enter a valid Post Code");
		highlight(obj, 0);
		setTimeout('document.form1.elements[\'' + obj.name + '\'].focus()', 25);
		setTimeout('document.form1.elements[\'' + obj.name + '\'].select()', 25);
		return false;
	}
	else {
		obj.value = str.toUpperCase();
		highlight(obj, 1);
		return true;
	}
}

// this function checks for a valid amount to 2 decimal places
function validateDecMoney(obj, req) {
	str = obj.value;
	if(req)
		re_val = /^(\s*\d+(\,*\d*)*([.][\d][\d])?){1}$/;
	else
		re_val = /^(\s*\d+(\,*\d*)*([.][\d][\d])?)?$/;
	re_dig = /^\s*\d+$/;
	if (!(re_val.test(str))) {
		alert("Please enter an amount in one of the following formats:-\n\nx       - a single digit, or\nx.xx  (to 2 decimal places)");
		highlight(obj, 0);
		setTimeout('document.form1.elements[\'' + obj.name + '\'].focus()', 25);
		setTimeout('document.form1.elements[\'' + obj.name + '\'].select()', 25);
		return false;
	}
	else {
		if (re_dig.test(str)) {
			str += ".00";
			obj.value = str;
		}
		obj.value = str.replace(/\s*\,*/g,"");
		highlight(obj, 1);
		return true;
	}
}

// this function checks for a valid amount to any decimal places
function validateFloat(obj, req) {
	str = obj.value;
	if(req)
		re_val = /^(\s*\d+(\,*\d*)*([.][\d]*)?){1}$/;
	else
		re_val = /^(\s*\d+(\,*\d*)*([.][\d]*)?)?$/;
	re_dig = /^\s*\d+$/;
	if (!(re_val.test(str))) {
		alert("Please enter an amount using numbers and a decimal point");
		highlight(obj, 0);
		setTimeout('document.form1.elements[\'' + obj.name + '\'].focus()', 25);
		setTimeout('document.form1.elements[\'' + obj.name + '\'].select()', 25);
		return false;
	}
	else {
		if (re_dig.test(str)) {
			str += ".00";
			obj.value = str;
		}
		obj.value = str.replace(/\s*\,*/g,"");
		highlight(obj, 1);
		return true;
	}
}

// this function checks for a valid amount to 3 decimal places
function validateFloat3(obj, req) {
	str = obj.value;
	if(req)
		re_val = /^(\s*\d+(\,*\d*)*([.][\d][\d][\d])?){1}$/;
	else
		re_val = /^(\s*\d+(\,*\d*)*([.][\d][\d][\d])?)?$/;
	re_dig = /^\s*\d+$/;
	if (!(re_val.test(str))) {
		alert("Please enter an amount using numbers and a decimal point with upto 3 digits after the point");
		highlight(obj, 0);
		setTimeout('document.form1.elements[\'' + obj.name + '\'].focus()', 25);
		setTimeout('document.form1.elements[\'' + obj.name + '\'].select()', 25);
		return false;
	}
	else {
		if (re_dig.test(str)) {
			str += ".000";
			obj.value = str;
		}
		obj.value = str.replace(/\s*\,*/g,"");
		highlight(obj, 1);
		return true;
	}
}

// this function checks for an amount in pounds and pence format, and removes any commas and spaces
function validateMoney(obj, req) {
	str = obj.value;
	if(req)
		re_val = /^(\s*\d+(\,*\d*)*([.][\d][\d])?){1}$/;
	else
		re_val = /^(\s*\d+(\,*\d*)*([.][\d][\d])?)?$/;
	re_dig = /^\s*\d+(\,*\d*)*$/;
	if (!(re_val.test(str))) {
		alert("Please enter an amount in one of the following formats:-\n\nx       - a single digit, or\nx.xx  (pounds and pence)");
		highlight(obj, 0);
		setTimeout('document.form1.elements[\'' + obj.name + '\'].focus()', 25);
		setTimeout('document.form1.elements[\'' + obj.name + '\'].select()', 25);
		return false;
	}
	else {
		if (re_dig.test(str)) {
			str += ".00";
			obj.value = str;
		}
		obj.value = str.replace(/\s*\,*/g,"");
		highlight(obj, 1);
		return true;
	}
}

// this function checks for a valid time, and re - formats the string into 24hr clock notation
function validateTime(obj, req) {
	if(!(req) && obj.value == "") {
		highlight(obj, 1);
		return true;
	}
	else {
		errorstr = "";
		timestr  = obj.value;
		obj.value = timestr.replace(/\s*/,"");
		re_val = /^\s*(([0-2]?[0-9])[\W]([0-5][0-9])([\W][\aApP][mM])?){1}$/;
		if (!(re_val.test(timestr))) {
			alert("Please enter a Time in one of the following formats:\n\n x:xx (24 hour clock)\nxx:xx (24 hour clock)\n x:xx am (or pm)\nxx:xx am (or pm)\n\nwith no more than one character or space between the hour and minutes\nand between the am or pm if using the 12 hour clock format!");
			highlight(obj, 0);
			setTimeout('document.form1.elements[\'' + obj.name + '\'].focus()', 25);
			setTimeout('document.form1.elements[\'' + obj.name + '\'].select()', 25);
			return false;
		}
		else {
			tstr = timestr.split(/\W/);
			if(parseInt(tstr[1]) > 59)
				errorstr += "The minutes are an invalid value!\n";
			if(tstr.length == 2) {
				if(parseInt(tstr[0]) > 23)
					errorstr += "The hours are an invalid value for 24 hour clock notation!\n";
			}
			else {
				switch(tstr[2]) {
					case "am"	:	
					case "pm"	:	
					case "AM"	:
					case "PM"	: 	if(parseInt(tstr[0]) > 12)
										errorstr += "The hours are an invalid value for 12 hour clock notation!\n";
									break;
				}
			}
			if(errorstr) {
				alert(errorstr);
				highlight(obj, 0);
				setTimeout('document.getElementById(\'' + obj.id + '\').focus()', 25);
				setTimeout('document.getElementById(\'' + obj.id + '\').select()', 25);
				return false;
			}
			else {
				if(tstr.length == 3)
					tstr[0] = parseInt(tstr[0]) + 12;
				rplstr = tstr[0] + ":" + tstr[1];
				obj.value = rplstr;
				highlight(obj, 1);
				return true;
			}
		}
	}
}

// the next few following functions check for a valid date, and re-format the string into a long date format
function validateDate(objid, req) {
	objval = document.getElementById(objid).value;
	if(!(req) && (objval == "")) {
		highlight(objid, 1);
		return true;
	}
	else {
		re_dt_a = /^(([\d][\d]?)[\W]([\d][\d]?)[\W]([\d][\d][\d][\d])){1}$/;
		re_dt_b = /^(([\d][\d]?)[\W]([\w]+)[\W]([\d][\d][\d][\d])){1}$/;
		re_sp = /\W/;
		if (re_dt_a.test(objval)) {						// test for format dd/mm/yyyy etc...
			datestr = objval.split(re_sp);					// split date string into day, month, year
			day = parseInt(datestr[0].replace(/[0]*/,""));
			month = parseInt(datestr[1].replace(/[0]*/,""));
			year = parseInt(datestr[2]);
			if (month_OK(month)) {						// check month is valid
				if (day_OK(day, month, year)) {			//check if day is valid for month & year
					document.getElementById(objid).value = day + " " + months[month] + " " + year;			//reformat input field if all OK
					highlight(objid, 1);
					return true;
				}
			}
		}
		else if (re_dt_b.test(objval)) {					// test for format dd <Month name> yyyy etc...
			datestr = objval.split(re_sp);					// split date string into day, month, year
			day = parseInt(datestr[0].replace(/[0]*/,""));
			month = datestr[1];
			year = parseInt(datestr[2]);
			month_num = 0;
			for (i=1;i<=months.length;i++) {			// check <Month name> is valid month name
				if (months[i] == month)
					month_num = i;
			}
			if (month_OK(month_num)) {					// use month_OK to report error if month not valid
				if (day_OK(day, month_num, year)) {		// check if day is valid for month & year
					document.getElementById(objid).value = day + " " + month + " " + year;			//reformat input field if all OK
					highlight(objid, 1);
					return true;
				}
			}
		}
		else
			date_error(0);								// report error if no format match is found
		highlight(objid, 0);
		setTimeout('document.getElementById(\'' + objid + '\').focus()', 25);
		setTimeout('document.getElementById(\'' + objid + '\').select()', 25);
		return false;									// if it got this far there was an error - returns a false
	}
}

function date_error(error) {						// displays an error message
	switch (error) {
		case 0	:	alert("You have entered a date in an invalid format!\nPlease correct!\nThe date format should be:\nDD/MM/YYYY or\nDD/M/YYYY or\nD/MM/YYYY or\nD/M/YYYY or\nD <Month name> YYYY or\nDD <Month name> YYYY");
					break;
		case 1	:	alert("You have entered an invalid month - Please correct!");
					break;
		case 2	:	alert("You have entered an invalid day of the month - Please correct!");
					break;
	}
}

function month_OK(month) {
	if ((month > 0) && (month <= 12)) {				// checks for valid month & report error if not...
		return true;
	}
	else {
		date_error(1);
		return false;
	}
}

function day_OK(day, month, year) {					// checks for valid day of month & reports error if not...
	switch (month) {
		case 4	:
		case 6	:
		case 9	:
		case 11 :	if (day <= 30)
						return true;
					else
						date_error(2);
					break;
		case 1	:
		case 3	:
		case 5	:
		case 7	:
		case 8	:
		case 10	:
		case 12	:	if (day <= 31)
						return true;
					else
						date_error(2);
					break;
		case 2	:	if (leap_year(year)) {
						if (day <= 29)
							return true;
						else
							date_error(2);
					}
					else {
						if (day <= 28)
							return true;
						else
							date_error(2);
					}
					break;
	}
	return false;
}

function leap_year(year) {								// checks if <year> is a leap year
	if (!(year % 4 == 0))
		return false;
	if (year % 100 == 0)
		if (!(year % 400 == 0))
			return false;
	return true;
}
// end of date validation functions

function validateEmail(objid, req) {
	objval = document.getElementById(objid).value;
	if (!(req) && (objval == "")) {
		highlight(objid, 1);
		return true;
	}
	str = objval;
	if(req)
		re_val = /^(\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+){1}$/;
	else
		re_val = /^(\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+)?$/;
	if (!(re_val.test(str))) {
		alert("Please enter a valid Email Address!");
		highlight(objid, 0);
		setTimeout('document.getElementById(\'' + objid + '\').focus()', 25);
		setTimeout('document.getElementById(\'' + objid + '\').select()', 25);
		return false;
	}
	else {
		document.getElementById(objid).value = str.replace(/\s*/, "");
		highlight(objid, 1);
		return true;
	}
}

function validateIP(obj, req) {
	str = obj.value;
	if(req)
		re_val = /^((([0-1]?[0-9]?[0-9]{1}|[2]{1}[0-4]{1}[0-9]{1}|[2]{1}[5]{1}[0-5]{1})[.]){3}(([0-1]?[0-9]?[0-9]{1}|[2]{1}[0-4]{1}[0-9]{1}|[2]{1}[5]{1}[0-5])){1}){1}$/;
	else
		re_val = /^((([0-1]?[0-9]?[0-9]{1}|[2]{1}[0-4]{1}[0-9]{1}|[2]{1}[5]{1}[0-5]{1})[.]){3}(([0-1]?[0-9]?[0-9]{1}|[2]{1}[0-4]{1}[0-9]{1}|[2]{1}[5]{1}[0-5])){1})?$/;
	if (!(re_val.test(str))) {
		alert("Please enter a valid IP Address!");
		highlight(obj, 0);
		setTimeout('document.form1.elements[\'' + obj.name + '\'].focus()', 25);
		setTimeout('document.form1.elements[\'' + obj.name + '\'].select()', 25);
		return false;
	}
	else {
		obj.value = str.replace(/\s*/,"");
		highlight(obj, 1);
		return true;
	}
}

function validateCheckbox(obj, req) {
	re_dig = /^\d+$/;
	numchked = 0;

	if(document.form1.elements[obj.name].length) {
		if(req == "R") {
			for(chkbx=0;chkbx<document.form1.elements[obj.name].length;chkbx++) {
				if(document.form1.elements[obj.name][chkbx].checked == true)
					numchked += 1;
			}
			if(numchked > 0) {
				for(chkbx=0;chkbx<document.form1.elements[obj.name].length;chkbx++) {
					document.form1.elements[obj.name][chkbx].style.backgroundColor = "";
				}
				return true;
			}
			else {
				alert("At least one box must be ticked!");
				for(chkbx=0;chkbx<document.form1.elements[obj.name].length;chkbx++) {
					document.form1.elements[obj.name][chkbx].style.backgroundColor = "#FFAAAA";
				}
				setTimeout('document.form1.elements[\'' + obj.name + '\'][0].focus()', 25);
				setTimeout('document.form1.elements[\'' + obj.name + '\'][0].select()', 25);
				return false;
			}
		}
		else if(re_dig.test(req)) {
			for(chkbx=0;chkbx<document.form1.elements[obj.name].length;chkbx++) {
				if(document.form1.elements[obj.name][chkbx].checked == true)
					numchked += 1;
			}
			if(numchked == req) {
				for(chkbx=0;chkbx<document.form1.elements[obj.name].length;chkbx++) {
					document.form1.elements[obj.name][chkbx].style.backgroundColor = "";
				}
				return true;
			}
			else {
				alert("Exactly " + req + " boxes must be ticked!");
				for(chkbx=0;chkbx<document.form1.elements[obj.name].length;chkbx++) {
					document.form1.elements[obj.name][chkbx].style.backgroundColor = "#FFAAAA";
				}
				setTimeout('document.form1.elements[\'' + obj.name + '\'][0].focus()', 25);
				setTimeout('document.form1.elements[\'' + obj.name + '\'][0].select()', 25);
				return false;
			}
		}
		else
			return false;
	}
	else {
		if(req == "R") {
			if(document.form1.elements[obj.name].checked == true) {
				document.form1.elements[obj.name].style.backgroundColor = "";
				return true;
			}
			else {
				alert("The box must be ticked!");
				document.form1.elements[obj.name].style.backgroundColor = "#FFAAAA";
				setTimeout('document.form1.elements[\'' + obj.name + '\'].focus()', 25);
				setTimeout('document.form1.elements[\'' + obj.name + '\'].select()', 25);
				return false;
			}
		}
	}
}

function highlight(objid, cancel) {
	if(cancel)
	    document.getElementById(objid).style.backgroundColor = "";
	else
		document.getElementById(objid).style.backgroundColor = "#FFAAAA";
}
	
function validateForm() {
	str = "";
	required = 0;
	for(subchk=0;subchk<document.form1.length;subchk++) {
		if(document.form1.elements[subchk].name.charAt(0) == "V" && document.form1.elements[subchk].name.charAt(3) == "_" && document.form1.elements[subchk].name.charAt(4) == "_") {
			if(document.form1.elements[subchk].disabled == false) {
				if(!(validateMe(document.form1.elements[subchk], document.form1.elements[subchk].name.charAt(1), document.form1.elements[subchk].name.charAt(2)))){
					//alert(document.form1.elements[subchk].name);
					//alert(document.form1.elements[subchk].value);
					return false;
				}
			}
		}
	}
	return true;
}
	
function validateMe(obj, req, type) {

	if (validateMe.arguments.length == 1){
		nreq = obj.name.charAt(1);
		ntype = obj.name.charAt(2);
	}else{ 
		nreq=req;
		ntype=type;
	}

	switch(nreq) {
		case "O"	:	required = 0;
						break;
		case "R"	:	required = 1;
						break;
	}
	
	switch(ntype) {
		case "V"	:	return validateValue(obj, required);
						break;
		case "I"	:	return validateInteger(obj, required);
						break;
		case "P"	:	return validatePostcode(obj, required);
						break;
		case "F"	:	return validateDecMoney(obj, required);
						break;
		case "M"	:	return validateMoney(obj, required);
						break;
		case "T"	:	return validateTime(obj, required);
						break;
		case "D"	:	return validateDate(obj, required);
						break;
		case "E"	:	return validateEmail(obj, required);
						break;
		case "C"	:	return validateCheckbox(obj, req);
						break;
		case "N"	:	return validateMonth(obj, req);
						break;
		case "Y"	:	return validateYear(obj, req);
						break;
		case "W"	:	return validateWholeNumber(obj, req);
						break;
		case "4"	:	return validateFloat(obj, req);
						break;
		case "3"	:	return validateFloat3(obj, req);
						break;
		case "A"	:	return validateIP(obj, req);
						break;
	}
}