function checkform(of)
{
	// Test if DOM is available
	if(!document.getElementById || !document.createTextNode){return;}
	//if(!document.getElementById('required')){return;}

	// Define error messages and split the required fields
	var valid = true;
	var errorID='errormsg';
	var errorClass='error'
	/* changes for named list */
	var errorMsg='Por favor, corrija los siguentes errores:';
	/* end changes for named list */
	var errorImg='';//'/Scripts/alert.gif';
	var errorAlt='Error';
	var errorTitle='Este campo tiene un error!';
	var nowUsing='';
	var foundErrors = [];
	//var reqfields=document.getElementById('required').value.split(',');
	
	// Cleanup old mess
	valid=true;
	// if there is an old errormessage field, delete it
	if(document.getElementById(errorID))
	{
		var em=document.getElementById(errorID);
		em.parentNode.removeChild(em);
	}
	var reqfields = of.getElementsByTagName("*");
	// remove old images and classes from the required fields
	for(var i=0;i<reqfields.length;i++)
	{
		var f=reqfields[i];
		if(f.previousSibling && /img/i.test(f.previousSibling.nodeName)){
			f.parentNode.removeChild(f.previousSibling);
		}
		if(!f.getAttribute("originalClassName")){
		  f.setAttribute("originalClassName",f.className);
		}
		f.className=f.getAttribute("originalClassName");
	}
	// loop over required fields
	for(var i=0;i<reqfields.length;i++){
		var f=reqfields[i];
		nowUsing=f;
		validfield=true;

		// two ways of using it:
		// <input type="text" required="Must complete field">
		// <input type="text" validate="Must be a valid email and have at least 6 characters" rules="required|mail|min:6">
		if(!f.getAttribute("required") && !f.getAttribute("validate")){continue;}
		rules = f.getAttribute("rules") || "required";
		if(f.getAttribute("required")) rules==""||rules=="required"?"required":"required|"+rules;
		rules = rules.split("|");

		// get field value according to its type
		if(f.type){
			switch(f.type.toLowerCase()){
				case 'text':
					str = f.value;
					break;
				case 'password':
					str = f.value;
					break;
				case 'textarea':
					str = f.value;
					break;
				case 'checkbox':
					checked = f.checked;
					str = checked ? f.value : "";
					break;
				case 'select-one':
					str = f.options[f.selectedIndex].value; 
					break;
			}
		}

	    for(var ii=0,jj=rules.length; ii < jj; ii++){
	    	rule = rules[ii];
	    
			rule = rule.split(":");
			rule[0] = rule[0].toLowerCase();

			if(rule[0] == "required"){
				validfield = validfield && cf_isNotEmpty(str);
			}else if(rule[0] == "mail"){
				validfield = validfield && cf_isEmailAddr(str);
			}else if(rule[0] == "alpha"){
				validfield = validfield && cf_isAlpha(str);
			}else if(rule[0] == "alphanumeric"){
				validfield = validfield && cf_isAlphanumeric(str);
			}else if(rule[0] == "plaintext"){
				validfield = validfield && cf_isPlainText(str);
			}else if(rule[0] == "numeric"){
				validfield = validfield && cf_isNumeric(str);
			}else if(rule[0] == "match"){
				if(rule[1]) validfield = validfield && cf_match(str, rule[1]);
			}else if(rule[0] == "minchars"){
				if(rule[1]) validfield = validfield && cf_minLength(str, rule[1]);
			}else if(rule[0] == "maxchars"){
				if(rule[1]) validfield = validfield && cf_maxLength(str, rule[1]);
			}else if(rule[0] == "not"){
				if(rule[1]) validfield = validfield && cf_notEqual(str, rule[1]);
			}else if(rule[0] == "lastcharnot"){
				if(rule[1]) validfield = validfield && cf_lastCharNot(str, rule[1]);
			}else if(rule[0] == "minvalue"){
				if(rule[1]) validfield = validfield && cf_minValue(str, rule[1]);
			}else if(rule[0] == "maxvalue"){
				if(rule[1]) validfield = validfield && cf_maxValue(str, rule[1]);
			}

		}
		
		valid = valid && validfield;
		
		if(errorImg != "") i=i+2;

	}
	alertStr = "";
	for (i in foundErrors) { 
		alertStr = alertStr + "\n" + foundErrors[i];
	};
	if(alertStr.length > 0) alert("Corrija estos errores:\n"+alertStr);
	return valid;

	/* Tool methods */
	function cf_adderr()
	{
		o=nowUsing;
		valid = false;
		// create image, add to and colourise the error fields
		if(errorImg != ""){
			var errorIndicator=document.createElement('img');
			errorIndicator.alt=errorAlt;
			errorIndicator.src=errorImg;
			errorIndicator.title=errorTitle;
			o.parentNode.insertBefore(errorIndicator,o);
		}
		o.className=errorClass;
			
		// Check if there is no error message
		if(!document.getElementById(errorID)){
		// create errormessage and insert before submit button
			var em=document.createElement('div');
			em.id=errorID;
			var newp=document.createElement('p');
			newp.appendChild(document.createTextNode(errorMsg))
			// clone and insert the error image
			if(errorImg != ""){
				newp.appendChild(errorIndicator.cloneNode(true));
			}
			em.appendChild(newp);
			/* added for named list */
			var newul=document.createElement('ul');		
			em.appendChild(newul);
			/* end added for named list */
			// find the errors placeholder
			var sb=document.getElementById('errors_placeholder');
			if(sb){
				sb.parentNode.insertBefore(em,sb);
			}	
		} 
		/* added for named list */
		var txt = o.getAttribute("required");
		txt = o.getAttribute("validate")?o.getAttribute("validate"):txt;
		if(document.getElementById(errorID)){
			var em=document.getElementById(errorID).getElementsByTagName('ul')[0];
			var newli=document.createElement('li');
			newli.appendChild(document.createTextNode(txt));
			em.appendChild(newli);
		}
		/* end added for named list */
		foundErrors[o.name] = txt;
	}
	
	function cf_isNotEmpty(str){
		if(str.length > 0) return true;
		cf_adderr();
		return false;
	}
	
	function cf_isEmailAddr(str){
	    if(str.match(/^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,7}$/) || str.length == 0) return true;
   		cf_adderr();
		return false;
	}
	
	function cf_isAlpha(str){
	    if(str.match(/^[a-zA-Z ]+$/)) return true;
		cf_adderr();
		return false;
	}
	
	function cf_isAlphanumeric(str){
	    if(str.match(/^[0-9a-zA-Z ]+$/)) return true;
		cf_adderr();
		return false;
	}
	
	function cf_isPlainText(str){
	    if(str.match(/^[\/ .,0-9a-zA-Zܿ!\?;:]+$/)) return true;
		cf_adderr();
		return false;
	}
		
	function cf_isNumeric(str){
	    if(str.match(/^[0-9]*$/)) return true;
		cf_adderr();
		return false;    
	}
	
	function cf_match(str, regex){
		if(str.match(regex)) return true;
		cf_adderr();
		return false;
	}
	
	function cf_minLength(str, len){
		if(str.length >= len) return true;
		cf_adderr();
		return false;
	}
	
	function cf_maxLength(str, len){
		if(str.length <= len) return true;
		cf_adderr();
		return false;
	}
	
	function cf_notEqual(str, str2){
		if(str != str2) return true;
		cf_adderr();
		return false;
	}
	function cf_lastCharNot(str, chr){
		if(f.value.charAt(f.value.length-1) != '*') return true;
		cf_adderr();
		return false;
	}
}
