/*
Form Validator
Author: Peter Tornstrand <peter[at]tornstrand[dot]com>
Homepage: http://www.tornstrand.com/scripts/javascript-form-validation/
Date: 2006-04-04
Version: 1.2
*/

/*
Set to false if you don't want the error messages
*/
var err = true;

/*
Set to true if you want modal javascript dialogues instead of DOM messages
*/
var modal = false;

/*
Browser detect, need's a little work
*/
var ie;
if (navigator.appVersion.indexOf("MSIE")!=-1) {
	ie = true; 
} else {
	ie = false;
}

/**
* Loops through the page forms and add's onSubmit events.
**/
var addOnSubmitEvent = function() {
	var frms = document.getElementsByTagName('form');
	for (var i=0; i<frms.length; i++) {
		frms[0].onsubmit = function() {
			return validate(this);
		}
	}
}

/**
* Function for displaying error message to user.
* @param frm [Object HTMLFormElement] The form
* @param el [Object HTMLInputElement] Source of the error message
**/
var displayErrorMessage = function(frm, el) {
	
	var labels = document.getElementsByTagName('label');
	var errorMsg = '';
	
	if (el.type=='radio'||el.type=='checkbox') {
		for (var i = 0; i<labels.length; i++) {
			if (labels[i].htmlFor==el.name) {
				errorMsg = 'You must select a value for ' + labels[i].innerHTML.replace('*','');
			}
		}
	} else {
		for (var i = 0; i<labels.length; i++) {
			if (labels[i].htmlFor==el.id) {
				errorMsg = 'You must enter a value for ' + labels[i].innerHTML.replace('*','');
			}
		}
	}
	
	if (err) {
		if (modal) {
			alert(errorMsg);
			el.focus();
		}
		else {
			if (document.getElementById('errorMessage')) {
				frm.removeChild(document.getElementById('errorMessage'));
			}
			var errorDiv = document.createElement('div');
			errorDiv.id = 'errorMessage';
			errorDiv.innerHTML = errorMsg;
			frm.insertBefore(errorDiv, frm.childNodes[0]);
			el.focus();
		}
	}
}

/**
* Function called to validate form elements.
* @param frm [Object HTMLFormElement] The form to validate
* @return [Boolean] Did the form validate or not
**/
var validate = function(frm) {
	var el = frm.elements;
	for (var i=0; i<el.length; i++) {
    	if (el[i].className.indexOf('req') != -1) {
			
			// Text, Textarea, File
			if (el[i].type=='text'||el[i].type=='textarea'||el[i].type=='file') {
				if (el[i].value=="") {
					el[i].className = el[i].className + ' error';
 					err == true ? displayErrorMessage(frm, el[i]) : null;
					return false;
 				} else {
					el[i].className = el[i].className.replace('error','');
				}

			}

			// Radio
			else if (el[i].type=='radio') {
				var radiogroup = el[el[i].name];
		        var itemchecked = false;
		        for(var j = 0 ; j < radiogroup.length ; ++j) {
					if(radiogroup[j].checked) {
						itemchecked = true;
						break;
					}
		        }
		        if(!itemchecked) { 
					el[i].className = el[i].className + ' error';
 					err == true ? displayErrorMessage(frm, el[i]) : null;
					return false;
		        }
			}
			
			// Checkbox
			else if (el[i].type=='checkbox') {
				var itemchecked = false;
		        var elems = document.getElementsByTagName("input");
		        for(var j=0; j<elems.length; j++) {
					if(elems[j].type=='checkbox'&&elems[j].name==el[i].name) {
		        		if(elems[j].checked) {
		        			itemchecked = true;
		        			break;
		        		}
		        	}
		        }
		        if(!itemchecked) { 
					el[i].className = el[i].className + ' error';
 					err == true ? displayErrorMessage(frm, el[i]) : null;
					return false;
				}
			}
			
			// Select-one
			else if (el[i].type=='select-one') {
				if (el[i].selectedIndex==0) {
					el[i].className = el[i].className + ' error';
 					err == true ? displayErrorMessage(frm, el[i]) : null;
					return false;
		        } else {
		        	el[i].className = el[i].className.replace('error','');
		        }
			}
			
			// Select-multiple
			else if (el[i].type=='select-multiple') {
				var optionselected = false;
		      	for(var j=0;j<el[i].options.length; ++j) {
		      		if (el[i].options[j].selected) {
		      			optionselected = true;
		      			break;
		      		}
		      	}
		      	if (!optionselected) {
					el[i].className = el[i].className + ' error';
 					err == true ? displayErrorMessage(frm, el[i]) : null;
					return false;
		        } else {
		        	el[i].className = el[i].className.replace('error','');
		        }
			}
		}
	}
	return true;
}


/**
* Function called when a element changes it's value.
**/
var evaluate = function() {
	for (i=0; i<conds.length; i++) {
		var element = document.getElementsByName(conds[i][0]);
		var elemVal = conds[i][1];
		var elements = document.getElementsByName(conds[i][2]);
		var bol = conds[i][3];
		
		for (var k=0; k<element.length; k++) {
			if (element[k].name==this.name) {
				if (this.type=='select-one') {
					if(this[this.selectedIndex].value==elemVal) {
						setState(elements, bol);
					} else {
						setState(elements, !bol);
					}
				} else if (this.type=='select-multiple') {
					var optionselected = false;
					for(var j=0; j<this.options.length; j++) {
		      			if (this.options[j].value==elemVal&&this.options[j].selected) {
		      				optionselected = true;
		      				break;
		      			}
		      		}
					if (optionselected) {
						setState(elements, bol);
					} else {
						setState(elements, !bol);
					}
				} else {
					if(this.value==elemVal) {
						setState(elements, bol);
					} else {
						setState(elements, !bol);
					}
				}
			}
		}
	}
}

/**
* Set a single or a group of elements to required or not required.
* @param elements [Object HTMLCollection] The elements to set required states on
* @param bol [Boolean] Set elements required or not required
**/
var setState = function(elements, bol) {
	if (bol) {
		for (var j=0; j<elements.length; j++) {
			if (elements[j].className.indexOf('req')==-1) {
				elements[j].className += ' req';
			}
		}
	} else {
		for (var j=0; j<elements.length; j++) {
			newClassName = elements[j].className.replace('req','');
			elements[j].className = newClassName;
		}
	}
}

/**
* Attach conditions to form elements.
**/
var attachConditions = function() {
	attachBlurs(document.getElementsByTagName('input'));
	attachBlurs(document.getElementsByTagName('select'));
}

/**
* Attach onBlur or onClick to elements depending on element type.
* @param elements [Object HTLMCollection] The elements to attach onBlur events to
**/
var attachBlurs = function(elements) {
	for (var i=0; i<elements.length; i++) {
		if (elements[i].type=='checkbox'||elements[i].type=='radio') {
			if (ie) {
				elements[i].attachEvent('onclick', evaluate, false);
			} else {
				elements[i].addEventListener('click', evaluate, false);
			}
		} else {
			if (ie) {
				elements[i].attachEvent('onblur', evaluate, false);
			} else {
				elements[i].addEventListener('blur', evaluate, false);
			}
		}
	}
}

/*
Conditions
Syntax: conds.push(Array('element name','element value','element name', false));
You should put your conditions in a seperate file and include in the page.
*/
var conds = Array();

/*
Add onLoad events to start the whole thing
*/
if (ie) {
	window.attachEvent("onload", addOnSubmitEvent, false);
	window.attachEvent("onload", attachConditions, false);
} else {
	window.addEventListener("load", addOnSubmitEvent, false);
	window.addEventListener("load", attachConditions, false);
}
