/*

title: JS form validator
author: matthewclarke@gmail.com
date: September, 2005

// Code is free to use and distribute. //

New validators and custom error messages are added/edited in FormFields object:
- this.required = /[a-zA-Z0-9]/;
- this._required = "is a required field";
the name of the field will be included dynamically

custom colors are also set in the FormFields object:
- this.fieldErrrorColor = "ede";
- this.fieldDefaultColor = "fff";


Validators are added to form fields via "validator" tag:
- <input type="text" name="company" validator="required" />

Form is validated this way:
<form name="xxxxx" method="xxxxx" action="xxxxxxx" onSubmit="return new FormChecker(this).validate();">

JS should be linked to page:
<script type="text/javascript" src="xxxxx/xxxx/form_validator.js"></script>

*/

// ITERATORS
function ArrayIterator (a) {
	this.count = 0;
	this.a = a;
	this.lgt = this.a.length;
}
var oo = ArrayIterator.prototype;
oo.next = function () {
	var x = (this.count < this.lgt) ? true : false;
	this.count++;
	return x;
}
oo.current = function () {
	return this.a[this.count-1];
}
delete oo;

// FORM FIELDS

function FormFields() {
 	//
	this.fieldErrrorColor = "CCC";
	this.fieldDefaultColor = "FFF";
	//
	this.required = /[a-zA-Z0-9]/;
	this._required = "is a required field";
	this.zip = /\d{5}(-\d{4})?/; //97209
	this._zip = "must have at least 5 numerals";
	this.currency = /\$\d{1,3}(,\d{3})*\.\d{2}/; // $34.00 $23,000
	this._currency = "must start with a $";
	this.time = /^([1-9]|1[0-2]):[0-5]\d$/; //12:01
	this._time = "must be a valid time";
	this.email = /^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,3}|[0-9]{1,3})(\]?)$/;
	this._email = "does not appear to be valid";
	this.phone = /^\(?\d{3}\)?\s|-\d{3}-\d{4}$/; //###-###-####
	this._phone = "phone number should be in ###-###-#### format";
	this.phoneNumberInternational = /^\d(\d|-){7,20}/;
	this.date = /^\d{1,2}(\-|\/|\.)\d{1,2}\1\d{4}$/; //xx/xx/xxxx
	this.state = /^(AK|AL|AR|AZ|CA|CO|CT|DC|DE|FL|GA|HI|IA|ID|IL|IN|KS|KY|LA|MA|MD|ME|MI|MN|MO|MS|MT|NB|NC|ND|NH|NJ|NM|NV|NY|OH|OK|OR|PA|RI|SC|SD|TN|TX|UT|VA|VT|WA|WI|WV|WY)$/i;
	this._state = "does not appear to be a state";
	//
}

// FORM CHECKER

function FormChecker (f) {
	this.form = f;
	this.msg = '';
	this.errorCount = 0;
}
var oo = FormChecker.prototype;
oo.validate = function() {
	var FF = new FormFields();
	var A = new ArrayIterator(this.form.elements);
	var o_cache = false;
	while (A.next()) {
		var o = A.current();		
		var x = FF[o.validator];
		if (x != undefined) {
			var match = x.exec(o.value);
			if (!match) {
				this.errorCount++;
				if (!o_cache) o_cache = o;
				o.style.background = FF.fieldErrrorColor;
				this.msg += '- '+o.name+' '+FF['_'+o.validator]+' \n';
			} else {
				o.style.background = FF.fieldDefaultColor;
			}

		}
	}
	return this.finalCheck(o_cache);
}
oo.finalCheck = function(o) {
	if (o) {
		o.focus();
		o.select();
		var s = (this.errorCount > 1) ? 's' : '';
		alert(this.errorCount+' error'+s+' found:\n\n'+this.msg);
		return false;
	} else {
		return true;
	}
}
delete oo;
