// ========================================================================

// ACCESSIBLE VALIDATION FORM SCRIPT: 

// (c)2004 Sergi Meseguer http://zigotica.com/, 07/2004 

// under CC license http://creativecommons.org/licenses/by-sa/2.0/

// mod. 2006: checkbox + radio, format (phone, url, range)

/* ========================================================================

   HOW TO USE THE SCRIPT:

   1. Use labels, either in its implicit or explicit forms:

     <label for="user">User</label>

     <input id="user" name="user" type="text" />

     or 

     <label>User<input id="user" name="user" type="text" /></label>



   2. Add a class="required" and a description in a title attibute 

      to each label you want to check:

      <label for="user" class="required" title="User">User</label>

  

   3. Describe data format in the alt attibute of the form element:

      Options are: text, phone, url, email, range and rangenum. Examples:

      <input id="user" name="user" type="text" alt="text" />

      <input id="r" name="r" type="text" alt="rangenum|-10|35" />

      <input id="r" name="r" type="text" alt="range|alpha|gamma" />



   4. Add the script in the html:

      <script type="text/javascript" src="validform.js"></script>

        

   5. Add the style in the html (optional):

      <link href="form.css" rel="stylesheet" type="text/css" />

        

   ======================================================================*/

VALID = {

	tieFormEvents : function() {

		// customize your own messages:

		// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

		VALID.compulsory = "DEBE RELLENAR LOS SIGUIENTES CAMPOS:";

		VALID.goodemail = "el correo electrónico debe tener el formato nombre@dominio.ext";

		VALID.goodphone = "el teléfono solamente permite números";

		VALID.goodurl = "la URL debe empezar por http://";

		VALID.goodrange = "se requiere un rango (";

		VALID.numrange = "el valor debe ser numérico";

		// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!



		// attaching events to form fields:

		var areas = document.getElementsByTagName('textarea');

		for (var a = 0; (area = areas[a]); a++) {

			EXTRAS.addEvent(area, 'change', VALID.changing, false);

		}

		var inputs = document.getElementsByTagName('input');

		for (var a = 0; (input = inputs[a]); a++) {

				// fix for safari/opera when input is checkbox or radio:

				if((input.getAttribute("type") == "radio" || input.getAttribute("type") == "checkbox") && document.addEventListener && !document.addBinding)

				EXTRAS.addEvent(input, 'mouseout', VALID.changing, false);			

				else EXTRAS.addEvent(input, 'change', VALID.changing, false);

		}

		var forms = document.getElementsByTagName('form');

		for (var a = 0; (form = forms[a]); a++) {

			form.onsubmit = VALID.checkForm;

		}

	},



	checkForm : function(e) {

		// hacking IE events:

		var e = (e) ? e : window.event ;

		var target = (e.target) ? e.target : e.srcElement ; 



		var radiocheck = 0;

		var remaining = [];

		var str = "";

		var r = 0;

		

		var requireds = EXTRAS.getElementsByClass('required problem',1);

		for (var i = 0; i < requireds.length; i++) {

			valor = requireds[i].title;

			valor = valor.replace(/: \(\*\)/i, ""); 

			remaining.push("\r\n"+valor)

		}

		var requireds = EXTRAS.getElementsByClass('required',1);

		for (var i = 0; i < requireds.length; i++) {

			valor = requireds[i].title;

			valor = valor.replace(/: \(\*\)/i, ""); 

			remaining.push("\r\n"+valor)

		}



		if(remaining.length > 0) {

			while(r < remaining.length) {str +=''+remaining[r];r++}

			alert(VALID.compulsory + str);

			return false; // stop submission!

		}

		else {

			return true; // do submit

		}

	},



	checkfield : function(target) {

		var label;

		var labels = document.getElementsByTagName('label');



		for (var i = 0; i < labels.length; i++) {

			if (labels[i].htmlFor == target.name) {

				label =  labels[i];

			}

		}

		

		//step 1: checking presence

		// if radio or checkboxes are required within a label, any of its input fields must be checked

		var ok = 0;

		if(target.type=="radio" || target.type=="checkbox") {

			var radiochecks = document.getElementsByTagName('input'); 

			for (var r=0; r < radiochecks.length; r++) {

				if(radiochecks[r].checked && radiochecks[r].name == label.htmlFor) {

					ok = 1; 

					break;

				}

			}

		}

		else if(target.type!="radio" && target.type!="checkbox"){

			if (target.value.length != 0) ok = 1;

		}

		if (ok == 0 && label.className.indexOf("required") != -1) {

			label.className = 'required problem';

		} 

		else if (ok == 1 && label.className.indexOf("required") != -1) {

			label.className = 'required completed';

		}

		else if (ok == 1 && label.className.indexOf("required") == -1) {

			label.className = 'completed';

		}

		else if (ok == 0 && label.className.indexOf("required") == -1) {

			label.className = '';

		}			



		//step 2: checking data format

    		// Regular Expression matching http://

    		var urlRegExp = /http:\/\//i;

    		if(target.alt == "url" && target.value.length != 0 && !urlRegExp.test(target.value)) {

			target.value = "http://"+target.value;

	    	}

    		

    		// Regular Expression matching phone number

    		if(target.alt == "phone"){

	    		var phoneRegExp = /[0-9.]/i;

		    	if(target.value.length != 0 && phoneRegExp.test(target.value)) {

				target.value = target.value.replace(/[a-zA-Z_-]/gi,"");

				if (label.className.indexOf("required") != -1) {

					label.className = 'required completed';

				} 

				else {

					label.className = 'completed';

				}

		    	}

		    	else if(target.value.length != 0 && !phoneRegExp.test(target.value)) {

				if (label.className.indexOf("required") != -1) {

					label.className = 'required problem';

				} 

		    		else {

		    			label.className = 'problem';

		    		}

		    		alert(VALID.goodphone);

		    	}

	    	}

	    	

    		// Regular Expression matching email from

		// http://regexlib.com/UserPatterns.aspx?authorId=1758

	    	if(target.alt == "email") {

	    		var emailRegExp = /^([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$/i;

		    	if(target.value.length != 0 && emailRegExp.test(target.value)) {

				if (label.className.indexOf("required") != -1) {

					label.className = 'required completed';

				} 

				else {

					label.className = 'completed';

				}

		    	}

		    	else if(target.value.length != 0 && !emailRegExp.test(target.value)) {

				if (label.className.indexOf("required") != -1) {

					label.className = 'required problem';

				} 

		    		else {

		    			label.className = 'problem';

		    		}

		    		alert(VALID.goodemail);

		    	}

		}



	    	// checking for a value in a range:

	    	if(target.alt.indexOf("range") != -1) {

		    	var R = target.alt.split("|");

		    	var m = R[1];

		    	var M = R[2];

		    	var value = target.value;

		    	if(target.alt.indexOf("rangenum") != -1) {

		    		m = parseInt(R[1]); 

		    		M = parseInt(R[2]); 

		    		value = parseInt(value);

		    	}

		    	window.status = VALID.goodrange + m + ">= n <= " + M + ")"; //hack

		    	if(target.value.length != 0 && value >= m && value <= M) {

				if (label.className.indexOf("required") != -1) {

					label.className = 'required completed';

				} 

				else {

					label.className = 'completed';

				}

				window.status = ""; //end hack

		    	}

		    	else if(target.value.length != 0 && (value < m || value > M)) {

				if (label.className.indexOf("required") != -1) {

					label.className = 'required problem';

				} 

		    		else {

		    			label.className = 'problem';

		    		}

		    		alert(VALID.goodrange + m + ">= n <= " + M + ")");

		    	}

			else if(target.alt.indexOf("rangenum") != -1 && isNaN(value)) {

				if (label.className.indexOf("required") != -1) {

					label.className = 'required problem';

				} 

		    		else {

		    			label.className = 'problem';

		    		}

				alert(VALID.numrange);

			}

		}

	},



	changing : function(e) {

		// hacking IE events:

		var e = (e) ? e : window.event ;

		var target = (e.target) ? e.target : e.srcElement ; 

		

		VALID.checkfield(target);

	}

}



EXTRAS = {

	// Event listener by Scott Andrew (www.scottandrew.com):

	addEvent : function(obj, evType, fn, useCapture){

		if (obj.addEventListener){

			obj.addEventListener(evType, fn, useCapture);

			return true;

		} 

		else if (obj.attachEvent){

			var r = obj.attachEvent("on"+evType, fn);

			return r;

		} 

		else {

			return false;

		}

	}, 

	

	// Method adapted from Dan Pupius (pupius.co.uk):

	getElementsByClass : function(className,equal,node) {

		if(!node) node=document;

		var refTags = document.all ? document.all : node.getElementsByTagName("*");

		var retVal = new Array();

		for(var z=0;z<refTags.length;z++) {

			if((equal==1 && refTags[z].className == className) || (equal==0 && refTags[z].className.indexOf(className) != -1))

			retVal.push(refTags[z]);

		}

		return retVal; 

	}

}



// adds 1 or more elements to an array (IE only)

if(!Array.prototype.push)

{

	Array.prototype.push =  function()

	{

		var i;

		for(i=0; j=arguments[i]; i++) this[this.length] = j;

		return this.length;

	}

}



// start on page load

if(document.getElementsByTagName) {

	EXTRAS.addEvent(window, "load", VALID.tieFormEvents, false);

}