/**********************************************************
Author:
Adam Barry
Klestrup partners
www.klestrup-partners.dk

Date: December 8 2008

© 2008 Adam Barry, all rights reserved
-----------------------------------------------------------

Name:
formValidation script (Microsoft .NET compatible)

-----------------------------------------------------------
Description:
Function that enable runs validation on userinputs on
various forms conforming to Microsoft.Net built pages.

-----------------------------------------------------------
Usage:
Simply place a link to the this script in the head-section
of the XHTML page. The script will then automatically
execute on page load.

<script type="text/javascript" src="formValidation.Net.js"></script>

<form method="get" action="">


	<div class="form">
		<fieldset>
			<legend>Form framework</legend>
			<ul>
				<li><label for="name">Name</label><input name="name" id="name" class="text required" type="text" /></li>
				<li><label for="address">Address</label><input name="address" id="address" class="text" type="text" /></li>
				<li><label for="email">E-mail</label><input name="email" id="email" class="text email" type="text" /></li>
				<li><label for="number">Number</label><input name="number" id="number" class="text number required" type="text" /></li>
			</ul>
			<button type="button" class="submit"><span><span><span>Submit</span></span></span></button>
			<button type="reset"><span><span><span>Reset</span></span></span></button>
		</fieldset>
	</div>

	<div class="form">
		<fieldset>
			<legend>Form framework</legend>
			<ul>
				<li><label for="name">Name</label><input name="name" id="name" class="text required" type="text" /></li>
				<li><label for="address">Address</label><input name="address" id="address" class="text" type="text" /></li>
				<li><label for="email">E-mail</label><input name="email" id="email" class="text email" type="text" /></li>
			</ul>
			<button type="button" class="submit"><span><span><span>Submit</span></span></span></button>
			<button type="reset"><span><span><span>Reset</span></span></span></button>
		</fieldset>
	</div>


</form>

Please note that the class attribute "required" and "email"
determins whether the specific form element is required.

-----------------------------------------------------------
Dependencies:
This script depends on the windowOnLoad-script to execute

-----------------------------------------------------------
Revision history:

2009-05-15: Submit-on-enter functionality added

2009-05-18: Script refactored with emphasis on submit-on-
enter functionality

2009-06-27: Added additional check to test whether buttons onchange property has already been set
This allows script to be run multiple times on page

**********************************************************/

function initSubmitButtons () {
	if (!document.getElementsByTagName) return false;

	var buttons = document.getElementsByTagName("button");
	for (var i = 0; i < buttons.length; i++) {
		if (buttons[i].className.indexOf("submit") > -1) {

			var button = buttons[i];

			if (button.onclick != null && button.onchange == null) {

				// store the onclick command in onchange attribute
				button.onchange = button.onclick;

				button.onclick = function() {

					var me = this;

					if (findDivForm(me) == true) {
						me.onchange();
					}

					else {
						return false;
					}
				}

			}
		}
	}
}addLoadEvent(function(){initSubmitButtons();});


function initInputs () {

	/* Overcome stupid Firefox-error */
	var browser = navigator.userAgent;

	if (browser.indexOf('Firefox') > -1) {

		if (!document.getElementsByTagName) return false;

		var elements = document.getElementsByTagName("input");
		for (var i = 0; i < elements.length; i++) {
			elements[i].setAttribute("autocomplete","off");
		}
	}
}addLoadEvent(function(){initInputs();});


function findDivForm (button) {

	var formDivClassName = "form";
	var formDiv = button.parentNode;

	/* Loop throug the parentNodes of the clícked button until a div.form is found */
	while (formDiv.className.indexOf("form") == -1) {
		formDiv = formDiv.parentNode;
	}

	/* Validate the field elements in div.form */
	return validateForm(formDiv);
}


function submitButtonExecute (vThisform) {
	if (!vThisform) {return false;}

	buttons = vThisform.getElementsByTagName('button');
	if (!buttons) {return false;}

	for (var i = 0; i < buttons.length; i++) {
		if (buttons[i].className.indexOf('submit') > -1 && 	buttons[i].onchange != null) {
			buttons[i].onchange();
		}
	}
}


function submitPseudoForm(vThisform) {
	submitButtonExecute(vThisform);
	return false;
}


function validateCustomForm (button) {

    var formDivClassName = "form";
	var formDiv = button.parentNode;

	//Loop throug the parentNodes of the clícked button until a div.form is found
	while (formDiv.className.indexOf("form") == -1) {
		formDiv = formDiv.parentNode;
	}

	// Validate the field elements in div.form
	submitPseudoForm(formDiv);
}


/**********************************************************
Validators
**********************************************************/

function validate_required(field) {

	with (field) {

		if (type == "checkbox") {
			if (checked == "") {
				field.className+=" error";
				field.focus();
				return false;
			}
		}

		if (value==null || value.length <= 0 || value==" ") {
			field.className+=" error";
			field.focus();
			return false;
		}

		else {
			field.className = field.className.replace(new RegExp("error\\b"), "");
			return true;
		}
	}
}


function validate_email(field) {

	with (field) {

		if (field.value.indexOf(".") > 2 && field.value.indexOf("@") > 0) {
			field.className = field.className.replace(new RegExp("error\\b"), "");
			return true;
		}
		else {
			field.className+=" error";
			field.focus();
			return false;
		}
	}
}


function validate_number(field) {

	with (field) {

		if (field.value.match(/^\d+$/)) {
			field.className = field.className.replace(new RegExp("error\\b"), "");
			return true;
		}
		else {
			field.className+=" error";
			field.focus();
			return false;
		}
	}
}


function validate_select(element) {

    if (element.selectedIndex == 0) {
        element.focus();
        element.className += " error";
        return false;
    }
}


function validate_textarea(field) {

	if (field.value.length <= 0) {
		field.focus();
		field.className += " error";
		return false;
	}
}


/**********************************************************
Form validation
**********************************************************/

function validateForm(vThisform) {

	if (!vThisform) {return false;}

	var thisform = vThisform.getElementsByTagName("*");

	 /*	Loop through all form elements of 'thisform' and determine
		which of them have 'required' or 'email' classes and are not children of a
		noValidation fieldset */

	for (var i = 0; i < thisform.length; i++) {
		var me = thisform[i];

		/* Loop through the form's required fields */
		if (me.className.indexOf('required') > -1 && me.parentNode.parentNode.parentNode.className.indexOf('noValidation') == -1) {

			if (me.tagName.toLowerCase() == "input" || me.tagName.toLowerCase == "password") {

				if (validate_required(me) == false) {
					return false;
				}
			}

			if (me.tagName.toLowerCase() == "select") {

				if (validate_select(me) == false) {
					return false;
				}
			}

			if (me.tagName.toLowerCase() == "textarea") {

				if (validate_textarea(me) == false) {
					return false
				}
			}
		}

		/* Loop through the form's fields that have been filled out, although they are not required */
		if (me.className.indexOf('email') > -1 && me.value.length > 0) {

			if (validate_email(me) == false) {
				return false;
			}
		}

		if (me.className.indexOf('number') > -1 && me.value.length > 0) {

			if (validate_number(me) == false) {
				return false;
			}
		}
	}

	return true; //Form is valid
}



/**********************************************************
No validation pseudo-forms
**********************************************************/

function noValidationCheckboxes () {
	if (!document.getElementsByTagName) return false;

	var inputs = document.getElementsByTagName('input');

	for (var i = 0; i < inputs.length; i++) {

		if (inputs[i].className.indexOf('noValidation') > -1) {
			var me = inputs[i];

			me.onclick = function () {

				// if the page is reloaded and the checkbox is unchecked
				if (me.checked == true && me.parentNode.className.indexOf('noValidation') > -1) {
					me.parentNode.className = me.parentNode.className.replace(new RegExp("noValidation\\b"), "");
				}

				if (me.checked == false) {
					me.parentNode.className = me.parentNode.className.replace(new RegExp("noValidation\\b"), "");
				}
				else {
					me.parentNode.className += " noValidation";
				}
			}
		}
	}

}addLoadEvent(function(){noValidationCheckboxes();});


/**********************************************************
Eventhandlers
**********************************************************/

function checkFormsOnEnter() {
	if (!document.getElementsByTagName) return false;

	var forms = new Array();
	var elements = document.getElementsByTagName("div");

	for (var i = 0; i < elements.length; i++) {
		if (elements[i].className.indexOf("form") > -1) {
			forms.push(elements[i]);
		}
	}

	for (var i = 0; i < forms.length; i++) {
		forms[i].onkeydown = function(event) {

			var evt = event || window.event;

			if (evt) {
				var target = evt.target || evt.srcElement;

				switch (evt.keyCode) {
					case 13:	//Enter/return key
						if (target.tagName.toLowerCase() == "textarea") {
							return true;
						}

						else {
							if (validateForm(this) == true) {
								submitPseudoForm(this);
							}
							return false;
							break;
						}
				}
			}
		}
	}
}addLoadEvent(function(){checkFormsOnEnter();});
