// validation onchange handler for HTML form input elements function ecValidateField(actualValidationFunction, formField, hiddenName) { var fvr = FormVRec_findOrMake(formField.form); if (fvr.validateField(actualValidationFunction, null, formField)) { if (window.incModCount) incModCount(); if (hiddenName != null) hiddenName.value = 1; return true; } else return false; } // validation onsubmit handler for HTML form elements function ecValidateForm(form) { return FormVRec_findOrMake(form).validate(); } // actual validation function for floating point numbers function validateFloat(formField) { formField.value = trimStr(formField.value); if (formField.value == "") return true; var i = scanFloat(formField.value, 0); if (isNaN(parseFloat(formField.value)) || i < formField.value.length) { var failMsg = "The value \"" + formField.value + "\" is not valid for a (floating point) number.\n\n" + "Some examples of numbers in valid formats are:-\n" + "12 , -3.14 , .667 , -517.23e42 , .333E-26"; alert(failMsg); return false; } else return true; } // actual validation function for unsigned integers function validateUnsignedInt(formField) { var failMsg = "The value \"" + formField.value + "\" is not valid for an unsigned whole number.\n\n" + "Some examples of numbers in valid formats are:-\n" + "0 , 1 , 1 , 2 , 3 , 5 , 8 , 13 , 21"; validateUnsignedIntWithMsg(formField,failMsg); } function validateUnsignedIntWithMsg(formField,failMsg) { formField.value = trimStr(formField.value); if (formField.value == "") return true; var i = scanDigits(formField.value, 0); if (i < formField.value.length) { alert(failMsg); return false; } else return true; } // actual validation function for dates function validateDate(formField) { formField.value = trimStr(formField.value); var errMsg = checkDate(formField.value); if (errMsg != null) { alert(errMsg) return false; } else return true; } // Globals for the validation system var firstFormVRec = null; // a list of FormVRec objects, one for each form to be validated var validationFailedField; // a global buffer to pass the bad field to the timeout routine highlighting and focusing it // FormVRec object -- responsible for validating a form function FormVRec_findOrMake(form) // static method { for (var fvr = firstFormVRec; fvr != null; fvr = fvr.next) if (fvr.form === form) return fvr; firstFormVRec = new FormVRec(form, firstFormVRec); return firstFormVRec; } function FormVRec(form, nextFormVRec) { this.indexField = FormVRec_indexField; this.findOrMakeField = FormVRec_findOrMakeField; this.validate = FormVRec_validate; this.validateField = FormVRec_validateField; this.form = form; this.fieldVRecs = null; this.next = nextFormVRec; var elements = form.elements; for (var j = 0; j < elements.length; j++) this.indexField(elements[j]); } function FormVRec_indexField(formField) { if (!formField.onchange) return; var changeHandler = formField.onchange.toString(); var i = changeHandler.indexOf("ecValidateField"); if (i < 0 || i != changeHandler.lastIndexOf("ecValidateField")) return; while (i < changeHandler.length && changeHandler.charAt(i) != "(") i++; i++; while (i < changeHandler.length && changeHandler.charAt(i) == " ") i++; var start = i; while (i < changeHandler.length && " ,".indexOf(changeHandler.charAt(i)) == -1) i++; this.fieldVRecs = new FieldVRec(null, changeHandler.slice(start, i), formField, this.fieldVRecs); } function FormVRec_findOrMakeField(actualValidationFunction, validationFunctionNameStr, formField) { var f; for (f = this.fieldVRecs; f != null; f = f.next) if (f.field === formField) break; if (f == null) f = this.fieldVRecs = new FieldVRec(actualValidationFunction, validationFunctionNameStr, formField, this.fieldVRecs); return f; } function FormVRec_validate() { for (var v = this.fieldVRecs; v != null; v = v.next) if (!v.validate()) return false; return true; } function FormVRec_validateField(actualValidationFunction, validationFunctionNameStr, formField) { var f = this.findOrMakeField(actualValidationFunction, validationFunctionNameStr, formField); return f.validate(); } // FieldVRec object -- responsible for validating one form field function FieldVRec(actualValidationFunction, validationFunctionNameStr, formField, nextFieldVRec) { this.validate = FieldVRec_validate; this.field = formField; this.func = actualValidationFunction; this.funcNameStr = validationFunctionNameStr; this.next = nextFieldVRec; } function FieldVRec_validate() { var validationResult; if (this.func != null) validationResult = this.func(this.field); else { validationResult = eval(this.funcNameStr + "(this.field)"); } if (validationResult) return true; else { validationFailedField = this.field; setTimeout("validationFailedField.focus();validationFailedField.select();", 20); return false; } } // subroutines used by the validation functions function trimStr(str) { if (str == null || str.length == 0) return ""; var start = 0; while (start < str.length && " \t".indexOf(str.charAt(start)) >= 0) start++; var end = str.length; while (end > 0 && " \t".indexOf(str.charAt(end - 1)) >= 0) --end; return str.slice(start, end); } function scanFloat(str, i) { i = scanSignOpt(str, i); if (i < 0) return i; i = scanMantissa(str, i); if (i < 0) return i; return scanExponentOpt(str, i); } function scanSignOpt(str, i) { if (i < str.length) switch (str.charAt(i)) { case "+": case "-": i++; break; default: break; } return i; } function scanMantissa(str, i) { if (i >= str.length) return -str.length; if (str.charAt(i) == ".") return scanDigits(str, i + 1); i = scanDigits(str, i); if (i < 0) return i; if (i < str.length && str.charAt(i) == ".") i = scanDigitsOpt(str, i + 1); return i; } function scanExponentOpt(str, i) { if (i >= str.length) return i; switch (str.charAt(i)) { case "e": case "E": i++; break; default: return i; } i = scanSignOpt(str, i); if (i < 0) return i; return scanDigits(str, i); } function scanDigits(str, i) { var nextI = scanDigitsOpt(str, i); return nextI == i ? -nextI : nextI; } function scanDigitsOpt(str, i) { while (i < str.length && "0123456789".indexOf(str.charAt(i)) >= 0) i++; return i; } function checkDate(dateStr) { if (dateStr == null || dateStr == "") return null; var code_0 = "0".charCodeAt(0); var code_sep_offset = "/".charCodeAt(0) - code_0; var i = 0; var month = 0; var day = 0; var digitCount = 0; var dateTemplate = 'MM/dd/yyyy'; var dateFormat1 = 'MM/dd/yyyy'; var dateFormat2 = 'dd/MM/yyyy'; while (i < dateStr.length) { var c = dateStr.charCodeAt(i++) - code_0; if (c == code_sep_offset) break; if (c < 0 || c > 9) { return "The value \"" + dateStr + "\" is not in the required date format: "+dateTemplate+"."; } digitCount++; if (dateTemplate.indexOf('MM') == dateFormat1.indexOf('MM')) { month = 10*month + c; } else if (dateTemplate.indexOf('dd') == dateFormat2.indexOf('dd')) { day = 10*day + c; } } if (digitCount < 1 || digitCount > 2 || i >= dateStr.length || dateStr.charAt(i - 1) != "/") { return "The value \"" + dateStr + "\" is not in the required date format: "+dateTemplate+"."; } digitCount = 0; while (i < dateStr.length) { var c = dateStr.charCodeAt(i++) - code_0; if (c == code_sep_offset) break; if (c < 0 || c > 9) { return "The value \"" + dateStr + "\" is not in the required date format: "+dateTemplate+"."; } digitCount++; if (dateTemplate.indexOf('dd') == dateFormat1.indexOf('dd')) { day = 10*day + c; } else if (dateTemplate.indexOf('MM') == dateFormat2.indexOf('MM')) { month = 10*month + c; } } if (digitCount < 1 || digitCount > 2 || i >= dateStr.length || dateStr.charAt(i - 1) != "/") { return "The value \"" + dateStr + "\" is not in the required date format: "+dateTemplate+"."; } var year = 0; digitCount = 0; while (i < dateStr.length) { var c = dateStr.charCodeAt(i++) - code_0; if (c == code_sep_offset) break; if (c < 0 || c > 9) { return "The value \"" + dateStr + "\" is not in the required date format: "+dateTemplate+"."; } digitCount++; year = 10*year + c; } // alert("year: "+year+" month: "+month+" day: "+day); // for debugging if (digitCount != 4) { return "The value \"" + dateStr + "\" is not in the required date format: "+dateTemplate+"."; } if (year < 1900 || year > 9999) { return "The value \"" + dateStr + "\" is not in the required date format: "+dateTemplate+". The year must be between 1900 and 9999."; } if (month < 1 || month > 12) { return "The value \"" + dateStr + "\" is not in the required date format: "+dateTemplate+". The month must be between 1 and 12."; } var daysInMonth; switch (month) { case 2: daysInMonth = ((year%4 == 0) && ((!(year%100 == 0)) || (year%400 == 0))) ? 29 : 28; break; case 4: case 6: case 9: case 11: daysInMonth = 30; break; default: daysInMonth = 31; break; } if (day < 1) { return "The value \"" + dateStr + "\" is not in the required date format: "+dateTemplate+". The day of the month must be at least 1."; } var monthNames = [ "", "january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december" ]; if (day > daysInMonth) { return "The value \"" + dateStr + "\" is not in the required date format: "+dateTemplate+". The day of the month can't be greater than " + daysInMonth + " (the last day of " + monthNames[month] + " " + year + ")."; } while (i < dateStr.length) if (" \t".indexOf(dateStr.charAt(i++)) < 0) { return "The value \"" + dateStr + "\" is not in the required date format: "+dateTemplate+"."; } return null; }