/*
	module name: validate_form.js
	date: Monday, March 31, 2008
	author: Jay Dansand (jay.dansand@gmail.com) for Lawrence University ITS
	configuration:
		You can specify your own alert messages (or disable alert messages) for when the form fails at some step of validation.
		Look at the definitions of required_fail_notice, email_fail_notice, and match_fail_notice below this header.
	usage:
		To use this script, include it in an HTML document, create any form, and assign a unique ID to that form.
		Add either or both of these hidden form inputs:
			input type="hidden" name="required" value="[comma-separated fields that are required]"
			input type="hidden" name="match" value="[comma-separated fields in couples that are required to match]"
		and add this JavaScript to the submit button:
			onclick="return validate_form('myform');"	where "myform" is the unique ID of the form.
		OR add this JavaScript to the form:
			onsubmit="return validate_form('myform');"
		Any required or matching fields must actually be added to the form as normal fields (input type="text", "area", "password", etc.)
		with a name that matches (CASE SENSITIVE) the names specified above.

			The "required" hidden input specifies (CASE SENSITIVE, comma-delimited) form fields that are required to be filled in
		before the form will submit.  Any field name with "email" or "e-mail" in it (not case sensitive) will be validated as an email field,
		which requires something@some.thing data before it will submit.  Any other field type merely requires some kind of data be present.
				Example: input type="hidden" name="required" value="name, email"	This requires a name and a valid-looking email.

			The "match" hidden input specifies (CASE SENSITIVE, comma-delimited) form field PAIRS that must match before the
		form is submitted.  Match fields are not REQUIRED fields, so if both fields are blank, the form is still considered valid, because
		blanks match.  If you want to require either field as well, place one or both of the field names in the name="required" input
		as described above.
			Enter fields as comma-separated lists of COUPLES, for example:
				input type="hidden" name="match" value="email, email2"	This requires that email and email2 have the same contents.
		You may match multiple sets:
				input type="hidden" name="match" value="email, email2, password, password2"
		The matches are tested as couples, so in the above case email must match email2, and password must match password2.  If you want
		to require the fields as well:
				input type="hidden" name="required" value="email,password"
				input type="hidden" name="match" value="email, email2, password, password2"
		This requires both email and password be specified, and that email and email2 have the same (CASE SENSITIVE) content, as well
		as password and password2.
		
	complete example:
		<html>
		<head>
		<script type="text/javascript" src="http://lawrence.edu/util/javascript/form2mail_validation/validate_form.js"></script>
		</head>
		<body>
		<form id="example_form">
			<input type="hidden" name="required" value="name, email">
			<input type="hidden" name="match" value="name, name2, user_email, email_verify">
			Name: <input type="text" name="name"><br />
			Name again to verify: <input type="text" name="name2"><br />
			Email: <input type="text" name="user_email"><br />
			Email again to verify: <input type="text" name="email_verify"><br />
			<input type="submit" onclick="return validate_form('example_form');">
		</form>
		</body>
		</html>
		Note that matching fields do not require any kind of similarity in names, only that they are specified as pairs in the match input.
		Also note: again, anything with "email" or "e-mail" anywhere in the name will be validated by "required" as an email-type input.
		
		
		UPDATE HISTORY:
		6/4/2008 - Ben Willard
		-Added optional validation for new form2mail sum-based CAPTCHA. Validation will occur automatically so long as the proper fields 
		for the sum CAPTCHA are present on the form. Those fields are CAPTCHA-sum-key,CAPTCHA-sum-answer,CAPTCHA-sum-1, and CAPTCHA-sum-2.
*/
//Specify the message to show users when required data is not present (leave blank for no alert box):
var required_fail_notice = "Please fill out all required information.";
//Specify the message to show users when an email address does not appear to be valid (leave blank for no alert box):
var email_fail_notice = "Please enter a valid email address.";
//Specify the message to show users when data does not match (leave blank for no alert box):
var match_fail_notice = "Information in fields does not match.";
//Specify the message to show users when the CAPTCHA response is not valid
var captcha_fail_notice = "The answer provided for the CAPTCHA is incorrect";
//--------------------------------------------------
//DO NOT MODIFY BELOW THIS LINE
//--------------------------------------------------
//Validate individual form fields, and make sure that fields with "email" or "e-mail" in the name are of email format
function validate_field(field)
{
	//Trim the value of the field (removing leading and trailing spaces)
	//Test the type of field we're validating (text, radio/checkbox, select, etc.)
	if (field.options)
	{	//This is a SELECT field or some other input.  At least one option must be selected.
		var options = field.options;	//A shorthand handle for the options
		for (var i = 0; i < options.length; ++i)	//iterate all elements; return true if one or more is selected.
			if (options[i].selected && options[i].value != "") return true;
		alert(required_fail_notice);
		return false;
	}
	else if (field.length)
	{	//A multiple element list such as radio or checkbox elements
		for (var i = 0; i < field.length; ++i)	//iterate all elements; return true if one or more is checked.
			if (field[i].checked) return true;
		//if no element is checked, then return false (radio or checkbox hasn't been selected)
		alert(required_fail_notice);
		return false;
	}
	else
	{	
		//A single element field, such as a text input, etc.
		var value = field.value.replace(/^\s+|\s+$/g,"")
		//Test if the field is an email field or not
		if (field.name.search(/e-?mail/i) >= 0)
		{	//An email field
			var email_match = /.+@([A-Za-z0-9]+[^\.]*[A-Za-z0-9]+\.)+[A-Za-z0-9]+[^\.]*[A-Za-z0-9]$/;
			if (email_match.test(value))	//Test if the email is valid-ish
				return true;
			else
			{	//If it isn't, alert the user and fail
				alert(email_fail_notice);	//Alert user
				return false;
			}
		}
		else	//Not an email field
			if (value.length > 0)	//Test the length, make sure some data was entered
				return true;
			else
			{	//If it wasn't, alert the user and fail
				alert(required_fail_notice);	//Alert user
				return false;
			}
	}
}

//Validate the form with ID = "formname", by making sure that all fields specified (comma-delimited) in the "required" field exist, and
//all couplets in the "match" field match (for email/password verification, etc.)
function validate_form(formname)
{
	//Get a handle for the form
	var form = (document.all) ? document.all[formname] : document.getElementById(formname);
	//Get the list of required fields
	var required = (!form.required) ? [""] : form.required.value.replace(/^\s+|\s+$/g,"").split(/,\s*/);
	//Get the list of matching fields
	var match = (!form.match) ? [""] : form.match.value.replace(/^\s+|\s+$/g,"").split(/,\s*/);
	//Iterate through all required fields and validate them
	for (index in required)
	{
		if (required[index] != "")
		{
			var field = eval("form." + required[index]);
			if (field)
			{
				if (!validate_field(field))
				{
					if (field.focus) field.focus();	//If we can, set focus on the field
					if (field.select) field.select();	//If we can, select all data in the field
					return false;	//Cancel form submission
				}
			}
		}
	}
	//Iterate through all match pairs and validate them
	for (var i = 0; i < match.length; i += 2)
	{
		if (match[i] != "" && match[i + 1] != "")
		{
			var field = eval("form." + match[i]);
			var field2 = eval("form." + match[i + 1]);
			if (field && field2)
			{
				if (field.value != field2.value)
				{
					if (field.focus) field.focus();	//If we can, set focus on the field
					if (field.select) field.select();	//If we can, select all data in the field
					alert(match_fail_notice);	//Alert user
					return false;	//Cancel form submission
				}
			}
		}
	}
	
	//If all fields are validated,required matches made, and CAPTCHA valid, then allow form submission
	return true;
}

