/* FILE HEADER **************************************************** JS Validate** Author: Karl Seguin, Timo Haberkern** Homepage: http://jsval.berlios.de/** Version: 1.3.3** Copyright 2003, 2005 Timo Haberkern, Karl Seguin    This file is part of JS Validate.    JS Validate is free software; you can redistribute it and/or modify    it under the terms of the GNU Lesser General Public License as published by    the Free Software Foundation; either version 2 of the License, or    (at your option) any later version.    JS Validate is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU Lesser General Public License    along with JS Validate; if not, write to the Free Software    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA**** END HEADER ***************************************************/function validateCompleteForm (objForm, strErrorClass) {    return _validateInternal(objForm, strErrorClass, 0);};function validateStandard (objForm, strErrorClass) {    return _validateInternal(objForm, strErrorClass, 1);};/***************************************************************** Internal functions*****************************************************************/function _validateInternal(form, strErrorClass, nErrorThrowType){   var strErrorMessage = ""; var objFirstError = null;   if (nErrorThrowType == 0){    strErrorMessage = (form.err) ? form.err : _getLanguageText("err_form");   };   var fields = _GenerateFormFields(form);   for (var i = 0; i < fields.length; ++i){      var field = fields[i];      if (!field.IsValid(fields)){        field.SetClass(strErrorClass);        if (nErrorThrowType == 1) {            _throwError(field);            return false;        }else{            if (objFirstError == null){               objFirstError = field;            }            strErrorMessage = _handleError (field, strErrorMessage);            bError = true;        }      } else {      	field.ResetClass();      }   };   if (objFirstError != null) {      alert(strErrorMessage);      objFirstError.element.focus();      return false;  };  return true; }; function _getLanguageText(id){    objTextsInternal = new _jsVal_Language();    objTexts = null;    try {        objTexts = new jsVal_Language();    } catch (ignored){};    switch (id) {        case "err_form": strResult = (!objTexts || !objTexts.err_form) ? objTextsInternal.err_form : objTexts.err_form; break;        case "err_enter": strResult = (!objTexts || !objTexts.err_enter) ? objTextsInternal.err_enter : objTexts.err_enter; break;        case "err_select": strResult = (!objTexts || !objTexts.err_select) ? objTextsInternal.err_select : objTexts.err_select; break;    };    return strResult; }; function _GenerateFormFields(form){   var arr = new Array();   for (var i = 0; i < form.length; ++i){      var element = form.elements[i];                  var index = _getElementIndex(arr,element);      //if it doesn't already exist, add it to our array, else merge the change      if (index == -1){         arr[arr.length] = new Field(element, form);      }else{         arr[index].Merge(element)      };   };   return arr;};function _getElementIndex(arr, element){   if (element.name) {       var elementName = element.name.toLowerCase();       for (var i = 0; i < arr.length; ++i){       	  if (arr[i].element.name) { 			   if (arr[i].element.name.toLowerCase() == elementName){               	  return i;               }          };       };   }   return -1;};/***************************************************************** Standard translation*****************************************************************/function _jsVal_Language() {    this.err_form = "Please enter/select values for the following fields:\n\n";    this.err_select = "Please select a valid \"%FIELDNAME%\"";    this.err_enter = "Please enter a valid \"%FIELDNAME%\"";};/***************************************************************** Field Class*****************************************************************/function Field(element, form){   this.type = element.type;   this.element = element;   this.exclude = element.exclude || element.getAttribute('exclude');   this.err = element.err || element.getAttribute('err');   this.required = _parseBoolean(element.required || element.getAttribute('required'));   this.realname = element.realname || element.getAttribute('realname');   this.elements = new Array();      switch (this.type){      case "textarea":      case "password":      case "text":      case "file":         this.value = element.value;         this.minLength = element.minlength || element.getAttribute('minlength');         this.maxLength = element.maxlength || element.getAttribute('maxlength');         this.regexp = this._getRegEx(element);         this.minValue = element.minvalue || element.getAttribute('minvalue');         this.maxValue = element.maxvalue || element.getAttribute('maxvalue');         this.equals = element.equals || element.getAttribute('equals');         this.callback = element.callback || element.getAttribute('callback');         break;      case "select-one":      case "select-multiple":         this.values = new Array();         for (var i = 0; i < element.options.length; ++i){            if (element.options[i].selected && (!this.exclude || element.options[i].value != this.exclude)){               this.values[this.values.length] = element.options[i].value;            }         }         this.min = element.min || element.getAttribute('min');         this.max = element.max || element.getAttribute('max');         this.equals = element.equals || element.getAttribute('equals');         break;      case "checkbox":         this.min = element.min || element.getAttribute('min');         this.max = element.max || element.getAttribute('max');         //no break, let it fall through to radio      case "radio":          this.required = _parseBoolean(this.required || element.getAttribute('required'));          this.values = new Array();          if (element.checked){             this.values[0] = element.value;          }   		                   this.elements[0] = element;          break;   };};Field.prototype.Merge = function(element){   //never negate a require field   var required = _parseBoolean(element.getAttribute('required'));   if (required){      this.required = true;   };   //all other cases (except required) we only add if there isn't already a value (first come first served)   if (!this.err){      this.err = element.getAttribute('err');   };   if (!this.equals){   	  this.equals = element.getAttribute('equals');   };   if (!this.callback){   	  this.callback = element.getAttribute('callback');   };   if (!this.realname){      this.realname = element.getAttribute('realname');   };   if (!this.max){      this.max = element.getAttribute('max');   };   if (!this.min){      this.min = element.getAttribute('min');   };   if (!this.regexp){      this.regexp = this._getRegEx(element);   };   if (element.checked){      this.values[this.values.length] = element.value;   };   this.elements[this.elements.length] = element;};Field.prototype.IsValid = function(arrFields){   switch (this.type){      case "textarea":      case "password":      case "text":      case "file":         return this._ValidateText(arrFields);      case "select-one":      case "select-multiple":      case "radio":      case "checkbox":         return this._ValidateGroup(arrFields);      default:         return true;   };};Field.prototype.SetClass = function(newClassName){   if ( (newClassName) && (newClassName != "") ) {       if ( (this.elements) && (this.elements.length > 0)) {          for (var i = 0; i < this.elements.length; ++i){          	  if(this.elements[i].className != newClassName){                this.elements[i].oldClassName = this.elements[i].className;                this.elements[i].className = newClassName;              }          }       }else{       	  if(this.element.className != newClassName){            this.element.oldClassName = this.element.className;            this.element.className = newClassName;          }       };   }};Field.prototype.ResetClass = function(){	if ( (this.type != "button") && (this.type != "submit") && (this.type != "reset") ) {   		if ( (this.elements) && (this.elements.length > 0)) {      		for (var i = 0; i < this.elements.length; ++i){      			if(this.elements[i].oldClassName){         	 	  this.elements[i].className = this.elements[i].oldClassName;         	 	}         	 	else {    	  	 	  this.element.className = "";    	  		}      		}   		}else{   			if(this.elements.oldClassName){    	  	  this.element.className = this.element.oldClassName;    	  	}    	  	else {    	  	  this.element.className = "";    	  	}   		};	};};Field.prototype._getRegEx = function(element){   regex = element.regexp || element.getAttribute('regexp')   if (regex == null) return null;   retype = typeof(regex);   if (retype.toUpperCase() == "FUNCTION")       return regex;   else if ( (retype.toUpperCase() == "STRING") && !(regex == "JSVAL_RX_EMAIL") && !(regex == "JSVAL_RX_TEL")   				&& !(regex == "JSVAL_RX_PC") && !(regex == "JSVAL_RX_ZIP") && !(regex == "JSVAL_RX_MONEY") 				&& !(regex == "JSVAL_RX_CREDITCARD") && !(regex == "JSVAL_RX_POSTALZIP"))   {       nBegin = 0; nEnd = regex.length-1;       if (regex.charAt(0) == "/") nBegin=1;       if (regex.charAt(regex.length-1) == "/") nEnd=regex.length-2;	          return new RegExp(regex.slice(nBegin, nEnd));   }   else {       return regex;   };};Field.prototype._ValidateText = function(arrFields){   if ( (this.required) && (this.callback) ) {   	  nCurId = this.element.id ? this.element.id : "";   	  nCurName = this.element.name ? this.element.name : "";   	     	  eval("bResult = "+this.callback+"('"+nCurId+"', '"+nCurName+"', '"+this.value+"');");    	  if (bResult == false) {   	  	 return false;   	  };   } else {		   //required value is empty	   if (this.required && !this.value){	      return false;	   };	   //value less than minlength	   if (this.value && (this.minLength && this.value.length < this.minLength)){	      return false;	   };	   //value is more than maxlength	   if (this.value && (this.maxLength && this.value.length > this.maxLength)){	      return false;	   };	   //value fails regular expression	   if (this.regexp){	   	  if (!_checkRegExp(this.regexp, this.value))	   	  {	   	  	  //the field isn't required, but there is a value		      if (!this.required && this.value){		         return false;		      }		      if (this.required){		         return false;		      }	   	  }	   	  else	   	  {	   	  	return true;	   	  };	   };	   	   	   	   //check equality	   if (this.equals){	   	   for (var i = 0; i < arrFields.length; ++i){	       	   var field = arrFields[i];	       	   if ( (field.element.name == this.equals) || (field.element.id == this.equals) ) {	       	   	  if (field.element.value != this.value) {	       	   	  	 return false;	       	   	  };	       	   	  break;	       	   };	       };	   };	   	   //check against minvalue and maxvalue	   if (this.required){	      var fValue = parseFloat(this.value);	      if ((this.minValue || this.maxValue) && isNaN(fValue)){	         return false;	      };	      if ( (this.minValue) && (fValue < this.minValue) ) {	         return false;	      };	      if ( (this.maxValue) && (fValue > this.maxValue) ) {	         return false	      };	   };   }   return true;};Field.prototype._ValidateGroup = function(arrFields){   if (this.required && this.values.length == 0){      return false;   };   if (this.required && this.min && this.min > this.values.length){      return false;   };   if (this.required && this.max && this.max < this.values.length){      return false;   };   return true;};function _handleError (field, strErrorMessage) {   var obj = field.element;   strNewMessage = strErrorMessage + ( (field.realname)? field.realname : ((obj.id) ? obj.id : obj.name) ) + "\n";   return strNewMessage;};function _throwError(field){   var obj = field.element;   switch (field.type){      case "text":      case "password":      case "textarea":      case "file":         alert(_getError(field, "err_enter"));         try {         	obj.focus();         }         catch (ignore) {}         break;      case "select-one":      case "select-multiple":      case "radio":      case "checkbox":         alert(_getError(field, "err_select"));         break;      };};function _getError(field, str){   var obj = field.element;   strErrorTemp = (field.err) ? field.err : _getLanguageText(str);      idx = strErrorTemp.indexOf( "\\n" );   while ( idx > -1 ) {   	strErrorTemp = strErrorTemp.replace( "\\n", "\n" );    idx = strErrorTemp.indexOf( "\\n" );   };      return strErrorTemp.replace("%FIELDNAME%", (field.realname)? field.realname : ((obj.id) ? obj.id : obj.name));};function _parseBoolean(value){   return !(!value || value == 0 || value == "0" || value == "false");};function _checkRegExp(regx, value){  switch (regx){  case "JSVAL_RX_EMAIL":    return ((/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,5})+$/).test(value));  case "JSVAL_RX_TEL":    return ((/^1?[\- ]?\(?\d{3}\)?[\- ]?\d{3}[\- ]?\d{4}$/).test(value));  case "JSVAL_RX_PC":    return ((/^[a-z]\d[a-z] ?\d[a-z]\d$/i).test(value));  case "JSVAL_RX_ZIP":    return ((/^\d{5}$/).test(value));  case "JSVAL_RX_MONEY":    return ((/^\d+([\.]\d\d)?$/).test(value));  case "JSVAL_RX_CREDITCARD":    return (!isNaN(value));  case "JSVAL_RX_POSTALZIP":    if(value.length == 6 || value.length == 7)      return((/^[a-zA-Z]\d[a-zA-Z] ?\d[a-zA-Z]\d$/).test(value));    if(value.length == 5 || value.length == 10)      return((/^\d{5}(\-\d{4})?$/).test(value));    break;  default:    return (regx.test(value));  };};