/* FILE HEADER ************************************************** ** JS Validate ** Author: Karl Seguin, Timo Haberkern ** Homepage: http://jsval.berlios.de/ ** Version: 1.0.0 ** Copyright 2003, 2004 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]; field.ResetClass(); if (!field.IsValid()){ field.SetClass(strErrorClass); if (nErrorThrowType == 1) { _throwError(field); return false; }else{ if (objFirstError == null){ objFirstError = field; } strErrorMessage = _handleError (field, strErrorMessage); bError = true; } } } 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){ var elementName = element.name.toLowerCase(); for (var i = 0; i < arr.length; ++i){ 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){ if (!element.oldClassName) element.oldClassName = element.className; 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'); switch (this.type){ case "textarea": case "password": case "text": 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'); 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'); 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 = new Array(); 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.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(){ switch (this.type){ case "textarea": case "password": case "text": return this._ValidateText(); case "select-one": case "select-multiple": case "radio": case "checkbox": return this._ValidateGroup(); default: return true; } } Field.prototype.SetClass = function(newClassName){ if (this.elements){ for (var i = 0; i < this.elements.length; ++i){ this.elements[i].oldClassName = this.elements[i].className; alert (newClassName); this.elements[i].className = newClassName; } }else{ 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){ for (var i = 0; i < this.elements.length; ++i){ this.elements[i].className = this.elements[i].oldClassName; } }else{ this.element.className = this.element.oldClassName; } } } 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 == "email") && !(regex == "tel") && !(regex == "pc") && !(regex == "zip") && !(regex == "money") && !(regex == "creditcard") && !(regex == "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(){ //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 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(){ 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": alert(_getError(field, "err_enter")); obj.focus(); 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 "email": return ((/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,5})+$/).test(value)); case "tel": return ((/^1?[\- ]?\(?\d{3}\)?[\- ]?\d{3}[\- ]?\d{4}$/).test(value)); case "pc": return ((/^[a-z]\d[a-z] ?\d[a-z]\d$/i).test(value)); case "zip": return ((/^\d{5}$/).test(value)); case "money": return ((/^\d+([\.]\d\d)?$/).test(value)); case "creditcard": return (!isNaN(value)); case "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)); } }