// Rules // ----- // not-null // email // allow-bad // numeric // match // date // Languages var strInvalidCharacters = "The following character(s) are not allowed: '%1'"; var strFieldRequired = "This field must be completed."; var strDoesNotMatch = "This field does not match."; var strThereWereProblems = "There was a problem with some of the data you entered. Please see the red boxes."; var strVdInvalidEmail = "The email address is not valid."; var strVdInvalidDate = "The date is not in a valid format: "; var strVdInvalidNumber = "This is not a valid number."; var strVdDateTooLarge = "There are less than %1 days in %2 this year." var strSelectValue = "You must select a value" var strSelectMod = "You must select at least one module"; var strOverMaxLength = "The max length for this field is %1 characters, you used %2." var strUnderMinLength = "The min length for this field is %1 characters, you used %2." // Typo fixed in following on 12/1/05 var arrMonthsNames = new Array(0, "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"); function did(str) { return document.getElementById(str); } // This class holds an error. function CError(element, strErrorSpanId, strError) { this.element = element; this.strErrorSpanId = strErrorSpanId; this.strError = strError; } // A little function to ensure when an id for an error span is created, a // given input will always get the same id. function makeErrorId(elForm, elInput) { if(elForm && elInput) return "formValidate_"+elForm.name+"_"+elInput.name; else return "ggg"; } /** * Cross browser function to get the position of an element reletive to the * top left of the page. * * param: el - The element we are looking to locate. Must be element object. * param: strAxis - The axis we want to know. Valid value are left or top */ function getRealPos(el, strAxis) { iPos = 0; while(el!=null) { iPos += el["offset" + strAxis]; el = el.offsetParent; } return iPos } /** * Cross browser function to get far edge of an element * * param: el - The element we are looking to locate. Must be element object. * param: strAxis - The axis we want to know. Valid value are left or top */ function getFarPos(el, strAxis) { elOld = el; iPos = 0; while(el!=null) { iPos += el["offset" + strAxis]; el = el.offsetParent; } el = elOld; if(strAxis == "Left" || strAxis == "left" || strAxis == "LEFT") iPos += el.offsetWidth; if(strAxis == "Top" || strAxis == "top" || strAxis == "TOP") iPos += el.offsetHeight; return iPos } /** * Trim function taken from: * http://www.vermontsoftware.com/Javascript/trim.html */ function Trim(s) { // Remove leading spaces and carriage returns while ((s.substring(0,1) == ' ') || (s.substring(0,1) == '\n') || (s.substring(0,1) == '\r')) s = s.substring(1,s.length); // Remove trailing spaces and carriage returns while ((s.substring(s.length-1,s.length) == ' ') || (s.substring(s.length-1,s.length) == '\n') || (s.substring(s.length-1,s.length) == '\r')) s = s.substring(0,s.length-1); return s; } /** * Cross browser method of changing to class of an element. */ function isElementEmpty(el) { strValue = Trim(el.value); return strValue==''; } function IsNumeric(strText) { var strValidChars = "0123456789"; var blIsNumber = true; var blDecimalPointFound = false; var cChar; for(i=0; i= 1582) // unnecessarily accurate, but accurate all the same if( (((iYear % 4 == 0) && (iYear % 100 != 0)) || (iYear % 400 == 0)) && iDay != 1) iDay--; if(iDay > arrMonths[iMonth]) blFail = true; } if(blFail) { strError = strVdDateTooLarge.replace("%1", iDay); strError = strError.replace("%2", arrMonthsNames[iMonth]); arrErrorList[arrErrorList.length] = new CError(elInput, strErrorSpanId, strError); return false; } if(document.getElementById(strErrorSpanId)) { document.getElementById(strErrorSpanId).innerHTML = ''; document.getElementById(strErrorSpanId).style['display'] = 'none'; } return true; } // Perform character validation on a form element function basicCharacterValidation(elInput, elForm, arrIlligalList, arrErrorList) { //if (elInput.name == "yourquestion") //alert (arrIlligalList); strValue = elInput.value; strErrorSpanId = makeErrorId(elForm, elInput); arrBadCharList = new Array(); for(var j=0; j < arrIlligalList.length; j++) { if(strValue.indexOf(arrIlligalList[j]) != -1) { arrBadCharList[arrBadCharList.length] = (arrIlligalList[j]); } } if(arrBadCharList.length > 0) { strError = strInvalidCharacters.replace("%1", arrBadCharList.join(',')) arrErrorList[arrErrorList.length] = (new CError(elInput, strErrorSpanId, strError)); return false; } if(document.getElementById(strErrorSpanId)) { document.getElementById(strErrorSpanId).innerHTML = ''; document.getElementById(strErrorSpanId).style['display'] = 'none'; } return true; } function basicFormValidation(elForm) { return internalFormValidationTryWraper(elForm, Array('"', '#', '<', '*', '>', "''", '`', '~', '$')); } function nonstrictFormValidation(elForm) { return internalFormValidationTryWraper(elForm, Array('"', '<', '>', "''", '`', '~', '$')); } function internalFormValidationTryWraper(elForm, arrIlligalList) { try { return internalFormValidation(elForm, arrIlligalList); } catch(error) { //alert("hello error!"); blResponse = confirm("Could not validate page. If you are sure your data is correct, press 'OK' otherwise press 'Cancel' to change your data."); strAddress = new String(window.location); if(strAddress.substr(7, 6) == 'srvdev') { strErr = ""; for(i in error) { if(i == 'number') { strErr += i+"="+(error[i] & 0xffff)+"\n"; } else { strErr += i+"="+error[i]+"\n"; } } alert(strErr); setTimeout(function(){throw(error);}, 200); } return blResponse; } } function internalFormValidation(elForm, arrIlligalList) { if(!elForm) return true; var iNumElements = elForm.elements.length; var arrErrorList = new Array(); for(var iElementIndex = 0; iElementIndex < iNumElements; iElementIndex++) //for(iElementIndex in elForm.elements) { element = elForm.elements[iElementIndex]; if(element && element.getAttribute) { blNotNull = getRule(element, 'not-null'); blEmail = getRule(element, 'email'); blAllowBad = getRule(element, 'allow-bad'); strExtraBad = getRule(element, 'extra-bad'); blNumeric = getRule(element, 'numeric'); strMatch = getRule(element, 'match'); strDate = getRule(element, 'date'); strNotSel = getRule(element, 'notsel'); multiNotSel = getRule(element, 'notmultisel'); strMaxLen = getRule(element, 'maxlen'); strMinLen = getRule(element, 'minlen'); switch(element.type) { case "text": case "password": case "textarea": { // Our first test is that the field is not empty. // This is applied by the rule 'not-null' if(blNotNull && element.value == '') { strErrorSpanId = makeErrorId(elForm, element); arrErrorList[arrErrorList.length] = (new CError(element, strErrorSpanId, strFieldRequired)); blReturn = false; break; } // Our first test is that the field is not empty. // This is applied by the rule 'not-null' if(strMaxLen !== false) { iStrLen = element.value.length; if(iStrLen > strMaxLen) { strErrorMessage = strOverMaxLength; strErrorMessage = strErrorMessage.replace('%1', strMaxLen); strErrorMessage = strErrorMessage.replace('%2', iStrLen); strErrorSpanId = makeErrorId(elForm, element); arrErrorList[arrErrorList.length] = (new CError(element, strErrorSpanId, strErrorMessage)); blReturn = false; break; } } // Our first test is that the field is not empty. // This is applied by the rule 'not-null' if(strMinLen !== false) { iStrLen = element.value.length; if(iStrLen < strMinLen) { strErrorMessage = strUnderMinLength; strErrorMessage = strErrorMessage.replace('%1', strMinLen); strErrorMessage = strErrorMessage.replace('%2', iStrLen); strErrorSpanId = makeErrorId(elForm, element); arrErrorList[arrErrorList.length] = (new CError(element, strErrorSpanId, strErrorMessage)); blReturn = false; break; } } // Next we run a function to test that the field contains no illigal // characters as defined by the arrIlligalList array. If the rule // 'allow-bad' is set then this test is *not* run. if(!blAllowBad) { arrMyIlligalList = arrCopy(arrIlligalList); //alert(arrIlligalList); } else arrMyIlligalList = []; if(strExtraBad !== false) { for(i= 0; i < strExtraBad.length; i++) arrMyIlligalList[arrMyIlligalList.length] = strExtraBad.charAt(i); } if(!basicCharacterValidation(element, elForm, arrMyIlligalList, arrErrorList)) break; // This test is run on email fields to validate them. if(blEmail) { if(!emailInputValidation(element, elForm, arrErrorList)) break; } // This test is run on date fields to validate them. if(strDate != false) { if(!dateInputValidation(element, elForm, strDate, arrErrorList)) break; } // This test is run on numeric fields to validate them. if(blNumeric && !IsNumeric(element.value)) { strErrorSpanId = makeErrorId(elForm, element); arrErrorList[arrErrorList.length] = (new CError(element, strErrorSpanId, strVdInvalidNumber)); blReturn = false; break; } if(strMatch != false) { elMatch = elForm.elements[strMatch]; if(!elMatch) elMatch = document.getElementById(strMatch); if(elMatch) { if(elMatch.value != element.value) { strErrorSpanId = makeErrorId(elForm, element); arrErrorList[arrErrorList.length] = (new CError(element, strErrorSpanId, strDoesNotMatch)); blReturn = false; break; } } } // If we got here then all the tests passed! setElementErrorStatus(element, true); strErrorSpanId = makeErrorId(elForm, element); if(did(strErrorSpanId)) did(strErrorSpanId).style.display='none'; break; } break; case "select-one": { if(strNotSel != false || typeof(strNotSel) == 'string') { if(element.value == strNotSel) { strErrorSpanId = makeErrorId(elForm, element); arrErrorList[arrErrorList.length] = (new CError(element, strErrorSpanId, strSelectValue)); element.style.visibility = 'hidden'; blReturn = false; break; } else { strErrorSpanId = makeErrorId(elForm, element); if(did(strErrorSpanId)) did(strErrorSpanId).style.display='none'; setElementErrorStatus(element, true); break; } } } case "select-multiple": { //alert("hello from select multiple!"); if (element.selectedIndex == -1 && multiNotSel) { //alert ("no multi select"); strErrorSpanId = makeErrorId(elForm, element); arrErrorList[arrErrorList.length] = (new CError(element, strErrorSpanId, strSelectMod)); element.style.visibility = 'hidden'; blReturn = false; break; //return false; } else { strErrorSpanId = makeErrorId(elForm, element); setElementErrorStatus(element, true); //alert ("multi-select stuff selected"); } } case "button": case "submit": case "reset": case "checkbox": case "radio": break; // do nothing default: { // If it isn't something we can validate, just make it green :) //setElementErrorStatus(element, true); break; } } } } if(arrErrorList.length > 0) { for(var i=0; i < arrErrorList.length; i++) { if(arrErrorList[i] && arrErrorList[i].element) { el = arrErrorList[i].element; strId = makeErrorId(elForm, el); el.onfocus = closeErrorElementsMessage; setElementErrorStatus(el, false); strMessage = arrErrorList[i].strError + ''+ '[close]'+ ''; if(document.getElementById(strId)) { elSpan = document.getElementById(strId); elSpan.style['display'] = ''; elSpan.innerHTML = strMessage; } else { elSpan = document.createElement('span'); setElementClass(elSpan, 'formValidationErrorArea'); elSpan.id = strId; elSpan.setAttribute('elTarget', el.name); if(elSpan.getAttribute('elTarget') == el.name && elSpan.tagName == "select-one") { el.style.visibility = 'hidden'; } iInputHeight = el.clientHeight + 3; iXPos = getRealPos(el,'Left'); iYPos = getRealPos(el,'Top'); elSpan.style['left'] = iXPos; elSpan.style['top'] = iYPos; elSpan.style['height'] = iInputHeight+'px'; elSpan.innerHTML = strMessage; elBody = document.getElementsByTagName('body')[0]; elBody.appendChild(elSpan); iFarEdgeOfInput = getFarPos(el, "Left"); iFarEdgeOfSpan = getFarPos(elSpan, "Left"); if(iFarEdgeOfInput < iFarEdgeOfSpan) { iNew = iXPos - (iFarEdgeOfSpan-iFarEdgeOfInput); if(iNew < 0) iNew = 0; elSpan.style['left'] = iNew; } } } } iHeight = 0; if(window.innerHeight) iHeight = window.innerHeight; if(document.body && document.body.clientHeight) iHeight = document.body.clientHeight; if(document.documentElement && document.documentElement.clientHeight) iHeight = document.documentElement.clientHeight; iYPos = getRealPos(arrErrorList[0].element, 'Top') - (iHeight/2); scroll(0, iYPos); alert(strThereWereProblems); return false; } return true; } function arrCopy(arr) { var arrNew = []; for(var i in arr) { //alert(i); if(typeof(arr[i]) == 'object' || typeof(arr[i]) == 'array') arrNew[i] = arrCopy(arr[i]) else arrNew[i] = arr[i]; } return arrNew; } function closeErrorElementsMessage(el) { if(!el) el = this; if(el) { elForm = el; while(elForm != null && elForm.tagName != 'FORM') elForm = elForm.parentNode; strId = makeErrorId(elForm, el); closeErrorMessage(strId); } } function closeErrorMessage(strId) { elSpan = did(strId) if(elSpan) { elSpan.style.display = 'none'; strFormElemene = elSpan.getAttribute('elTarget'); arrElements = document.getElementsByName(strFormElemene); for(i in arrElements) { if(arrElements[i] && arrElements[i].style) arrElements[i].style.visibility = ''; } } }