// Form Validator Javascript
// v 1.0
// Author: Tim Harper
// http://www.lunawebs.com/
//
// Usage:
// 1.  Include this javascript file in your web page
// 2.  Add a reference to the form tag so it knows where to display the errors
// <div id="errors"></div>
// <form id="myform" errorcontainer="errors">
// 3.  Add your validate statements.  You can use regular expressions, or javascript expressions.  
//     For javascript expressions, the variables value, form, and element are available for usage.
// input attributes
//   validate - the validation expression, validate="/^[0-9]+$/", validate="value == 0", validate=" value > form['otherelement'].value"
//   errortext - errortext="please enter your name."
var FormValidator = Class.create();

FormValidator.prototype = 
{
	initialize: function(formElement)
	{
		this.form=formElement;

		if (this.form.validator !=null) return;
		this.form.validator=this;
		
		this.errorContainer= $(formElement.getAttribute("errorcontainer"));
		if (this.errorContainer!=null)
			this.errorContainer.style.display="none";

		this.form.onsubmit_previous=this.form.onsubmit;
		this.form.onsubmit=this.onsubmit.bindAsEventListener(this);
		
		if (this.form.getAttribute("scrollto")==null)
			this.scrollto=0;
		else
			this.scrollto=this.form.getAttribute("scrollto");

		if (this.form.getAttribute("errorclass")==null)
			this.errorclass=null;
		else
			this.errorclass=this.form.getAttribute("errorclass");
		// store previous classes
		$A(this.form.elements).each( function(element) { 
			element.previousClass=element.className;
		});
		
	},
	
	onsubmit: function(event)
	{
		// Try and validate it
		if (!this.validate()) return false;
		// Did it do ok?  Now execute whatever was in the onsubmit event before, if there was something.
		if (this.form.onsubmit_previous!=null)
			return this.form.onsubmit_previous(event);

		return true;
	},
	validate: function()
	{
		this.clearErrors();
		valid=true;
		thisthis=this;
		$A(this.form.elements).each( function(element) { 
			if (!thisthis.validateElement(element))
			{
				thisthis.markError(element);
				valid=false;
			}
		});
		
		if (!valid)
		{
			window.scrollTo(0,this.scrollto);
		}
		this.showErrors();
		return valid;
	},
	showErrors: function()
	{
		if (this.errorContainer==null)
		{
			alert("Form has errors");
			return;
		}
				
		if (this.errorFields.length==0)
		{
			this.errorContainer.style.display="none";
			return;
		}
		
		this.errorContainer.innerHTML=this.getErrorHTML();
		this.errorContainer.style.display="block";
	},
	getErrorHTML: function()
	{
		html="<ul>";
		this.errorFields.each(function(element) {
			html+="<li>" + element.getAttribute("errortext") + "</li>";
		});
		html+="</ul>";
		return html;
	},
	clearErrors: function(element)
	{
		this.errorFields=[];
		$A(this.form.elements).each( function(element) { 
			element.className=element.previousClass;
		});

	},
	markError: function(element)
	{
		this.errorFields.push(element);
		if (element.getAttribute("errortext")==null)
			element.setAttribute("errortext", "Please provide a value for " + element.name);
		
		if (this.errorclass!=null) element.className=this.errorclass;
		
	},
	validateElement: function(element)
	{
		// get the value
		validate=element.getAttribute("validate");
		form=this.form;
		if (validate==null) return true;
		
		value=Form.Element.getValue(element);

		if (validate.substr(0,1)=="/") // regular expression ?
		{
			// parse the /'s out and the flags
			result=/^\/(.*)\/([a-z]*)$/.exec(validate);
			try
			{
				regExp = new RegExp(result[1], result[2] );
			}
			catch(ex)
			{
				alert('invalid regular expression ' + validate + ' on ' + element.name);
				return false;
			}
			if (regExp.exec(value)==null) // does it not match?
				return false;
			return true;
		}
		else
			return eval(validate);
	}
}

formValidator=null;
Event.observe(window, "load", function() {
	$A(document.getElementsByTagName("form")).each( function (formObject) {
		formValidator=new FormValidator(formObject);
	});
}, false);
