function validate(formRef)
{
	var i, j;          // global counters
	var fld, ft;       // reusable form field identifiers
	var fldName;       // the viewable name of the field
	var strFld;        // field value string
	var splFld;        // split field used to check format
	var isErr, strErr; // error handlers
	var isEmpty;       // checks if field is empty (zero length value)
	var regexp;        // regular expression for character matching

	// initialize error handlers
	strErr = "There were errors in the form!\n\n";
	isErr = false;
	isEmpty = false;

	// loop through each form element
	for (i=0; i<formRef.elements.length; i++)
	{
		// initialize form field
		fld = formRef.elements[i];
		ft = fld.type.toLowerCase();
		isEmpty = false;

		if (fld.name.indexOf("req") != -1)
		{
			if (ft.charAt(0) == "s")
			{
				// do simple empty check if form field is a select box
				if (fld.options[fld.selectedIndex].value.length == 0)
				{
					strErr += "There must select an item from " + getName(fld) + ".\n";
					isErr = true;
					isEmpty = true;
					highlight(getName(fld), true);
				}
				else
					highlight(getName(fld), false);
			}
			else if ((ft == "password" || ft == "text" || ft == "textarea" || ft == "hidden"))
			{
				// get and check form field name
				fldName = getName(fld);
				if (!fldName) return;
		
				// remove leading spaces
				fld.value = ltrim(fld.value);
			
				// remove trailing spaces
				fld.value = rtrim(fld.value);

				// check for an empty value if required
				if (fld.value.length == 0)
				{
					strErr += "There must be a value in field " + fldName + ".\n";
					isErr = true;
					isEmpty = true;
					highlight(fldName, true);
				}
				else
					highlight(fldName, false);
					
				if (fld.name.indexOf("email") != -1 && !isEmpty)
				{
					if (!checkEmail(fld))
					{
						strErr += "You have entered an invalid e-mail in field " + fldName + ".\n";
						isErr = true;
						highlight(fldName, true);
					}
				}
				else if (fld.name.indexOf("phone") != -1 && !isEmpty)
				{
					if (!checkPhone(fld))
					{
					strErr += "You have entered an invalid phone number in field " + fldName + ".\rPlease format as 123-123-1234\n";
						isErr = true;
						highlight(fldName, true);
					}
				}
				else if (fld.name.indexOf("zip") != -1 && !isEmpty)
				{
					if (!checkZip(fld))
					{
						strErr += "You have entered an invalid zip code in field " + fldName + ".\n";
						isErr = true;
						highlight(fldName, true);
					}
				}
				else if (fld.name.indexOf("password") != -1 && !isEmpty)
				{
					if (!checkPassword(fld))
					{
						strErr += "You have entered an invalid password in field " + fldName + ".\n";
						isErr = true;
						highlight(fldName, true);
					}
				}
				else if (fld.name.indexOf("time") != -1 && !isEmpty)
				{
					if (!checkTime(fld))
					{
						strErr += "You have entered an invalid time in field " + fldName + ".\n";
						isErr = true;
						highlight(fldName, true);
					}
				}
				else if (fld.name.indexOf("date") != -1 && !isEmpty)
				{
					if (!checkDate(fld))
					{
						strErr += "You have entered an invalid date in field " + fldName + ".\n";
						isErr = true;
						highlight(fldName, true);
					}
				}
	
				if (fld.name.indexOf("l(") != -1 && !isEmpty)
				{
					var chkLthArray = checkLength(fld);
					if (!chkLthArray[0])
					{
						strErr += chkLthArray[1];
						isErr = true;
						highlight(fldName, true);
					}
				}
			}
		}
		else if (fld.name.indexOf("chk") != -1)
		{
			// get and check form field name
			fldName = getName(fld);
			if (!fldName) return;
	
			// remove leading spaces
			fld.value = ltrim(fld.value);
		
			// remove trailing spaces
			fld.value = rtrim(fld.value);

			if (fld.value.length == 0)
				isEmpty = true;
			highlight(fldName, false);

			if (fld.name.indexOf("email") != -1 && !isEmpty)
			{
				if (!checkEmail(fld))
				{
					strErr += "You have entered an invalid e-mail in field " + fldName + ".\n";
					isErr = true;
					highlight(fldName, true);
				}
			}
			else if (fld.name.indexOf("phone") != -1 && !isEmpty)
			{
				if (!checkPhone(fld))
				{
					strErr += "You have entered an invalid phone number in field " + fldName + ".\rPlease format as 123-123-1234\n";
					isErr = true;
					highlight(fldName, true);
				}
			}
			else if (fld.name.indexOf("zip") != -1 && !isEmpty)
			{
				if (!checkZip(fld))
				{
					strErr += "You have entered an invalid zip code in field " + fldName + ".\n";
					isErr = true;
					highlight(fldName, true);
				}
			}
			else if (fld.name.indexOf("password") != -1 && !isEmpty)
			{
				if (!checkPassword(fld))
				{
					strErr += "You have entered an invalid password in field " + fldName + ".\n";
					isErr = true;
					highlight(fldName, true);
				}
			}
			else if (fld.name.indexOf("time") != -1 && !isEmpty)
			{
				if (!checkTime(fld))
				{
					strErr += "You have entered an invalid time in field " + fldName + ".\n";
					isErr = true;
					highlight(fldName, true);
				}
			}
			else if (fld.name.indexOf("date") != -1 && !isEmpty)
			{
				if (!checkDate(fld))
				{
					strErr += "You have entered an invalid date in field " + fldName + ".\n";
					isErr = true;
					highlight(fldName, true);
				}
			}

			if (fld.name.indexOf("l(") != -1 && !isEmpty)
			{
				var chkLthArray = checkLength(fld);
				if (!chkLthArray[0])
				{
					strErr += chkLthArray[1];
					isErr = true;
					highlight(fldName, true);
				}
			}
		}
	}	

	function checkEmail(fld)
	{
		// check formatting for an e-mail address
		//regexp = /^\w(\.?\w)*@\w(\.?[-\w])*\.([a-z]{3}(\.[a-z]{2})?|[a-z]{2}(\.[a-z]{2})?)$/i;
		regexp = /^\w+\S*@\w(\.?\S)*\.([a-z]{3}(\.[a-z]{2})?|[a-z]{2}(\.[a-z]{2})?)$/i;
		return regexp.test(fld.value);
	}
	
	/*function checkPhone(fld)
	{
		// check formatting for a phone number
		regexp = /\d{3}-\d{3}-\d{4}/;
		return regexp.test(fld.value);
	}*/

	function checkPhone(fld)
	{
		// check formatting for a phone number
		regexp = /^(\+\d{1,3} ?)?(\(\d{1,5}\)|\d{1,5}) ?\d{3,4} ?\d{0,7}$/i;
	
		// handle dashes and dialing codes
		fld.value = fld.value.replace(/[-]/g, " ");
		fld.value = fld.value.replace(/[.]/g, " ");
		fld.value = fld.value.replace(/[_]/g, " ");
		fld.value = fld.value.replace(/[(]/g, "");
		fld.value = fld.value.replace(/[)] /g, " ");
		fld.value = fld.value.replace(/[)]/g, " ");
		fld.value = fld.value.replace(/^(1 )/, "+1 ");
		fld.value = fld.value.replace(/^(44 )/, "+44 ");
	
		return regexp.test(fld.value);
	}
	
	function checkZip(fld)
	{
		// check formatting for a zip code
		regexp = /^\d{5}(-\d{4})?$/i;
		return regexp.test(fld.value);
	}
	
	function checkPassword(fld)
	{
		// check password for spaces and bad characters
		regexp = /[^a-z\d]/i;
		return !regexp.test(fld.value);
	}
	
	function checkTime(fld)
	{
		// check for a valid time
		regexp = /^(0?[1-9]|1[0-2]):([0-5]\d) ?(am|pm)$/i;
		return regexp.test(fld.value);
	}
	
	function checkDate(fld)
	{
		// check for a valid date
		var isDateErr = false;
		var date = fld.value;
		var months = ["january", "february", "march", "april", "may", "june", "july", "august", 
			"september", "october", "november", "december"];
	
		// replace "date" or "now" with the current date
		if (date.toLowerCase() == "date" || date.toLowerCase() == "now")
		{
			var now = new Date();
			date = (now.getMonth() + 1) + "/" + now.getDate() + "/" + now.getYear();
			fld.value = date;
		}
	
		// remove bad characters and strings from the date
		date = date.replace(/[,]/g, "");
		date = date.replace(/(nd|rd|th)/i, "");
	
		// parse out the different parts of the date
		if (date.indexOf("/") != -1)
			splFld = date.split("/");
		else if (date.indexOf("-") != -1)
			splFld = date.split("-");
		else
			splFld = date.split(" ");
	
		if (splFld.length != 3)
			isDateErr = true;
	
		// check and convert month (if it's a string)
		var isMonth = false;
	
		if (isNaN(splFld[0]))
		{
			splFld[0] = splFld[0].toLowerCase();
			for (i=0; i<months.length; i++)
			{
				if (splFld[0] == months[i] || splFld[0] == months[i].substr(0, 3))
				{
					isMonth = true;
					splFld[0] = i;
					break;
				}
			}
		}
		else
		{
			isMonth = true;
			splFld[0]--;
		}
	
		if (!isMonth && !isDateErr)
			isDateErr = true;
	
		if ((!splFld[2] || splFld[2].length < 4 || splFld[2].length > 4) && !isDateErr)
			isDateErr = true;
	
		// check the date for validity
		date = new Date();
		date.setMonth(splFld[0]);
		date.setDate(splFld[1]);
		date.setYear(splFld[2]);
		if (date.getDate() != splFld[1] && !isDateErr)
			isDateErr = true;
	
		// reformat the date in the box (if it's needed)
		if (!isDateErr)
			fld.value = (++splFld[0]) + "/" + splFld[1] + "/" + splFld[2];
		return !isDateErr;
	}
	
	function checkLength(fld)
	{
		// copies of global variables
		var isErr = false;
		var strErr = "";
		var fldName = getName(fld);
		
		// get length coordinates
		var s1 = fld.name.indexOf("l(") + 2;
		var s2 = fld.name.indexOf(",", s1);
		var e = fld.name.indexOf(")", s2) - 1;
	
		// get min and max lengths
		var minLength = fld.name.substr(s1, s2 - s1);
		var maxLength = fld.name.substr(s2 + 1, e - s2);
	
		// check length of field
		if (fld.value.length < minLength || fld.value.length > maxLength)
		{
			if (minLength != maxLength)
				strErr = "The length of field " + fldName + " must be between " + minLength + " and " + maxLength + " characters.\n";
			if (fld.name.indexOf("phone") != -1 && !isEmpty)
				strErr = "The length of field " + fldName + " must be " + parseInt(minLength-2) + " digits.\n";						
	
			isErr = true;
		}
		
		return [!isErr, strErr];
	}

	if (isErr)
		alert(strErr);
	else
	{
		if (formRef.elements["DeleteButton"])
		{
			var doDelete = confirm("Do you really want to delete this?");
			if (doDelete)
				formRef.submit();
		}
		else
			formRef.submit();
	}
}

function getName(field)
{
	// grab field's full name and split it
	var strName = field.name;
	var strNameArray = strName.split("*");
	
	// get the viewable name and format it for viewing
	if (strNameArray.length == 2)
	{
		strName = strNameArray[1];
		strName = strName.replace(/\^/g, " ");
	}
	else
	{
		alert("The field name for " + field.name + " is formatted incorrectly.");
		return false;
	}
	
	return strName; // return the formatted field name
}

function getObj(label)
{
	// get the label to change
	if (document.all)
		return document.all[label];
	else if (document.getElementById)
		return document.getElementById(label);
}

function ltrim(strTrim)
{
	// remove leading spaces in a string
	var i, start;

	for (i=0; i<strTrim.length; i++)
	{
		if (strTrim.charAt(i) != " ")
		{
			start = i;
			break;
		}
	}

	return strTrim.substr(start);
}

function rtrim(strTrim)
{
	// remove trailing spaces in a string
	var i, end;

	for (i=strTrim.length-1; i>=0; i--)
	{
		if (strTrim.charAt(i) != " ")
		{
			end = i;
			break;
		}
	}

	return strTrim.substr(0, end + 1);
}

function highlight(label, toggle)
{
	var clr = toggle ? "red" : "black";
	if (document.all)
		document.all[label].style.color = clr;
	else if (document.getElementById)
		document.getElementById(label).style.color = clr;
}

function textLimit(field, maxlen) {
if (field.value.length > maxlen) {
field.value = field.value.substring(0, maxlen);
alert('Your text input has exceeded the available field space! Please revise your message. Thank You');
} }