/* 
Form Tooltip Viewer and On-the-fly Validator, Scott Lenger, 2007
http://scottlenger.com

Instructions:

Classes determine which function will be used to valide the field, options are: text, email, phone, zip 
Display a tooltip by adding class="hastip" to the form field tag class="thetip" to the tip tag
class="required" will valid on submit
** Ensure your tooltip is in a p tag that is a sibling of the form field: refer to line 62


 Validations by: http://www.askthecssguy.com/2007/03/form_field_hints_with_css_and.html
// Phone Validation modified from: http://www.dynamicajax.com/fr/Validating_Phone_Numbers_With_JavaScript-197_219_231_330.html
// getElementsByClassName by Justin Diaz http://www.dustindiaz.com/getelementsbyclass/
// Radio button and other form validation: http://www.quirksmode.org/js/forms.html

*/


var formid = "validate"; // selects which form to target, used in findinputs and setFormValidation
var hinttag = "p"; // choose which tag will contain the field hints

// Get Class Function ////////////////////////////////////////////////////////////////
// returns the class name of any xhtml tag
function getElementsByClass(node,tag,searchClass) {
	var classElements = new Array();
	if ( node == null )
		node = document;
	if ( tag == null )
		tag = '*';
	var els = node.getElementsByTagName(tag);
	var elsLen = els.length;
	var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
	for (i = 0, j = 0; i < elsLen; i++) {
		if ( pattern.test(els[i].className) ) {
			classElements[j] = els[i];
			j++;
		}
	}
	return classElements;
}


// Validation Functions ////////////////////////////////////////////////////////////////////

// Basic Text (requires more than 4 characters) class="text"
function checkText(usrtxt) {
	var container = usrtxt.parentNode;
	var txt = usrtxt.value;
	if (txt.length > 1) {
		container.className = "valid";
	}
	else {
		container.className = "notvalid";
	}
}

// Email (requires & and . and at least 2 character extension) class="email"
function checkEmail(usrtxt) {
	var container = usrtxt.parentNode;
	var txt = usrtxt.value;
	if (/^.+@[^\.].*\.[a-z]{2,}$/.test(txt)) {
		container.className = "valid";
	} else {
		container.className = "notvalid";
	}
}

// Zip (requires 5 digits) class="zip"
function checkZip(usrtxt) {
	var container = usrtxt.parentNode;
	var num = usrtxt.value.replace(/[^\d]/g,'');
	if (num.length < 5){
		container.className = "notvalid";
	} else if (num.length > 4) {
		usrtxt.value = num.substring(0,5);
		container.className = "valid";
	}
}	

// Phone (requires 10 digits - US only) class="phone"
function checkPhone(usrtxt) {
	var container = usrtxt.parentNode;
	var num = usrtxt.value.replace(/[^\d]/g,'');
	if (num.length < 3) {
		container.className = "notvalid";
	} else if (num.length < 6) {
		usrtxt.value = num.substring(0,3) + "-" + num.substring(3,6);
		container.className = "notvalid";
	} else if (num.length < 8) {
		usrtxt.value = num.substring(0,3) + "-" + num.substring(3, 6) + "-" + num.substring(6);
		container.className = "notvalid";
	} else if (num.length > 9) {
		usrtxt.value = num.substring(0,3) + "-" + num.substring(3, 6) + "-" + num.substring(6, 10);
		container.className = "valid";
	} else if (num.length > 8) {
		usrtxt.value = num.substring(0,3) + "-" + num.substring(3, 6) + "-" + num.substring(6, 10);
		container.className = "notvalid";
	}		
}

// checkCheckbox (determines if box is checked) class="checkbox"
function checkCheckbox(usrtxt) {
	var container = usrtxt.parentNode;
	var checkbox = usrtxt.checked;
	if (checkbox != true) {
		container.className = "notvalid";
	} else {
		container.className = "valid";
	}
}
	
// checkRadio
// checkSelect


// SUBMIT FORM AND VALIDATE /////////////////////////////////////////////////////////////////
// validates all required fields again before sending
function formValidate() {
	// get all fields with class="required"
	var reqfields = getElementsByClass(document, "*", "required");
	var errors = "";

	for (var i=0; i<reqfields.length; i++) {
		// get class and send to appropriate validating function
		var testclass = reqfields[i].className.split(" ");

		for(j in testclass) {
			if (testclass[j] == 'text') { // if class="text"
				checkText(reqfields[i]);
			} else if (testclass[j] == 'email') { // if class="email"
				checkEmail(reqfields[i]);
			} else if (testclass[j] == 'phone') { // if class="phone"
				checkPhone(reqfields[i]);
			} else if (testclass[j] == 'zip') { // if class="phone"
				checkZip(reqfields[i]);
			} else if (testclass[j] == 'checkbox') { // if class="checkbox"
				checkCheckbox(reqfields[i]);
			}
		} // end test for class
		if (reqfields[i].parentNode.className == 'notvalid') { // read parent class to determine if field is valid
			errors += reqfields[i].parentNode.getElementsByTagName("label")[0].childNodes[0].nodeValue + "\n";
		}
	}

	if (errors == "") { // if no errors, prepare form for processing
		// getNameValues(); // return false;
	} else { // if errors
		errors = "Please correct the following form errors:\n" + errors; // list errors
		alert(errors); return false;
	}
}

/*
// COLLECT INPUT NAME/VALUES /////////////////////////////////////////////////////////////////
// gather input/textarea names and values and create string to send to $_POST
// makes the form more ajax friendly
var params = ""; // gets string of names/inputfields from field inputs

function getNameValues() {
	inputfields = document.getElementById(formid).getElementsByTagName("input"); 
	textareafields = document.getElementById(formid).getElementsByTagName("textarea");
	var amp = "";
		for (i=0; i<inputfields.length; i++) {
			if (i>2) {amp = "&";}
			if (inputfields[i].type == "text" || inputfields[i].type == "submit" || inputfields[i].type == "hidden") {
				params += amp + inputfields[i].name + "=" + encodeURI(inputfields[i].value);
			} else if (inputfields[i].type == "radio" || inputfields[i].type =="checkbox") { 
				if (inputfields[i].checked == true) {// we need to determine which input is checked before we get the name/value for these
					params += amp + inputfields[i].name + "=" + encodeURI(inputfields[i].value);
				}
			} else {
				alert(inputfields[i].type + "input type is not supported"); // for troubleshooting since not all input types are yet supported
			}
		}
		if (textareafields.length>2) {amp = "&";}
		for (j=0; j<textareafields.length; j++) {
			if (j>2) {amp = "&";}
			params += amp + textareafields[j].name + "=" + encodeURI(textareafields[j].value);
		}
	alert(params);
}
*/

// SET HINTS ////////////////////////////////////////////////////////////////////////////////////
// finds all tags with class "hints" and sets display:none
function clearFormHints() {
	var formhints = getElementsByClass(document, "*", "hint");
	for (var i=0; i<formhints.length; i++) {
		formhints[i].style.display = "none";
	}
}

// Add function to input field to display hint test in sibling tag with class="hashint"
function setFormHints() {
	var fields = getElementsByClass(document, "*", "hashint");
	for (var i=0; i<fields.length; i++) {
		fields[i].onfocus = function () {
			clearFormHints(); // clear all hints
    		this.parentNode.getElementsByTagName(hinttag)[0].style.display = "inline"; // set current hint
		}
	}  
}


// Add functions to XHTML Tags /////////////////////////////////////////////////////////////////////////
// keeping things unobtrusive
function setFormValidation() {
	// set form submit
	var getform = document.getElementById(formid);
	getform.onsubmit = function() {return formValidate();}
	// add text validate function text inputs
	var textinput = getElementsByClass(document, "*", "text");
	for (var i=0; i<textinput.length; i++) {
		textinput[i].onkeyup = function() {checkText(this);}
		textinput[i].onblur = function() {checkText(this);}
	}
	// add email validate function to email inputs
	var emailinput = getElementsByClass(document, "input", "email");
	for (var i=0; i<emailinput.length; i++) {
		emailinput[i].onkeyup = function() {checkEmail(this);}
		emailinput[i].onblur = function() {checkEmail(this);}
	}
	// add phone validate function to phone inputs
	var phoneinput = getElementsByClass(document, "input", "phone");
	for (var  i=0; i<phoneinput.length; i++) {
		phoneinput[i].onkeyup = function() {checkPhone(this);}
		phoneinput[i].onblur = function() {checkPhone(this);}
	}
	// add zip validate function to zip inputs
	var zipinput = getElementsByClass(document, "input", "zip");
	for (var i=0; i<zipinput.length; i++) {
		zipinput[i].onkeyup = function() {checkZip(this);}
		zipinput[i].onblur = function() {checkZip(this);}
	}
	var checkboxinput = getElementsByClass(document, "input", "checkbox");
	for (var i=0; i<checkboxinput.length; i++) {
		checkboxinput[i].onchange = function() {checkCheckbox(this);}
	}
	clearFormHints();
}