
var _fieldArray=new Array();var _numericTypes="|numeric|integer|currency|";var _stringTypes="|string|alpha|strictalpha|strictalphanum|email|url|numstring|";var _dateTypes="|date|";var _validTypes=_numericTypes+_stringTypes+_dateTypes;function _Field(fieldObj,label,parameters){function _dateFormat(formatStr){function _getRegExp(formatStr){formatStr=formatStr.replace(/M{3}/i,"([A-Za-z]{3})");formatStr=formatStr.replace(/M{2}/i,"([0-9]{2})");formatStr=formatStr.replace(/M{1}/i,"([0-9]{1,2})");formatStr=formatStr.replace(/D{2}/i,"([0-9]{2})");formatStr=formatStr.replace(/D{1}/i,"([0-9]{1,2})");formatStr=formatStr.replace(/Y{4}/i,"([0-9]{4})");formatStr=formatStr.replace(/Y{2}/i,"([0-9]{2})");return new RegExp("^"+formatStr+"$");}
function _getOrder(formatStr){formatStr=formatStr.toUpperCase();formatStr=formatStr.replace(/[^DMY]/g,"");formatStr=formatStr.replace(/D+/g,"D");formatStr=formatStr.replace(/M+/g,"M");formatStr=formatStr.replace(/Y+/g,"Y");var outArr=new Array();for(var i=0;i<3;i++){outArr[formatStr.substring(i,i+1)]=i+1;}
return outArr;}
function _alphaMonth(formatStr){return(/M{3}/i.test(formatStr));}
function _validate(str){return this.regExp.test(trimStr(str));}
function _parse(str){var months=new Array();var i=1;months["JAN"]=i++;months["FEB"]=i++;months["MAR"]=i++;months["APR"]=i++;months["MAY"]=i++;months["JUN"]=i++;months["JUL"]=i++;months["AUG"]=i++;months["SEP"]=i++;months["OCT"]=i++;months["NOV"]=i++;months["DEC"]=i++;var outDate=false;var REArr=this.regExp.exec(trimStr(str));if(REArr){var day=(REArr[this.order["D"]])?REArr[this.order["D"]]:1;var month=REArr[this.order["M"]];if(this.alphaMonth){month=months[month.toUpperCase()];if(!month){return false;}}
month-=1;var year=REArr[this.order["Y"]];outDate=new Date(year,month,day);if((outDate.getDate()!=day)||(outDate.getMonth()!=month)){return false;}}
return outDate;}
this.originalFormat=formatStr;this.regExp=_getRegExp(formatStr);this.alphaMonth=_alphaMonth(formatStr);this.order=_getOrder(formatStr);this.validFormat=_validate;this.parse=_parse;}
if(!fieldObj){alert("Developer message: field "+label+" not found.");return false;}
this.obj=fieldObj;fieldObj.validationInfo=this;this.label=(label)?label:"this field";this.required=false;this.type="string";this.isArray=(fieldObj.length&&fieldObj[0]&&fieldObj[0].type)?true:false;this.numericType=false;this.stringType=true;this.dateType=false;this.min=null;this.max=null;this.positive=false;this.negative=false;this.len=null;this.minlen=null;this.maxlen=null;this.dateFormat=null;this.dateFormatDescr=null;this.valFunction=null;this.valFuncParams=null;this.relatedTo=null;this.relationship=null;this.compareTo=null;this.compareHow=null;this.validateIf=true;if(parameters){var paramArr=parameters.split(/;/);for(var i=0;i<paramArr.length;i++){var equalsSignLoc=paramArr[i].indexOf("=");if(equalsSignLoc!=-1){var currParam=trimStr(paramArr[i].substr(0,equalsSignLoc).toLowerCase());var currValue=trimStr(paramArr[i].substr(equalsSignLoc+1));}
else{var currParam=trimStr(paramArr[i].toLowerCase());}
switch(currParam){case"required":this.required=true;break;case"type":currValue=currValue.toLowerCase();if(_validTypes.indexOf("|"+currValue+"|")!=-1){this.type=currValue;this.numericType=(_numericTypes.indexOf("|"+currValue+"|")!=-1);this.stringType=(_stringTypes.indexOf("|"+currValue+"|")!=-1);this.dateType=(_dateTypes.indexOf("|"+currValue+"|")!=-1);}
else{alert("Developer message: unknown field type ("+currValue+") supplied.\nField: "+this.label);this.numericType=false;this.stringType=true;this.dateType=false;}
break;case"min":case"max":case"len":case"minlen":case"maxlen":eval("this."+currParam+" = currValue");break;case"positive":this.positive=true;break;case"negative":this.negative=true;break;case"dateformat":if(!this.dateFormat){this.dateFormat=new Array();}
this.dateFormat[this.dateFormat.length]=new _dateFormat(currValue);break;case"dateformatdescr":this.dateFormatDescr=currValue;break;case"function":this.valFunction=currValue;break;case"funcparams":this.valFuncParams=currValue;break;case"relatedto":this.relatedTo=currValue;break;case"relationship":this.relationship=currValue.toLowerCase();break;case"compareto":this.compareTo=currValue;break;case"comparehow":this.compareHow=currValue.toLowerCase();break;case"validateif":this.validateIf=currValue;break;default:if(trimStr(currParam)){alert("Developer message: unknown field attribute ("+currParam+") supplied.\nField: "+this.label);}
break;}}
if(this.dateType){if(!this.dateFormat){this.dateFormat=new Array();this.dateFormat[0]=new _dateFormat("M/D/YYYY");this.dateFormatDescr="M/D/YYYY";}
if(!this.dateFormatDescr){var dateFormatDescrArr=new Array();for(var i=0;i<this.dateFormat.length;i++){dateFormatDescrArr[i]=this.dateFormat[i].originalFormat;}
this.dateFormatDescr=dateFormatDescrArr.join(", ");switch(dateFormatDescrArr.length){case 1:break;case 2:this.dateFormatDescr=this.dateFormatDescr.replace(/, ([^,]+)$/," or $1");break;default:this.dateFormatDescr=this.dateFormatDescr.replace(/, ([^,]+)$/,", or $1");break;}}}
if(!this.numericType&&!this.dateType&&(this.min!=null||this.max!=null)){alert("Developer message: 'min' and 'max' field attributes are only applicable to numeric and date field types.\nField: "+this.label);this.min=null;this.max=null;}
if(!this.numericType&&(this.positive||this.negative)){alert("Developer message: 'positive' and 'negative' field attributes are only applicable to numeric types.\nField: "+this.label);this.positive=false;this.negative=false;}
if(!this.stringType&&(this.len!=null||this.minlen!=null||this.maxlen!=null)){alert("Developer message: 'len', 'minlen', and 'maxlen' field attributes are only applicable to string field types.\nField: "+this.label);this.minlen=null;this.maxlen=null;}
else{if(this.len!=null&&isNaN(this.len)){alert("Developer message: supplied 'len' attribute is not a number.\nField: "+this.label);this.len=null;}
else{this.len=(this.len!=null)?Number(this.len):null;}
if(this.minlen!=null&&isNaN(this.minlen)){alert("Developer message: supplied 'minlen' attribute is not a number.\nField: "+this.label);this.minlen=null;}
else{this.minlen=(this.minlen!=null)?Number(this.minlen):null;}
if(this.maxlen!=null&&isNaN(this.maxlen)){alert("Developer message: supplied 'maxlen' attribute is not a number.\nField: "+this.label);this.maxlen=null;}
else{this.maxlen=(this.maxlen!=null)?Number(this.maxlen):null;}}
if(this.numericType){if(this.min!=null&&isNaN(this.min)){alert("Developer message: supplied 'min' attribute is not a number.\nField: "+this.label);this.min=null;}
else{this.min=(this.min!=null)?Number(this.min):null;}
if(this.max!=null&&isNaN(this.max)){alert("Developer message: supplied 'max' attribute is not a number.\nField: "+this.label);this.max=null;}
else{this.max=(this.max!=null)?Number(this.max):null;}}
if(this.dateType){if(this.min!=null){this.min=_parseDate(this,this.min);if(!this.min){alert("Developer message: supplied 'min' attribute is not a valid date.\nField: "+this.label);this.min=null;}}
if(this.max!=null){this.max=_parseDate(this,this.max);if(!this.max){alert("Developer message: supplied 'max' attribute is not a valid date.\nField: "+this.label);this.max=null;}}}
if((this.min!=null)&&(this.max!=null)&&(this.min>this.max)){alert("Developer message: supplied 'min' attribute is greater than supplied 'max' attribute.\nField: "+this.label);var tmp=this.min;this.min=this.max;this.max=tmp;}
if(this.positive&&this.negative){alert("Developer message: 'positive' attribute is incompatible with 'negative' attribute.\nField: "+this.label);this.negative=false;}
if(this.positive&&this.min!=null){alert("Developer message: 'positive' attribute is incompatible with 'min' attribute.\nField: "+this.label);this.min=null;}
if(this.positive&&this.max!=null&&this.max<=0){alert("Developer message: 'positive' attribute is incompatible with 'max' attribute with value less than zero.\nField: "+this.label);this.max=null;}
if(this.negative&&this.max!=null){alert("Developer message: 'negative' attribute is incompatible with 'max' attribute.\nField: "+this.label);this.min=null;}
if(this.negative&&this.min!=null&&this.min>=0){alert("Developer message: 'negative' attribute is incompatible with 'min' attribute with value greater than zero.\nField: "+this.label);this.max=null;}
if((this.minlen!=null)&&(this.maxlen!=null)&&(this.minlen>this.maxlen)){alert("Developer message: supplied 'minlen' attribute is greater than supplied 'maxlen' attribute.\nField: "+this.label);var tmp=this.minlen;this.minlen=this.maxlen;this.maxlen=tmp;}
if(this.len){if(this.len<0){alert("Developer message: supplied 'len' attribute is negative.\nField: "+this.label);this.len=null;}
else{this.minlen=this.len;this.maxlen=this.len;}}
if(this.minlen<0){alert("Developer message: supplied 'minlen' attribute is negative.\nField: "+this.label);this.minlen=null;}
if(this.maxlen<0){alert("Developer message: supplied 'maxlen' attribute is negative.\nField: "+this.label);this.maxlen=null;}}
function validate(){var _field=this;function _isEmpty(theValue){theValue=trimStr(theValue);return!((theValue)||(!theValue&&theValue==0&&theValue.length>0));}
function _isNumeric(){return!isNaN(_value);}
function _isInteger(){return(_isNumeric(_value)&&(_value==Math.floor(_value)));}
function _isCurrency(){return(_isNumeric(_value)&&(_checkNumberFormat(null,2)));}
function _isAlpha(){var re=new RegExp("[^a-z ,.]","i");return(!re.test(trimStr(_value)));}
function _isStrictAlpha(){var re=/[^a-z]/i;return(!re.test(trimStr(_value)));}
function _isStrictAlphaNum(){var re=/[^a-z0-9]/i;return(!re.test(trimStr(_value)));}
function _isNumString(){var re=/[^0-9]/i;return(!re.test(trimStr(_value)));}
function _isEmail(){var re=/^(\w|\.)+@(\w|\.)+\.(com|net|org)$/i;return(re.test(trimStr(_value)));}
function _isUrl(){var re=/^https?:\/\/[^ ]+$/i;return(re.test(trimStr(_value)));}
function _isDate(){var valid=false;for(var i=0;!valid&&i<_field.dateFormat.length;i++){valid=(_field.dateFormat[i].parse(_value))?true:false;}
return valid;}
function _checkNumberFormat(integerDigits,fractionalDigits){var integerPartOK=false;var fractionalPartOK=false;theValue=trimStr(_value);if(theValue.indexOf(".")!=-1){var valueParts=theValue.split(".",2);var integerPart=valueParts[0];var fractionalPart=valueParts[1];}
else{var integerPart=theValue;fractionalDigits=null;}
integerPartOK=(integerDigits==null)||(integerPart==integerPart.substr(0,integerDigits));fractionalPartOK=(fractionalDigits==null)||(fractionalPart==fractionalPart.substr(0,fractionalDigits));return(integerPartOK&&fractionalPartOK);}
function _checkLen(min,max){var valueLen=_value.length;if(min==null&&max==null){return true;}
if(min==max){if(valueLen!=min){return errorAlert(_fieldObj,sentenceCase(_field.label)+" must be exactly "+min+" characters long. Current length is "+valueLen+" characters.");}
else{return true;}}
if(min==null){if(valueLen>max){return errorAlert(_fieldObj,sentenceCase(_field.label)+" must be no more than "+max+" characters long. Current length is "+valueLen+" characters.");}
else{return true;}}
if(max==null){if(valueLen<min){return errorAlert(_fieldObj,sentenceCase(_field.label)+" must be at least "+min+" characters long. Current length is "+valueLen+" characters.");}
else{return true;}}
if(valueLen<min||valueLen>max){return errorAlert(_fieldObj,sentenceCase(_field.label)+" must be between "+min+" and "+max+" characters long. Current length is "+valueLen+" characters.");}
return true;}
function _checkRange(min,max){if(min==null&&max==null){return true;}
var theValue=_value;if(min==null){if(theValue>max){if(_field.dateType){return errorAlert(_fieldObj,sentenceCase(_field.label)+" must be on or before "+_formatDate(max)+".");}
else{return errorAlert(_fieldObj,sentenceCase(_field.label)+" must be less than or equal to "+max+".");}}
else{return true;}}
if(max==null){if(theValue<min){if(_field.dateType){return errorAlert(_fieldObj,sentenceCase(_field.label)+" must be on or after "+_formatDate(min)+".");}
else{return errorAlert(_fieldObj,sentenceCase(_field.label)+" must be greater than or equal to "+min+".");}}
else{return true;}}
if(theValue<min||theValue>max){if(_field.dateType){return errorAlert(_fieldObj,sentenceCase(_field.label)+" must be between "+_formatDate(min)+" and "+_formatDate(max)+".");}
else{return errorAlert(_fieldObj,sentenceCase(_field.label)+" must be between "+min+" and "+max+".");}}
return true;}
function _relationship(index){var otherField=eval(_field.relatedTo);if(otherField&&otherField.validationInfo){var otherFieldDef=otherField.validationInfo;if(otherFieldDef.isArray&&index!=null){if(otherField[index]){otherField=otherField[index];}
else{return true;}}
var otherValue=_getValue(otherField);switch(_field.relationship){case"dependent":if(_isEmpty(otherValue)&&!_isEmpty(_value)){return errorAlert(otherField,"If the "+_field.label+" field is entered, the "+otherFieldDef.label+" field is required also.");}
break;case"mutuallydependent":if(_isEmpty(otherValue)^_isEmpty(_value)){if(_isEmpty(_value)){var errorField=_fieldObj;}
else{var errorField=otherField;}
return errorAlert(errorField,"If either the "+_field.label+" or the "+otherFieldDef.label+" field is entered, the other is required also.");}
break;case"mutuallyexclusive":if(!(_isEmpty(otherValue)||_isEmpty(_value))){return errorAlert(_fieldObj,"Either the "+_field.label+" field or the "+otherFieldDef.label+" field can be entered, but not both.");}
break;case"exactlyone":if(!(_isEmpty(otherValue)^_isEmpty(_value))){return errorAlert(otherField,"One of the "+_field.label+" field or the "+otherFieldDef.label+" field must be entered, but not both.");}
break;case"atleastonerequired":if(_isEmpty(otherValue)&&_isEmpty(_value)){return errorAlert(otherField,"The "+_field.label+" field and/or the "+otherFieldDef.label+" field is required.");}
break;}}
return true;}
function _compare(index){var otherField=eval(_field.compareTo);if(otherField&&otherField.validationInfo){var otherFieldDef=otherField.validationInfo;if(otherFieldDef.isArray&&index!=null){if(otherField[index]){otherField=otherField[index];}
else{return true;}}
var otherValue=_getValue(otherField);if(otherValue==""||_value==""){return true;}
var thisValue=_value;switch(_field.compareHow){case"greaterthan":var comparisonText="greater than";if(_field.numericType&&otherFieldDef.numericType){thisValue=Number(thisValue);otherValue=Number(otherValue);}
if(_field.dateType&&otherFieldDef.dateType){otherValue=_parseDate(otherFieldDef,otherValue);comparisonText="after";}
if(thisValue<=otherValue){return errorAlert(_fieldObj,sentenceCase(_field.label)+" must be "+comparisonText+" "+otherFieldDef.label+".");}
break;case"lessthan":var comparisonText="less than";if(_field.numericType&&otherFieldDef.numericType){thisValue=Number(thisValue);otherValue=Number(otherValue);}
if(_field.dateType&&otherFieldDef.dateType){otherValue=_parseDate(otherFieldDef,otherValue);comparisonText="before";}
if(thisValue>=otherValue){return errorAlert(_fieldObj,sentenceCase(_field.label)+" must be "+comparisonText+" "+otherFieldDef.label+".");}
break;case"greaterthanorequal":var comparisonText="greater than or equal to";if(_field.numericType&&otherFieldDef.numericType){thisValue=Number(thisValue);otherValue=Number(otherValue);}
if(_field.dateType&&otherFieldDef.dateType){otherValue=_parseDate(otherFieldDef,otherValue);comparisonText="equal to or after";}
if(thisValue<otherValue){return errorAlert(_fieldObj,sentenceCase(_field.label)+" must be "+comparisonText+" "+otherFieldDef.label+".");}
break;case"lessthanorequal":var comparisonText="less than or equal to";if(_field.numericType&&otherFieldDef.numericType){thisValue=Number(thisValue);otherValue=Number(otherValue);}
if(_field.dateType&&otherFieldDef.dateType){otherValue=_parseDate(otherFieldDef,otherValue);comparisonText="equal to or before";}
if(thisValue>otherValue){return errorAlert(_fieldObj,sentenceCase(_field.label)+" must be "+comparisonText+" "+otherFieldDef.label+".");}
break;}}
return true;}
function _validate(index){if(index==null){_fieldObj=_field.obj;}
else{_fieldObj=_field.obj[index];}
_value=_getValue(_fieldObj);if(_isEmpty(_value)){if(_field.required){return errorAlert(_fieldObj,sentenceCase(_field.label)+" is a required field.");}}
else{switch(_field.type){case"numeric":if(!_isNumeric(_value)){return errorAlert(_fieldObj,sentenceCase(_field.label)+" must be a valid number.");}
break;case"integer":if(!_isInteger(_value)){return errorAlert(_fieldObj,sentenceCase(_field.label)+" must be a valid integer.");}
break;case"currency":if(!_isCurrency(_value)){return errorAlert(_fieldObj,sentenceCase(_field.label)+" must be a valid dollar amount.");}
break;case"string":break;case"alpha":if(!_isAlpha(_value)){return errorAlert(_fieldObj,sentenceCase(_field.label)+" must contain only letters, spaces, commas, and periods.");}
break;case"strictalpha":if(!_isStrictAlpha(_value)){return errorAlert(_fieldObj,sentenceCase(_field.label)+" must contain only letters.");}
break;case"strictalphanum":if(!_isStrictAlphaNum(_value)){return errorAlert(_fieldObj,sentenceCase(_field.label)+" must contain only letters and digits.");}
break;case"numstring":if(!_isNumString(_value)){return errorAlert(_fieldObj,sentenceCase(_field.label)+" must contain only digits.");}
break;case"email":if(!_isEmail(_value)){return errorAlert(_fieldObj,sentenceCase(_field.label)+" must be a valid email address in the format 'user@host'.");}
break;case"url":if(!_isUrl(_value)){return errorAlert(_fieldObj,sentenceCase(_field.label)+" must be a valid URL beginning with 'http://' or 'https://'.");}
break;case"date":_value=_parseDate(_field,_value);if(!_value){return errorAlert(_fieldObj,sentenceCase(_field.label)+" must be a valid date in the format "+_field.dateFormatDescr+".");}
break;}
if(!_checkLen(_field.minlen,_field.maxlen)){return false;}
if(_field.positive&&_value<=0){return errorAlert(_fieldObj,sentenceCase(_field.label)+" must be a positive number.");}
if(_field.negative&&_value>=0){return errorAlert(_fieldObj,sentenceCase(_field.label)+" must be a negative number.");}
if(!_checkRange(_field.min,_field.max)){return false;}}
if(_field.relatedTo&&_field.relationship&&!_relationship(index)){return false;}
if(_field.compareTo&&_field.compareHow&&!_compare(index)){return false;}
if(_field.valFunction){var theFunction=eval("self."+_field.valFunction);var theParams="";if(_field.valFuncParams){theParams=","+_field.valFuncParams;}
if(theFunction){if(!eval("theFunction(_fieldObj"+theParams+")")){return false;}}}
return true;}
if(eval(this.validateIf)){if(this.isArray){for(i=0;i<this.obj.length;i++){if(!_validate(i)){return false;}}
return true;}
else{return _validate();}}
else{return true;}}
this.validate=validate;}
function _getValue(element){var outVal;if(element.value||element.value==0){outVal=element.value;}
else{switch(element.type){case"select-one":outVal=element.options[element.selectedIndex].value;break;case"select-multiple":outVal=element.options[element.selectedIndex].value;break;default:alert("Can't get value of "+element.type);}}
return outVal;}
function _validateRange(_field,min,max){if(min==null&&max==null){return true;}
var _value=_getValue(_field);if(min==null){if(_value>max){return errorAlert(_fieldObj,"The value of "+_field.label+" must be less than or equal to "+max+".");}
else{return true;}}
if(max==null){if(_value<min){return errorAlert(_fieldObj,"The value of "+_field.label+" must be greater than or equal to "+min+".");}
else{return true;}}
if(_value<min||_value>max){return errorAlert(_fieldObj,"The value of "+_field.label+" must be between "+min+" and "+max+".");}
return true;}
function _formatDate(dateObj){var months=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];return dateObj.getDate()+" "+months[dateObj.getMonth()]+" "+dateObj.getFullYear();}
function _parseDate(field,str){var valid=false;for(var i=0;(!valid)&&i<field.dateFormat.length;i++){valid=field.dateFormat[i].parse(str);}
return valid;}
function validateFields(){for(var i=0;i<_fieldArray.length;i++){if(!_fieldArray[i].validate()){return false;}}
return true;}
function defineField(fieldObj,description,parameters){_fieldArray[_fieldArray.length]=new _Field(fieldObj,description,parameters);}
function deleteFields(){for(var i=0;i<_fieldArray.length;i++){_fieldArray[i]=null;}
_fieldArray=new Array();}
function errorConfirm(theField,Msg){var choice=confirm(Msg);if(!choice){if(theField.select){theField.select();}
if(theField.focus){theField.focus();}}
return choice;}
function errorAlert(theField,msg){alert(msg);if(theField.select){theField.select();}
if(theField.focus){theField.focus();}
return false;}
function identical(valueOne,valueTwo){if(isNaN(Number(valueOne))){return(trimStr(valueOne.toUpperCase())==trimStr(valueTwo.toUpperCase()));}
else{return(parseFloat(valueOne)==parseFloat(valueTwo));}}
function trimStr(str){if(!str){return str;}
var tmpStr=str.replace(/\s+$/,"");return tmpStr.replace(/^\s+/,"");}
function sentenceCase(string){return string.substr(0,1).toUpperCase()+string.substr(1);}