//
// +----------------------------------------------------------------------+
// | Unobtrusive Javascript Validation for YUI v2.0 (2007-03-04)          |
// | http://blog.jc21.com                                                 |
// +----------------------------------------------------------------------+
// | Attaches Events to all forms on a page and checks their form         |
// | elements classes to provide some validation.                         |
// +----------------------------------------------------------------------+
// | Copyright: jc21.com 2008                                             |
// +----------------------------------------------------------------------+
// | Licence: Absolutely free. Don't mention it.                          |
// +----------------------------------------------------------------------+
// | Author: Jamie Curnow <jc@jc21.com>                                   |
// +----------------------------------------------------------------------+
//
//



//==================================================================================================================
//  Trim Whitespace
//------------------------------------------------------------------------------------------------------------------
String.prototype.trim=function(){
	return this.replace(/^\s*|\s*$/g,'');
}
String.prototype.ltrim=function(){
	return this.replace(/^\s*/g,'');
}
String.prototype.rtrim=function(){
	return this.replace(/\s*$/g,'');
}

//==================================================================================================================
//  FIC_checkForm
//  Form Input Checking by JC
/*
		Apply these class names to form elements:

		* required (not blank)
		* validate-number (a valid number)
		* validate-digits (digits only, spaces allowed.)
		* validate-alpha (letters only)
		* validate-alphanum (only letters and numbers)
		* validate-date (a valid date value)
		* validate-email (a valid email address)
		* validate-url (a valid URL)
		* validate-date-au (a date formatted as; dd/mm/yyyy)
		* validate-currency-dollar (a valid dollar value)
		* validate-one-required (At least one checkbox/radio element must be selected in a group)
		* validate-not-first (Selects only, must choose an option other than the first)
		* validate-not-empty (Selects only, must choose an option with a value that is not empty)
		* validate-regex (requires the element to have a nonstandard 'regex=' attribute applied)

		Also, you can specify this non-standard attribute for text, passwird and textarea elements:
		* minlength="x" (where x is the minimum number of characters)
*/
//------------------------------------------------------------------------------------------------------------------
function FIC_checkForm(e) {
	var errs = new Array();

	//this function is called when a form is submitted.
	var theForm = YAHOO.util.Dom.get(e).target;
	if (theForm.nodeName.toLowerCase() != 'form') {
		theForm = YAHOO.util.Dom.getAncestorByTagName(theForm,'form');
	}

	var all_valid = true;

	//access form elements
	//inputs
	var f_in = theForm.getElementsByTagName('input');

	//check inputs
	for (i=0;i<f_in.length;i++) {
		if (f_in[i].type.toLowerCase() != 'submit' && f_in[i].type.toLowerCase() != 'button' && f_in[i].type.toLowerCase() != 'hidden') {
			if (isVisible(f_in[i])) {

				var inv = f_in[i].value.trim();
				var t = f_in[i].type.toLowerCase();
				if (t == 'text' || t == 'password') {
					//text box
					var valid = FIC_checkField(f_in[i]);
				} else if(t == 'radio' || t == 'checkbox'){
					// radio or checkbox
					var valid = FIC_checkRadCbx(f_in[i],f_in);
				} else {
					var valid = true;
				}

				if (valid) {
					YAHOO.util.Dom.removeClass(f_in[i],'validation-failed');
					YAHOO.util.Dom.removeClass(YAHOO.util.Dom.getPreviousSibling(f_in[i]),'validation-failed');
					YAHOO.util.Dom.addClass(f_in[i],'validation-passed');
				} else {
					YAHOO.util.Dom.removeClass(f_in[i],'validation-passed');
					YAHOO.util.Dom.addClass(f_in[i],'validation-failed');
					YAHOO.util.Dom.addClass(YAHOO.util.Dom.getPreviousSibling(f_in[i]),'validation-failed');
					//try to get title
					if (f_in[i].getAttribute('title')){
						errs[errs.length] = f_in[i].getAttribute('title');
					}
					all_valid = false;
				}
			}
		}
	} //end for i

	//textareas
	var f_ta = theForm.getElementsByTagName('textarea');
	//check textareas
	for (i=0;i<f_ta.length;i++) {
		if (isVisible(f_ta[i])) {
			var valid = FIC_checkField(f_ta[i]);

			if (valid) {
				YAHOO.util.Dom.removeClass(f_ta[i],'validation-failed');
				YAHOO.util.Dom.removeClass(YAHOO.util.Dom.getPreviousSibling(f_ta[i]),'validation-failed');
				YAHOO.util.Dom.addClass(f_ta[i],'validation-passed');
			} else {
				YAHOO.util.Dom.removeClass(f_ta[i],'validation-passed');
				YAHOO.util.Dom.addClass(f_ta[i],'validation-failed');
				YAHOO.util.Dom.addClass(YAHOO.util.Dom.getPreviousSibling(f_ta[i]),'validation-failed');
				//try to get title
				if (f_ta[i].getAttribute('title')){
					errs[errs.length] = f_ta[i].getAttribute('title');
				}
				all_valid = false;
			}
		}
	} //end for i

	//selects
	var f_sl = theForm.getElementsByTagName('select');
	//check selects
	for (i=0;i<f_sl.length;i++) {
		if (isVisible(f_sl[i])) {
			var valid = FIC_checkSel(f_sl[i]);
			if (valid) {
				YAHOO.util.Dom.removeClass(f_sl[i],'validation-failed');
				YAHOO.util.Dom.removeClass(YAHOO.util.Dom.getPreviousSibling(f_sl[i]),'validation-failed');
				YAHOO.util.Dom.addClass(f_sl[i],'validation-passed');
			} else {
				YAHOO.util.Dom.removeClass(f_sl[i],'validation-passed');
				YAHOO.util.Dom.addClass(f_sl[i],'validation-failed');
				YAHOO.util.Dom.addClass(YAHOO.util.Dom.getPreviousSibling(f_sl[i]),'validation-failed');
				//try to get title
				if (f_sl[i].getAttribute('title')){
					errs[errs.length] = f_sl[i].getAttribute('title');
				}
				all_valid = false;
			}
		}
	} //end for i

	if (!all_valid) {
		if (errs.length > 0){
			alert("We have found the following error(s):\n\n  * "+errs.join("\n  * ")+"\n\nPlease check the fields and try again");
		} else {
			alert('Some required values are not correct. Please check the items in red.');
		}
		YAHOO.util.Event.stopEvent(e);
	}
	return all_valid;
} // end FIC_checkForm

//==================================================================================================================
//  FIC_checkField
//	e = the element
//------------------------------------------------------------------------------------------------------------------
function FIC_checkField(e) {
	var valid = true;
	var t = e.value.trim();

	//search for required
	if (YAHOO.util.Dom.hasClass(e,'required') && t.length == 0) {
		//required found, and not filled in
		valid = false;
	}

	//check length
	if (YAHOO.util.Dom.hasClass(e,'required')) {
		//check for minlength.
		var m = e.getAttribute('minlength');
		if (m && Math.abs(m) > 0){
			if (e.value.length < Math.abs(m)){
				valid = false;
			}
		}
	}

	//search for validate-
	if (YAHOO.util.Dom.hasClass(e,'validate-number') && isNaN(t) && t.match(/[^\d]/)) {
		//number bad
		valid = false;
	} else if (YAHOO.util.Dom.hasClass(e,'validate-digits') && t.replace(/ /,'').match(/[^\d]/)) {
		//digit bad
		valid = false;
	} else if (YAHOO.util.Dom.hasClass(e,'validate-alpha') && !t.match(/^[a-zA-Z]+$/)) {
		//alpha bad
		valid = false;
	} else if (YAHOO.util.Dom.hasClass(e,'validate-alphanum') && t.match(/\W/)) {
		//alpha bad
		valid = false;
	} else if (YAHOO.util.Dom.hasClass(e,'validate-date')) {
		var d = new Date(t);
		if (isNaN(d)) {
			//date bad
			valid = false;
		}
	} else if (YAHOO.util.Dom.hasClass(e,'validate-email') && !t.match(/\w{1,}[@][\w\-]{1,}([.]([\w\-]{1,})){1,3}$/)) {
		//email bad
		valid = false;
		if (!YAHOO.util.Dom.hasClass(e,'required') && t.length == 0) {
			valid = true;
		}
	} else if (YAHOO.util.Dom.hasClass(e,'validate-url') && !(t.length==0) && !t.match(/^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i)) {
		//url bad
		valid = false;
	} else if (YAHOO.util.Dom.hasClass(e,'validate-date-au') && !t.match(/^(\d{2})\/(\d{2})\/(\d{4})$/)) {
		valid = false;
	} else if (YAHOO.util.Dom.hasClass(e,'validate-currency-dollar') && !t.match(/^\$?\-?([1-9]{1}[0-9]{0,2}(\,[0-9]{3})*(\.[0-9]{0,2})?|[1-9]{1}\d*(\.[0-9]{0,2})?|0(\.[0-9]{0,2})?|(\.[0-9]{1,2})?)$/)) {
		valid = false;
	} else if (YAHOO.util.Dom.hasClass(e,'validate-regex')) {
        var r = RegExp(e.getAttribute('regex'));
        if (r && ! t.match(r)) {
            valid = false;
        }
    }

	return valid;
}

//==================================================================================================================
//  FIC_checkRadCbx
//	element = this element, radio or checkbox
//	fields = input fields dom element
//------------------------------------------------------------------------------------------------------------------
function FIC_checkRadCbx(element,fields){
	var valid = true;

	//search for required
	if (YAHOO.util.Dom.hasClass(element,'validate-one-required')) {
		//required found
		//check if other checkboxes or radios have been selected.
		valid = false;
		for (var i=0;i<fields.length;i++){
			if(fields[i].name.toLowerCase() == element.name.toLowerCase() && fields[i].checked){
				valid = true;
				break;
			}
		}
	}

	return valid;
}

//==================================================================================================================
//  FIC_checkSel
//	e = this select element
//------------------------------------------------------------------------------------------------------------------
function FIC_checkSel(e){
	var valid = true;
	//search for validate-
	if (YAHOO.util.Dom.hasClass(e,'validate-not-first') && e.selectedIndex == 0) {
		//bad
		valid = false;
	} else if (YAHOO.util.Dom.hasClass(e,'validate-not-empty') && e.options[e.selectedIndex].value.length == 0) {
		//bad
		valid = false;
	}
	return valid;
}

//==================================================================================================================
//  attachToForms
//------------------------------------------------------------------------------------------------------------------
function attachToForms(e) {
	//search dom for all forms
	var frms = document.getElementsByTagName('form');
	for(var i=0;i<frms.length;i++) {
		YAHOO.util.Event.addListener(frms[i], "submit", FIC_checkForm);
	}
}

//==================================================================================================================
//  isVisible
//------------------------------------------------------------------------------------------------------------------
function isVisible(e) {
	//returns true if should be visible to user.
	while (e.nodeName.toLowerCase() != 'body' && YAHOO.util.Dom.getStyle(e,'display') != 'none' && YAHOO.util.Dom.getStyle(e,'visibility') != 'hidden') {
		e = e.parentNode;
	}
	if (e.nodeName.toLowerCase() == 'body') {
		return true;
	} else{
		return false;
	}
}


//YAHOO.util.Event.addListener(window, "load", attachToForms);
