JavaScript DHTML/Form Control/Form Validation

Материал из Web эксперт
Перейти к: навигация, поиск

Check form input value and alert user by change the control background

   <source lang="html4strict">

<html> <head> <title>Form Validation</title> <script type="text/javascript"> function checkValid() {

   var valueField = document.forms[0]["myValue"];
   if (valueField.value != "A") {
       valueField.style.background = "#FF0000";
       var inputDiv = document.getElementById("inputDiv");
       var feedbackdiv = document.createElement("div");
       feedbackdiv.setAttribute("id","feedback");
       inputDiv.appendChild(feedbackdiv);
       feedbackdiv.appendChild(document.createTextNode("Incorrect myValue."));
       return false;
   } else {
       return true;
   }

} </script> </head> <body> <form name="formexample" id="formexample" action="#">

myValue: <input id="myValue" name="myValue">
<input id="submit" type="submit">

</form> <script type="text/javascript">

   function init() {
       document.forms[0].onsubmit = function() { 
          return checkValid() 
       };
   }
   window.onload = init;

</script> </body> </html>

 </source>
   
  


Comprehensive form validation

   <source lang="html4strict">
 

<HTML> <HEAD> <TITLE>validate_form.js -- Example: Heavy Duty</TITLE> <SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript"> /**

 VALIDATE_FORM.JS
 Comprehensive solution for validating HTML forms.
 Copyright (C) 2002, Jeff Epstein, jeff_epstein@yahoo.ru, http://www.jeffyjeffy.ru#download
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 This program 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 General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
**/

/**

 See validate_form_documentation.html for information.
 NOTES TO SELF
   //alert("The CODE for getRCBSMTrackerArrIdx=" + getRCBSMTrackerArrIdx);
   I would like to add a function to get the number of elements that have a (any) value.
**/

//GLOBAL VARIABLES...start (do not alter this section)

 var sDBG_INDENT = "     ";
 var asRCBSM_TRACKER_NAME = "";
 var aiRCBSM_TRACKER_SEL_COUNT = "";
 var aiRCBSM_TRACKER_ARR_IDX = "";
 var iELEMENT_COUNT = -1;
 var bFIRST_DEBUG_SCREEN_SEEN = false;
 var sCURRENT_LENGTH_FOR_TA = "~CURRLEN~";
 var bPHONE_ZIP_FORMATS_VALIDATED = false;

//GLOBAL VARIABLES...end /**

 All messages must be at least one character in length.  If they are empty string, its as if they do not exist.
**/

function getFormErrorMsgs(f_orm, s_userErrorPrefix, i_debugPerScreen) {

 //This initialization function must be the very first line.
 initializeLocalVars();
 if(!arePhoneZipFormatsValid())  {
   return;
 }
 crashIfBadConfiguration(f_orm);
 if(hasCrashed())  {
   //For whatever reason utility.crash() was called, indicating
   //an error has occured.  Get out.  Get out while you still
   //can.
   return;
 }
 outputDebugging(f_orm, i_debugPerScreen);
 return getUserErrors(f_orm, s_userErrorPrefix);

} /**

 PRIVATE FUNCTIONS...start
**/
 function arePhoneZipFormatsValid()  {
   if(bPHONE_ZIP_FORMATS_VALIDATED)  {
     //Phone and zip code formats are checked only once.
     //They"ve already been checked once and are all were
     //found to be valid.
     return true;
   }
   //The formats have not yet been checked, or they were, but
   //were found to be invalid.
   var i = -1;
   var siPMin = "";
   var siPMax = "";
   for(i = 1; i < 11; i++)  {
     siPMin = eval("siPHONE_" + i + "_MINIMUM");
     siPMax = eval("siPHONE_" + i + "_MAXIMUM");
     if(!isPhoneFormatValid("false", siPMin, siPMax))  {
       alert("---  validate_form.js ERROR  ---\n\nPhone number format invalid:\n\tsiPHONE_" + i + "_MINIMUM="" + eval("siPHONE_" + i + "_MINIMUM") + ""\n\tsiPHONE_" + i + "_MAXIMUM="" + eval("siPHONE_" + i + "_MAXIMUM") + ""\n\nThe specific error message follows...");
       isPhoneFormatValid("true", siPMin, siPMax);
       return false;
     }
   }
   var siZRMin = "";
   var siZRMax = "";
   var siZAMin = "";
   var siZAMax = "";
   for(i = 1; i < 11; i++)  {
     siZRMin = eval("siZIP_" + i + "_RQD_MINIMUM");
     siZRMax = eval("siZIP_" + i + "_RQD_MAXIMUM");
     siZAMin = eval("siZIP_" + i + "_ALT_MINIMUM");
     siZAMax = eval("siZIP_" + i + "_ALT_MAXIMUM");
     if(!isZipFormatValid("false", siZRMin, siZRMax, siZAMin, siZAMax))  {
       alert("---  validate_form.js ERROR  ---\n\nZip code format invalid:\n\tsiZIP_" + i + "_RQD_MINIMUM="" + eval("siZIP_" + i + "_RQD_MINIMUM") + ""\n\tsiZIP_" + i + "_RQD_MAXIMUM="" + eval("siZIP_" + i + "_RQD_MAXIMUM") + ""\n\tsiZIP_" + i + "_ALT_MINIMUM="" + eval("siZIP_" + i + "_ALT_MINIMUM") + ""\n\tsiZIP_" + i + "_ALT_MAXIMUM="" + eval("siZIP_" + i + "_ALT_MAXIMUM") + ""\n\nThe specific error message follows...");
       isZipFormatValid("true", siZRMin, siZRMax, siZAMin, siZAMax)
       return false;
     }
   }
   bPHONE_ZIP_FORMATS_VALIDATED = true;
   return true;
 }
  function crashIfBadConfiguration(f_orm)  {
   crashIfMissing(f_orm, "f_orm", "validate_form.getFormErrorMsgs");
   crashIfBadBSSA("f_orm.asGlobalBadSubStrs", f_orm.asGlobalBadSubStrs);
   f_orm.bsGlobalTrimSpaces = getOptBooleanStringVF(f_orm.bsGlobalTrimSpaces, "f_orm.bsGlobalTrimSpaces");
   if(hasCrashed())  {
     return;
   }
   for(var i = 0; i < f_orm.length; i++)  {
     if(f_orm[i].type == "text"  ||  f_orm[i].type == "password")  {
       crashIfBadCfg_text(f_orm, f_orm[i]);
     }  else if(f_orm[i].type == "textarea")  {
       crashIfBadCfg_textarea(f_orm, f_orm[i]);
     }  else if(f_orm[i].type == "checkbox"  ||  f_orm[i].type == "select-multiple")  {
       crashIfBadCfg_cbsm(f_orm, i);
     }  else if(f_orm[i].type == "radio"  ||  f_orm[i].type == "select-one")  {
       crashIfBadCfg_rso(f_orm, i);
     }
   }
 }
 function outputDebugging(f_orm, i_debugPerScreen)  {
   if(!i_debugPerScreen  ||  i_debugPerScreen == -1)  {
     //No debugging is requested
     return;
   }
   if(typeof(i_debugPerScreen) != "number"  ||  i_debugPerScreen < 1)  {
     return crashVF("i_debugPerScreen is not required (currently "" + i_debugPerScreen + ""), but when provided, it must be a number (currently "" + typeof(i_debugPerScreen) + "") either equal to -1, or greater than zero.");
   }
   var iDebugItemsTotal = 0;
   var iDebugItemsThisRound = 0;
   var sDebugBuffer = "";
   var sDebugThisItem = "";
   for(var i = 0; i < f_orm.length; i++)  {
     if(f_orm[i].type == "text"  ||  f_orm[i].type == "password")  {
       sDebugThisItem = getDebugging_text(f_orm, f_orm[i]);
     }  else if(f_orm[i].type == "textarea")  {
       sDebugThisItem = getDebugging_textarea(f_orm, f_orm[i]);
     }  else if(f_orm[i].type == "checkbox"  ||  f_orm[i].type == "select-multiple")  {
       sDebugThisItem = getDebugging_cbsm(f_orm, i);
     }  else if(f_orm[i].type == "radio"  ||  f_orm[i].type == "select-one")  {
       sDebugThisItem = getDebugging_rso(f_orm, i);
     }
     if(sDebugThisItem)  {
       iDebugItemsTotal++;
       iDebugItemsThisRound++;
       sDebugBuffer += sDebugThisItem + "\n";
       if(iDebugItemsThisRound >= i_debugPerScreen)  {
         sDebugBuffer = getGlobalDebugging(sDebugBuffer, f_orm);
         alert("---  validate_form.js  DEBUGGING  (" + (iDebugItemsTotal - iDebugItemsThisRound + 1) + " to " + iDebugItemsTotal + " of " + iELEMENT_COUNT + ")  ---\n\n" + sDebugBuffer);
         iDebugItemsThisRound = 0;
         sDebugBuffer = "";
       }
       sDebugThisItem = "";
     }
   }
   if(sDebugBuffer)  {
     sDebugBuffer = getGlobalDebugging(sDebugBuffer, f_orm);
     alert("---  validate_form.js  DEBUGGING  (" + (iDebugItemsTotal - iDebugItemsThisRound + 1) + " to " + iDebugItemsTotal + " of " + iELEMENT_COUNT + ")  ---\n\n" + sDebugBuffer);
   }
 }
 function getGlobalDebugging(s_debugBuffer, f_orm)  {
   if(!bFIRST_DEBUG_SCREEN_SEEN)  {
     bFIRST_DEBUG_SCREEN_SEEN = true;
     var sGlobalDebug = "";
     if(f_orm.asGlobalBadSubStrs)  {
       sGlobalDebug = sDBG_INDENT + "f_orm.asGlobalBadSubStrs=  [ " + f_orm.asGlobalBadSubStrs + " ]\n";
     }
     if(f_orm.bsGlobalTrimSpaces == "true")  {
       sGlobalDebug += sDBG_INDENT + "f_orm.bsGlobalTrimSpaces=  "true"\n";
     }
     if(sGlobalDebug)  {
       return "---  GLOBAL SETTINGS  ---\n" + sGlobalDebug + "\n\n" + s_debugBuffer;
     }
   }
   //Either the first debugging screen has already been displayed, or
   //this is the first screen, but there is no global settings
   return s_debugBuffer;
 }
 function getUserErrors(f_orm, s_prefix)  {
   var sUserErrors = "";
   for(var i = 0; i < f_orm.length; i++)  {
     if(f_orm[i].type == "text"  ||  f_orm[i].type == "password")  {
       sUserErrors += getUserErrors_text(f_orm, i, s_prefix);
     }  else if(f_orm[i].type == "textarea")  {
       sUserErrors += getUserErrors_textarea(f_orm, i, s_prefix);
     }  else if(f_orm[i].type == "checkbox"  ||  f_orm[i].type == "select-multiple")  {
       sUserErrors += getUserErrors_cbsm(f_orm, i, s_prefix);
     }  else if(f_orm[i].type == "radio"  ||  f_orm[i].type == "select-one")  {
       sUserErrors += getUserErrors_rso(f_orm, i, s_prefix);
     }
   }
   return sUserErrors;
 }
 /**
   form_element must be provided, and a form element...START
  **/
   function getDebuggingNameType(form_element)  {
     return "---  " + form_element.name + "  ---          [" + form_element.type + "]\n";
   }
   function getDebuggingMsgRequired(s_msgRequired)  {
     if(s_msgRequired)  {
       return sDBG_INDENT + "sMsgRequired:  "" + s_msgRequired + ""\n";
     }
     return "";
   }
   function getDebuggingValue(s_value)  {
     if(s_value)  {
       return sDBG_INDENT + "VALUE:  "" + s_value + ""\n";
     }
     return "";
   }
 /**
   form_element must be provided, and a form element...END
  **/
 /**
   Do not call this function without first calling crashIfBadCfg_cbsm for the form-and-form-element.
  **/
 function getUserErrors_cbsm(f_orm, i_arrIdx, s_prefix)  {
   var feCbsm = f_orm[i_arrIdx];
   var sMsgRequired = "";
   var sMsgMCRange = "";
   var iMCMin = "";
   var iMCMax = "";
   if(feCbsm.type == "checkbox")  {
     if(getFirstArrIdx(feCbsm.name) != i_arrIdx)  {
       //This checkbox has already had its user errors retrieved.
       return "";
     }
     //This checkbox has not yet had its user errors retrieved.
     sMsgRequired = f_orm[feCbsm.name + ".sMsgRequired"];
     sMsgMCRange = f_orm[feCbsm.name + ".sMsgMCRange"];
     iMCMin = f_orm[feCbsm.name + ".iMCMin"];
     iMCMax = f_orm[feCbsm.name + ".iMCMax"];
   }  else  {
     //this is a select-multiple type...which has not yet had its
     //user errors retrieved.
     sMsgRequired = feCbsm.sMsgRequired
     sMsgMCRange = feCbsm.sMsgMCRange
     iMCMin = feCbsm.iMCMin
     iMCMax = feCbsm.iMCMax
   }
   var iMCSelCount = getMCSelectedCount(feCbsm.name);
   if(sMsgRequired  &&  iMCSelCount < 1)  {
     return s_prefix + sMsgRequired + "\n";
   }
   //If its required, a value has been selected.
   if(iMCSelCount < 1)  {
     //Its not required, and no value has been selected,
     //which is okay.
     return "";
   }
   if((iMCMin  &&  iMCMin > iMCSelCount)  ||
      (iMCMax  &&  iMCMax < iMCSelCount))  {
     return s_prefix + sMsgMCRange + "\n";
   }
   return "";
 }
 /**
   Do not call this function without first calling crashIfBadCfg_cbsm for the form-and-form-element.
  **/
 function getDebugging_cbsm(f_orm, i_arrIdx)  {
   var feCbsm = f_orm[i_arrIdx];
   var sMsgRequired = "";
   var sMsgMCRange = "";
   var iMCMin = "";
   var iMCMax = "";
   if(feCbsm.type == "checkbox")  {
     if(getFirstArrIdx(feCbsm.name) != i_arrIdx)  {
       //This checkbox has already been debugged.
       return "";
     }
     //This checkbox has not yet been debugged
     sMsgRequired = f_orm[feCbsm.name + ".sMsgRequired"];
     sMsgMCRange = f_orm[feCbsm.name + ".sMsgMCRange"];
     iMCMin = f_orm[feCbsm.name + ".iMCMin"];
     iMCMax = f_orm[feCbsm.name + ".iMCMax"];
   }  else  {
     //this is a select-multiple type...which has not yet been debugged.
     sMsgRequired = feCbsm.sMsgRequired
     sMsgMCRange = feCbsm.sMsgMCRange
     iMCMin = feCbsm.iMCMin
     iMCMax = feCbsm.iMCMax
   }
   var s = getDebuggingNameType(feCbsm) + getDebuggingMsgRequired(sMsgRequired);
   if(sMsgMCRange)  {
     s += sDBG_INDENT + "sMsgMCRange:  "" + sMsgMCRange + ""\n";
     if(iMCMin)  {
       s += sDBG_INDENT + sDBG_INDENT + "iMCMin:  " + iMCMin + "\n";
     }
     if(iMCMax)  {
       s += sDBG_INDENT + sDBG_INDENT + "iMCMax:  " + iMCMax + "\n";
     }
   }
   var iMCSelCount = getMCSelectedCount(feCbsm.name);
   if(iMCSelCount > 0)  {
     s += sDBG_INDENT + "NUMBER OF CHOICES SELECTED:  " + iMCSelCount + "\n";
   }
   return s;
 }
 function crashIfBadCfg_cbsm(f_orm, i_arrIdx)  {
   conditionallyAddRCBSM(f_orm, i_arrIdx);
   var feCbsm = f_orm[i_arrIdx];
   var sMsgMCRange = "";
   var iMCMin = "";
   var iMCMax = "";
   var iTotalOptions = -1;
   var sErrVarPre = "";
   var sErrVarPost = "";
   if(feCbsm.type == "checkbox")  {
     if(getFirstArrIdx(feCbsm.name) != i_arrIdx)  {
       //This checkbox has already been validated.
       return "";
     }
     //This checkbox has not yet been validated
     sMsgMCRange = f_orm[feCbsm.name + ".sMsgMCRange"];
     iMCMin = f_orm[feCbsm.name + ".iMCMin"];
     iMCMax = f_orm[feCbsm.name + ".iMCMax"];
     iTotalOptions = f_orm[feCbsm.name].length;
     sErrVarPre = "f_orm["" + feCbsm.name;
     sErrVarPost = ""]";
   }  else  {
     //this is a select-multiple type...which has not yet been validated.
     sMsgMCRange = feCbsm.sMsgMCRange;
     iMCMin = feCbsm.iMCMin;
     iMCMax = feCbsm.iMCMax;
     iTotalOptions = feCbsm.length;
     sErrVarPre = feCbsm.name;
     sErrVarPost = "";
   }
   if(sMsgMCRange)  {
     if(!iMCMin  &&  !iMCMax)  {
       return crashVF(sErrVarPre + ".sMsgMCRange" + sErrVarPost + " has been provided (currently "" + sMsgMCRange + ""), but neither " + sErrVarPre + ".iMCMin" + sErrVarPost + " nor " + sErrVarPre + ".iMCMax" + sErrVarPost + " have been provided.  At least one of these bounds are required.");
     }
     if(iMCMin)  {
       if(!isInteger(iMCMin))  {
         return crashVF(sErrVarPre + ".iMCMin" + sErrVarPost + " has been provided, but is not of type number.  Currently of type "" + typeof(iMCMin) + "" and equal to "" + iMCMin + "".");
       }
       if(iMCMin < 1  ||  iMCMin > iTotalOptions)  {
         return crashVF(sErrVarPre + ".iMCMin" + sErrVarPost + " has been provided (currently " + iMCMin + "), but is either less than one, or greater than the total number of options (" + iTotalOptions + ").");
       }
     }
     if(iMCMax)  {
       if(!isInteger(iMCMax))  {
         return crashVF(sErrVarPre + ".iMCMax" + sErrVarPost + " has been provided, but is not of type number.  Currently of type "" + typeof(iMCMax) + "" and equal to "" + iMCMax + "".");
       }
       if(iMCMax < 1  ||  iMCMax > iTotalOptions)  {
         return crashVF(sErrVarPre + ".iMCMax" + sErrVarPost + " has been provided (currently " + iMCMax + "), but is either less than one, or greater than the total number of options (" + iTotalOptions + ").");
       }
     }
     if(iMCMin  &&  iMCMax  &&  iMCMin > iMCMax)  {
       return crashVF(sErrVarPre + ".sMsgMCRange" + sErrVarPost + " has been provided (currently "" + sMsgMCRange + ""), and both " + sErrVarPre + ".iMCMin" + sErrVarPost + " (currently " + iMCMin + ") and " + sErrVarPre + ".iMCMax" + sErrVarPost + " (currently " + iMCMax + ") have been provided.  However, iMCMin must be less than or equal to iMCMax, which it is not.");
     }
   }  else if(iMCMin  ||  iMCMax)  {
     return crashVF(sErrVarPre + ".sMsgMCRange" + sErrVarPost + " has *not* been provided, but at least one of " + sErrVarPre + ".iMCMin" + sErrVarPost + " (currently "" + iMCMin + "") or " + sErrVarPre + ".iMCMax" + sErrVarPost + " (currently "" + iMCMax + "") has been provided.");
   }
 }
 /**
   Do not call this function without first calling crashIfBadCfg_rso for the form-and-form-element.
  **/
 function getUserErrors_rso(f_orm, i_arrIdx, s_prefix)  {
   var feRso = f_orm[i_arrIdx];
   var sValue = "";
   var sMsgRequired = "";
   if(feRso.type == "radio")  {
     if(getFirstArrIdx(feRso.name) != i_arrIdx)  {
       //We already debugged this radio element.
       return "";
     }
     sMsgRequired = f_orm[feRso.name + ".sMsgRequired"];
     sValue = getRadioValue(f_orm, feRso.name);
   }  else if(feRso.selectedIndex > -1) {
     sMsgRequired = feRso.sMsgRequired;
     sValue = feRso[feRso.selectedIndex].value;
   }
   if(sMsgRequired  &&  !sValue)  {
     return s_prefix + sMsgRequired + "\n";
   }
   //If its required, a value has been provided.
   return "";
 }
 /**
   Do not call this function without first calling crashIfBadCfg_rso for the form-and-form-element.
  **/
 function getDebugging_rso(f_orm, i_arrIdx)  {
   var feRso = f_orm[i_arrIdx];
   var sValue = "";
   var sMsgRequired = "";
   if(feRso.type == "radio")  {
     if(getFirstArrIdx(feRso.name) != i_arrIdx)  {
       //We already debugged this radio element.
       return "";
     }
     sMsgRequired = f_orm[feRso.name + ".sMsgRequired"];
     sValue = getRadioValue(f_orm, feRso.name);
   }  else if(feRso.selectedIndex > -1) {
     sMsgRequired = feRso.sMsgRequired;
     sValue = feRso[feRso.selectedIndex].value;
   }
   return getDebuggingNameType(feRso) + getDebuggingMsgRequired(sMsgRequired) + getDebuggingValue(sValue);
 }
 function getRadioValue(f_orm, s_radioName)  {
   var feRadio = f_orm[s_radioName];
   for(var i = 0; i < feRadio.length; i++)  {
     if(feRadio[i].checked)  {
       return feRadio[i].value;
     }
   }
   return "";
 }
 function crashIfBadCfg_rso(f_orm, i_arrIdx)  {
   var feRso = f_orm[i_arrIdx];
   if(feRso.type == "radio")  {
     conditionallyAddRCBSM(f_orm, i_arrIdx);
   }  else  {
     iELEMENT_COUNT++;
   }
   //Nothing to validate.  The only attribute that
   //can be associated to a radio or select-one type
   //is sMsgRequired...  Which either is or isn"t...
   //doesn"t matter which.
 }
 function conditionallyAddRCBSM(f_orm, i_arrIdx)  {
   var feCbsm = f_orm[i_arrIdx];
   if(wasRCBSMalreadyFound(feCbsm.name))  {
     //We already analyzed this element.
     return;
   }
   iELEMENT_COUNT++;
   addRCBSMtoTracker(f_orm, feCbsm, i_arrIdx);
 }
 /**
   Do not call this function without first calling crashIfBadCfg_textarea for the form-and-form-element.
  **/
 function getUserErrors_textarea(f_orm, i_arrIdx, s_prefix)  {
   var feTA = f_orm[i_arrIdx];
   if(feTA.sMsgRequired  &&  !feTA.value)  {
     return s_prefix + feTA.sMsgRequired + "\n";
   }
   if(!feTA.value)  {
     return "";
   }
   if(needsToBeTrimmed(f_orm, feTA))  {
     feTA.value = trimSpaces(feTA.value);
   }
   if(feTA.sMsgBadLength  &&
      (feTA.value.length < feTA.iMinLength  ||
       feTA.value.length > feTA.iMaxLength))  {
     return s_prefix + getBadLengthMsg(feTA) + "\n";
   }
   return getBadSubStrMessage(feTA.value, f_orm, feTA.asBadSubStrs, feTA.bsNoBadSubStrings, s_prefix, feTA.sMsgBadSubStr);
 }
 function getBadLengthMsg(fe_tta)  {
   var sMsg = fe_tta.sMsgBadLength;
   var iCLArrIdx = sMsg.indexOf(sCURRENT_LENGTH_FOR_TA);
   if(iCLArrIdx != -1)  {
     sMsg = sMsg.substring(0, iCLArrIdx) + fe_tta.value.length + sMsg.substring((iCLArrIdx + sCURRENT_LENGTH_FOR_TA.length), (sMsg.length + 1));
   }
   return sMsg;
 }
 function getBadSubStrMessage(s_value, f_orm, as_badSubStrs, bs_noBadSubStrings, s_prefix, s_errorMessage)  {
   if(!s_value)  {
     //Theres no value, so it can"t have any illegal sub-string.
     return "";
   }
   if(bs_noBadSubStrings == "true")  {
     //This element is exempt.
     return "";
   }
   //"x" is important...1/2
   var asBadSubStrs = "x";
   if(f_orm.asGlobalBadSubStrs)  {
     asBadSubStrs = f_orm.asGlobalBadSubStrs;
   }
   if(as_badSubStrs)  {
     asBadSubStrs = as_badSubStrs;
   }
   //"x" is important...2/2
   if(asBadSubStrs == "x")  {
     //There are no sub-strings to consider illegal.
     return "";
   }
   //There *are* sub-strings to be considered illegal.
   for(var i = 0; i < asBadSubStrs.length; i++)  {
     if(s_value.indexOf(asBadSubStrs[i]) != -1)  {
       return s_prefix + s_errorMessage + "\n";
     }
   }
   return "";
 }
 /**
   Do not call this function without first calling crashIfBadCfg_textarea for the form-and-form-element.
  **/
 function getDebugging_textarea(f_orm, fe_textarea)  {
   var s = getDebuggingNameType(fe_textarea) + getDebuggingMsgRequired(fe_textarea.sMsgRequired);
   if(fe_textarea.bsNoBadSubStrings == "true")  {
     s += sDBG_INDENT + "bsNoBadSubStrings:  "" + fe_textarea.bsNoBadSubStrings + ""\n";
   }  else if(f_orm.asGlobalBadSubStrs  ||  fe_textarea.asBadSubStrs)  {
     if(fe_textarea.asBadSubStrs)  {
       s += sDBG_INDENT + "asBadSubStrs:  [" + fe_textarea.asBadSubStrs + "]\n";
     }  else if(f_orm.asGlobalBadSubStrs)  {
       s += sDBG_INDENT + "f_orm.asGlobalBadSubStrs:  [" + f_orm.asGlobalBadSubStrs + "]\n";
     }
     s += sDBG_INDENT + sDBG_INDENT + "sMsgBadSubStr:  "" + fe_textarea.sMsgBadSubStr + ""\n";
   }
   if(fe_textarea.sMsgBadLength)  {
     s += sDBG_INDENT + "sMsgBadLength:  "" + fe_textarea.sMsgBadLength + ""\n";
     if(fe_textarea.iMinLength)  {
       s += sDBG_INDENT + sDBG_INDENT + "iMinLength:  " + fe_textarea.iMinLength + "\n";
     }
     if(fe_textarea.iMaxLength)  {
       s += sDBG_INDENT + sDBG_INDENT + "iMaxLength:  " + fe_textarea.iMaxLength + "\n";
     }
   }
   s += getDebuggingValue(fe_textarea.value);
   return s;
 }
 function crashIfBadCfg_textarea(f_orm, fe_textarea)  {
   crashIfMissing(fe_textarea, "fe_textarea", "validate_form.crashIfBadCfg_textarea");
   if(fe_textarea.type != "textarea")  {
     return crashVF("fe_textarea must be of type "text".  Currently "" + fe_textarea.type + ""...SANITY CHECK.  SHOULD NEVER HAPPEN.");
   }
   iELEMENT_COUNT++;
   var sName = sName;
   fe_textarea.bsNoBadSubStrings = getOptBooleanStringVF(fe_textarea.bsNoBadSubStrings, "f_orm." + sName + ".bsNoBadSubStrings");
   crashIfNBSSError(sName, fe_textarea.bsNoBadSubStrings, f_orm.asGlobalBadSubStrs, fe_textarea.asBadSubStrs);
   if(fe_textarea.bsNoBadSubStrings == "false"  &&
     (f_orm.asGlobalBadSubStrs  ||  fe_textarea.asBadSubStrs)  &&
     !fe_textarea.sMsgBadSubStr)  {
     return crashVF("Either f_orm.asGlobalBadSubStrs (currently [" + f_orm.asGlobalBadSubStrs + "]) or f_orm." + sName + ".asBadSubStrs (currently [" + fe_textarea.asBadSubStrs + "]) have  been provided, AND f_orm." + sName + ".bsNoBadSubStrings equals "false" (meaning there are sub-strings that are illegal for this field).  This means that f_orm." + sName + ".sMsgBadSubStr is required.  However, f_orm." + sName + ".sMsgBadSubStr has not been provided.");
   }
   crashIfBadSpaceTrimConfig(f_orm, fe_textarea);
   var iMin = fe_textarea.iMinLength;
   var iMax = fe_textarea.iMaxLength;
   if(fe_textarea.sMsgBadLength)  {
     if(!iMin  &&  !iMax)  {
       return crashVF("f_orm." + sName + ".sMsgBadLength has been provided (currently "" + fe_textarea.sMsgBadLength + ""), but neither f_orm." + sName + ".iMinLength nor f_orm." + sName + ".iMaxLength have been provided.");
     }
     if(iMin  &&  (!isInteger(iMin)  ||  iMin < 1))  {
       return crashVF("Both f_orm." + sName + ".sMsgBadLength (currently "" + fe_textarea.sMsgBadLength + "") and f_orm." + sName + ".iMinLength (currently " + iMin + ") have been provided, but iMinLength must be an integer, and at least equal to one.  Additional information:  f_orm." + sName + ".iMaxLength currently equals " + iMax + ".");
     }
     if(iMax  &&  (!isInteger(iMax)  ||  iMax < 1))  {
       return crashVF("Both f_orm." + sName + ".sMsgBadLength (currently "" + fe_textarea.sMsgBadLength + "") and f_orm." + sName + ".iMaxLength (currently "" + iMax + "") have been provided, but iMaxLength must be an integer, and at least equal to one.  Additional information:  f_orm." + sName + ".iMinLength currently equals " + iMin + ".");
     }
     if(iMin  &&  iMax  &&  iMin > iMax)  {
       return crashVF("f_orm." + sName + ".sMsgBadLength (currently "" + fe_textarea.sMsgBadLength + ""), f_orm." + sName + ".iMinLength (currently " + iMin + ") and f_orm." + sName + ".iMaxLength (currently " + iMax + ") have all been provided, but iMinLength must be less than or equal to iMaxLength.");
     }
   }  else if(iMin  ||  iMax)  {
     return crashVF("f_orm." + sName + ".sMsgBadLength has *not* been provided, but at least one of f_orm." + sName + ".iMinLength (currently " + iMin + ") and f_orm." + sName + ".iMaxLength (currently " + iMax + ") have been provided.");
   }
 }
 /**
   Do not call this function without first calling crashIfBadCfg_textarea for the form-and-form-element.
  **/
 function getUserErrors_text(f_orm, i_arrIdx, s_prefix)  {
   var feText = f_orm[i_arrIdx];
   if(needsToBeTrimmed(f_orm, feText))  {
     feText.value = trimSpaces(feText.value);
   }
   if(feText.sMsgRequired  &&  !feText.value)  {
     return s_prefix + feText.sMsgRequired + "\n";
   }
   if(!feText.value)  {
     return "";
   }
   //It is assumed/expected that there is only one "sMsgTxt"
   //variables associated to feText.  The only reason that
   //the following ifs are not else-ifs, is because of the
   //for loop of eval statements.
   if(feText.sMsgTxtEmail)  {
     if(!isEmail(feText.value))  {
       return s_prefix + feText.sMsgTxtEmail + "\n";
     }
   }  else if(feText.sMsgTxtInt)  {
     if(!isInteger(feText.value)  ||
        (feText.iIntMin  &&  feText.iIntMin > feText.value)  ||
        (feText.iIntMax  &&  feText.iIntMax < feText.value))  {
       return s_prefix + feText.sMsgTxtInt + "\n";
     }
   }  else if(feText.sMsgTxtDec)  {
     if(!isDecimal(feText.value)  ||
        (feText.iDecMin  &&  feText.iDecMin > feText.value)  ||
        (feText.iDecMax  &&  feText.iDecMax < feText.value))  {
       return s_prefix + feText.sMsgTxtDec + "\n";
     }
   }  else if(feText.sMsgTxtPhone)  {
     var sPhoneStripped = getValidPhone1(feText.value);
     if(!sPhoneStripped)  {
       return s_prefix + feText.sMsgTxtPhone + "\n";
     }
     feText.value = sPhoneStripped;
   }  else if(feText.sMsgTxtZip)  {
     var sZipStripped = getValidZip1(feText.value);
     if(!sZipStripped)  {
       return s_prefix + feText.sMsgTxtZip + "\n";
     }
     feText.value = sZipStripped;
   }  else  {
     for(var i = 1; i < 11; i++)  {
       if(eval("feText.sMsgTxtPhone" + i))  {
         var sPhoneStripped = eval("getValidPhone" + i + "(feText.value)");
         if(!sPhoneStripped)  {
           return s_prefix + eval("feText.sMsgTxtPhone" + i) + "\n";
         }
         feText.value = sPhoneStripped;
         break;    //There is only one sMsgTxt* per element
       }
       if(eval("feText.sMsgTxtZip" + i))  {
         var sZipStripped = eval("getValidZip" + i + "(feText.value)");
         if(!sZipStripped)  {
           return s_prefix + eval("feText.sMsgTxtZip" + i) + "\n";
         }
         feText.value = sZipStripped;
         break;    //There is only one sMsgTxt* per element
       }
     }
   }
   if(feText.sMsgBadLength  &&  feText.value.length < feText.iMinLength)  {
     return s_prefix + getBadLengthMsg(feText) + "\n";
   }
   return getBadSubStrMessage(feText.value, f_orm, feText.asBadSubStrs, feText.bsNoBadSubStrings, s_prefix, feText.sMsgBadSubStr);
 }
 function needsToBeTrimmed(f_orm, fe_tta)  {
   if(!fe_tta.value)  {
     return false;
   }
   if(fe_tta.bsDontTrimSpaces == "true")  {
     return false;
   }
   if(f_orm.bsGlobalTrimSpaces == "true"  ||  fe_tta.bsTrimSpaces == "true")  {
     return isSurroundedBySpace(fe_tta.value);
   }
 }
 /**
   Do not call this function without first calling crashIfBadCfg_text for the form-and-form-element.
  **/
 function getDebugging_text(f_orm, fe_text)  {
   var sDBG_INDENT = "     ";
   var s = getDebuggingNameType(fe_text) + getDebuggingMsgRequired(fe_text.sMsgRequired);
   var bEM = fe_text.sMsgTxtEmail;
   var bInt = fe_text.sMsgTxtInt;
   var bDec = fe_text.sMsgTxtDec;
   var bZC = fe_text.sMsgTxtZip;
   var bZC1 = fe_text.sMsgTxtZip1;
   var bZC2 = fe_text.sMsgTxtZip2;
   var bZC3 = fe_text.sMsgTxtZip3;
   var bZC4 = fe_text.sMsgTxtZip4;
   var bZC5 = fe_text.sMsgTxtZip5;
   var bZC6 = fe_text.sMsgTxtZip6;
   var bZC7 = fe_text.sMsgTxtZip7;
   var bZC8 = fe_text.sMsgTxtZip8;
   var bZC9 = fe_text.sMsgTxtZip9;
   var bZC10 = fe_text.sMsgTxtZip10;
   var bPN = fe_text.sMsgTxtPhone;
   var bPN1 = fe_text.sMsgTxtPhone1;
   var bPN2 = fe_text.sMsgTxtPhone2;
   var bPN3 = fe_text.sMsgTxtPhone3;
   var bPN4 = fe_text.sMsgTxtPhone4;
   var bPN5 = fe_text.sMsgTxtPhone5;
   var bPN6 = fe_text.sMsgTxtPhone6;
   var bPN7 = fe_text.sMsgTxtPhone7;
   var bPN8 = fe_text.sMsgTxtPhone8;
   var bPN9 = fe_text.sMsgTxtPhone9;
   var bPN10 = fe_text.sMsgTxtPhone10;
   if(bEM)  {
     s += sDBG_INDENT + "sMsgTxtEmail:  "" + fe_text.sMsgTxtEmail + ""\n";
   }
   if(bZC)  {
     s += sDBG_INDENT + "sMsgTxtZip:  "" + fe_text.sMsgTxtZip + ""\n";
   }
   if(bPN)  {
     s += sDBG_INDENT + "sMsgTxtPhone:  "" + fe_text.sMsgTxtPhone + ""\n";
   }
   for(var i = 1; i < 11; i++)  {
     if(eval("bPN" + i))  {
       s += sDBG_INDENT + "sMsgTxtPhone" + i + ":  "" + eval("fe_text.sMsgTxtPhone" + i) + ""\n";
     }
     if(eval("bZC" + i))  {
       s += sDBG_INDENT + "sMsgTxtZip" + i + ":  "" + eval("fe_text.sMsgTxtZip" + i) + ""\n";
     }
   }
   if(bInt)  {
     s += sDBG_INDENT + "sMsgTxtInt:  "" + fe_text.sMsgTxtInt + ""\n";
     if(fe_text.iIntMin)  {
       s += sDBG_INDENT + sDBG_INDENT + "iIntMin:  "" + fe_text.iIntMin + ""\n";
     }
     if(fe_text.iIntMax)  {
       s += sDBG_INDENT + sDBG_INDENT + "iIntMax:  "" + fe_text.iIntMax + ""\n";
     }
   }
   if(bDec)  {
     s += sDBG_INDENT + "sMsgTxtDec:  "" + fe_text.sMsgTxtDec + ""\n";
     if(fe_text.iDecMin)  {
       s += sDBG_INDENT + sDBG_INDENT + "iDecMin:  "" + fe_text.iDecMin + ""\n";
     }
     if(fe_text.iDecMax)  {
       s += sDBG_INDENT + sDBG_INDENT + "iDecMax:  "" + fe_text.iDecMax + ""\n";
     }
   }
   if(fe_text.bsNoBadSubStrings == "true")  {
     s += sDBG_INDENT + "bsNoBadSubStrings:  "" + fe_text.bsNoBadSubStrings + ""\n";
   }  else if(!bInt  &&  !bDec  &&
                  !bZC   &&  !bZC1  &&  !bZC2  &&  !bZC3  &&  !bZC4  &&  !bZC5  &&
                  !bZC6  &&  !bZC7  &&  !bZC8  &&  !bZC9  &&  !bZC10  &&
                  !bPN   &&  !bPN1  &&  !bPN2  &&  !bPN3  &&  !bPN4  &&  !bPN5  &&
                  !bPN6  &&  !bPN7  &&  !bPN8  &&  !bPN9  &&  !bPN10  &&
              (f_orm.asGlobalBadSubStrs  ||  fe_text.asBadSubStrs))  {
     var sSecondIndent = "";
     if(fe_text.asBadSubStrs)  {
       s += sDBG_INDENT + "asBadSubStrs:  [" + fe_text.asBadSubStrs + "]\n";
       sSecondIndent = sDBG_INDENT;
     }
   }
   if(fe_text.sMsgBadLength)  {
     s += sDBG_INDENT + "sMsgBadLength:  "" + fe_text.sMsgBadLength + ""\n" + sDBG_INDENT + sDBG_INDENT + "iMinLength:  " + fe_text.iMinLength + "\n";
     if(fe_text.maxLength)  {
       s += sDBG_INDENT + sDBG_INDENT + "MAXLENGTH:  " + fe_text.MAXLENGTH + "\n";
     }
   }
   s += getDebuggingValue(fe_text.value);
   return s;
 }
 function crashIfBadCfg_text(f_orm, fe_text)  {
   crashIfMissing(fe_text, "fe_text", "validate_form.crashIfBadCfg_text");
   if(fe_text.type != "text"  &&  fe_text.type != "password")  {
     return crashVF("fe_text must be of type "text" or "password".  Currently "" + fe_text.type + ""...SANITY CHECK.  SHOULD NEVER HAPPEN.");
   }
   var sName = fe_text.name;
   iELEMENT_COUNT++;
   var bEM = fe_text.sMsgTxtEmail;
   var bInt = fe_text.sMsgTxtInt;
   var bDec = fe_text.sMsgTxtDec;
   var bZC = fe_text.sMsgTxtZip;
   var bPN = fe_text.sMsgTxtPhone;
   var iSpecialTypes = 0;
   var sSpecialTypes = "";
   if(bEM)  {
     iSpecialTypes++;
     sSpecialTypes += "sMsgTxtEmail...";
   }
   if(bInt)  {
     iSpecialTypes++;
     sSpecialTypes += "sMsgTxtInt...";
     crashIfBadIntDecCfg(fe_text.iIntMin, fe_text.iIntMax, "false", sName, "iIntMin", "iIntMax");
   }  else if(fe_text.iIntMin  ||  fe_text.iIntMax)  {
     return crashVF("f_orm." + sName + ".sMsgTxtInt has *not* been provided, but one or both of the sub-variables " + sName + ".iIntMin (currently "" + fe_text.iIntMin + "")/" + sName + ".iIntMax (currently "" + fe_text.iIntMax + "") have been provided.");
   }
   if(bDec)  {
     iSpecialTypes++;
     sSpecialTypes += "sMsgTxtDec...";
     crashIfBadIntDecCfg(fe_text.iDecMin, fe_text.iDecMax, "true", sName, "iDecMin", "iDecMax");
   }  else if(fe_text.iDecMin  ||  fe_text.iDecMax)  {
     return crashVF("f_orm." + sName + "." + sAnIntADec + " has *not* been provided, but one or both of the sub-variables " + sName + ".iDecMin (currently "" + fe_text.iDecMin + "")/" + sName + ".iDecMax (currently "" + fe_text.iDecMax + "") have been provided.");
   }
   if(bPN)  {
     iSpecialTypes++;
     sSpecialTypes += "sMsgTxtPhone...";
   }
   for(var i = 1; i < 11; i++)  {
     eval("var bPN" + i + " = fe_text.sMsgTxtPhone" + i);
     if(eval("bPN" + i))  {
       iSpecialTypes++;
       sSpecialTypes += "sMsgTxtPhone" + i + "...";
     }
   }
   if(bZC)  {
     iSpecialTypes++;
     sSpecialTypes += "sMsgTxtZip...";
   }
   for(var i = 1; i < 11; i++)  {
     eval("var bZC" + i + " = fe_text.sMsgTxtZip" + i);
     if(eval("bZC" + i))  {
       iSpecialTypes++;
       sSpecialTypes += "sMsgTxtZip" + i + "...";
     }
   }
   if(iSpecialTypes > 1)  {
     return crashVF("f_orm." + sName + " is of type "text", but has " + iSpecialTypes + " special text types associated to it.  Zero or one of the following special types may be used for a text form element:  sMsgTxtEmail, sMsgTxtInt, sMsgTxtDec, sMsgTxtZip, sMsgTxtZip1, sMsgTxtZip2, sMsgTxtZip3, sMsgTxtZip4, sMsgTxtZip5, sMsgTxtZip6, sMsgTxtZip7, sMsgTxtZip8, sMsgTxtZip9, sMsgTxtZip10, sMsgTxtPhone, sMsgTxtPhone1, sMsgTxtPhone2, sMsgTxtPhone3, sMsgTxtPhone4, sMsgTxtPhone5, sMsgTxtPhone6, sMsgTxtPhone7, sMsgTxtPhone8, sMsgTxtPhone9, sMsgTxtPhone10.\n\nActually existing special types found:  " + sSpecialTypes);
   }
   crashIfBadBSSA("f_orm." + sName + ".asBadSubStrs", fe_text.asBadSubStrs);
   fe_text.bsNoBadSubStrings = getOptBooleanStringVF(fe_text.bsNoBadSubStrings, "f_orm." + sName + ".bsNoBadSubStrings");
   crashIfNBSSError(sName, fe_text.bsNoBadSubStrings, f_orm.asGlobalBadSubStrs, fe_text.asBadSubStrs);
   if(fe_text.bsNoBadSubStrings == "false"  &&  !bInt  &&  !bDec  &&
        !bZC   &&  !bZC1  &&  !bZC2  &&  !bZC3  &&  !bZC4  &&  !bZC5  &&
        !bZC6  &&  !bZC7  &&  !bZC8  &&  !bZC9  &&  !bZC10  &&
        !bPN   &&  !bPN1  &&  !bPN2  &&  !bPN3  &&  !bPN4  &&  !bPN5  &&
        !bPN6  &&  !bPN7  &&  !bPN8  &&  !bPN9  &&  !bPN10  &&
     (f_orm.asGlobalBadSubStrs  ||  fe_text.asBadSubStrs)  &&
     !fe_text.sMsgBadSubStr)  {
     return crashVF("Either f_orm.asGlobalBadSubStrs (currently [" + f_orm.asGlobalBadSubStrs + "]) or f_orm." + sName + ".asBadSubStrs (currently [" + fe_text.asBadSubStrs + "]) have  been provided, AND f_orm." + sName + ".bsNoBadSubStrings equals "false" (meaning there are sub-strings that are illegal for this field) AND this text/password field does not have a "number" special type (sMsgTxtInt, sMsgTxtDec, sMsgTxtZip, sMsgTxtZip1, sMsgTxtZip2, sMsgTxtZip3, sMsgTxtZip4, sMsgTxtZip5, sMsgTxtZip6, sMsgTxtZip7, sMsgTxtZip8, sMsgTxtZip9, sMsgTxtZip10, sMsgTxtPhone, sMsgTxtPhone1, sMsgTxtPhone2, sMsgTxtPhone3, sMsgTxtPhone4, sMsgTxtPhone5, sMsgTxtPhone6, sMsgTxtPhone7, sMsgTxtPhone8, sMsgTxtPhone9, sMsgTxtPhone10).  This means that f_orm." + sName + ".sMsgBadSubStr is required.  However, f_orm." + sName + ".sMsgBadSubStr has not been provided.");
   }
   crashIfBadSpaceTrimConfig(f_orm, fe_text);
   var bIsSpecial = (bEM  ||  bInt  || bDec  ||
     bZC   ||  bZC1  ||  bZC2  ||  bZC3  ||  bZC4  ||  bZC5  ||
      bZC6  ||  bZC7  ||  bZC8  ||  bZC9  ||  bZC10  ||
      bPN   ||  bPN1  ||  bPN2  ||  bPN3  ||  bPN4  ||  bPN5  ||
      bPN6  ||  bPN7  ||  bPN8  ||  bPN9  ||  bPN10);
   if(bIsSpecial  &&
     (fe_text.bsTrimSpaces == "true"  ||  fe_text.bsDontTrimSpaces == "true"))  {
     return crashVF("Either f_orm." + sName + ".bsTrimSpaces (currently "" + fe_text.bsTrimSpaces + "") or f_orm." + sName + ".bsDontTrimSpaces (currently "" + fe_text.bsTrimSpaces + "") equal "true".  But this is illegal, because the element has these special types associated to it:  " + sSpecialTypes);
   }
   var iMin = fe_text.iMinLength;
   if(fe_text.sMsgBadLength)  {
     if(!iMin)  {
       return crashVF("f_orm." + sName + ".sMsgBadLength has been provided (currently "" + fe_text.sMsgBadLength + ""), but f_orm." + sName + ".iMinLength has not been provided");
     }
     if(iMin  &&  (!isInteger(iMin)  ||  iMin < 1))  {
       return crashVF("Both f_orm." + sName + ".sMsgBadLength (currently "" + fe_text.sMsgBadLength + "") and f_orm." + sName + ".iMinLength (currently "" + iMin + "") have been provided, but iMinLength must be an integer, and at least equal to one.");
     }
     //NOTE:  When MAXLENGTH is an attribute of the element,
     //fe_text.MAXLENGTH is undefined, but fe_text.maxLength
     //is not.  Things that make you go hmm.
     if(fe_text.maxLength  &&  fe_text.maxLength != -1  &&
        isInteger(fe_text.maxLength)  &&  iMin > fe_text.maxLength)  {
       return crashVF("Both f_orm." + sName + ".sMsgBadLength (currently "" + fe_text.sMsgBadLength + "") and f_orm." + sName + ".iMinLength (currently " + iMin + ") have been provided, but iMinLength must be an integer between one and f_orm." + sName + ".MAXLENGTH (currently " + fe_text.maxLength + "), inclusive.");
     }
   }  else if(iMin)  {
     return crashVF("f_orm." + sName + ".sMsgBadLength has *not* been provided, but the sub-attribute f_orm." + sName + ".iMinLength (currently " + iMin + ") has been provided.");
   }
   if(fe_text.iMaxLength)  {
     return crashVF("f_orm." + sName + ".iMaxLength (currently " + fe_text.iMaxLength + ") is only a legal sub-attribute for text elements.  To enforce maximum length in a text or password element, use the standard MAXLENGTH attribute.");
   }
 }
 //"di_" prefix stands for decimal-or-integer
 function crashIfBadIntDecCfg(di_min, di_max, bs_decimalAllowed, s_formLmntName, s_nameMin, s_nameMax)  {
   var sIntDecPostfix = "Int";
   var sAnIntADec = "an integer";
   var sIntDec = "integer";
   var sIsFuncName = "isInteger";
   if(bs_decimalAllowed == "true")  {
     sIntDecPostfix = "Dec";
     sAnIntADec = "a decimal";
     sIntDec = "decimal";
     sIsFuncName = "isDecimal";
   }
   if(di_min  &&  !isNumber(di_min, bs_decimalAllowed))  {
     return crashVF("f_orm." + s_formLmntName + ".sMsgTxt" + sIntDecPostfix + " has been provided, and the sub-variable " + s_formLmntName + "." + s_nameMin + " has also been provided.  However, " + s_nameMin + " must be " + sAnIntADec + ".  Currently "" + di_min + "".");
   }
   if(di_max  &&  !isNumber(di_max, bs_decimalAllowed))  {
     return crashVF("f_orm." + s_formLmntName + ".sMsgTxt" + sIntDecPostfix + " has been provided, and the sub-variable " + s_formLmntName + "." + s_nameMax + " has also been provided.  However, " + s_nameMax + " must be " + sAnIntADec + ".  Currently "" + di_max + "".");
   }
   if(di_min  &&  di_max  &&
     !isValidRange(di_min, di_max))  {
     return crashVF("f_orm." + s_formLmntName + ".sMsgTxt" + sIntDecPostfix + " has been provided, and both the sub-variables " + s_formLmntName + "." + s_nameMin + " and " + s_formLmntName + "." + s_nameMax + " have also been provided.  Both these variables are definitely legal " + sIntDec + "s (according to util_string." + sIsFuncName + "()), however, " + s_nameMin + " (currently "" + di_min + "") and " + s_nameMax + " (currently "" + di_max + "") are not a legal range according to util_number.isValidRange().");
   }
 }
 function crashIfBadSpaceTrimConfig(f_orm, fe_tta)  {
   fe_tta.bsTrimSpaces = getOptBooleanStringVF(fe_tta.bsTrimSpaces, "f_orm." + fe_tta.name + ".bsTrimSpaces");
   fe_tta.bsDontTrimSpaces = getOptBooleanStringVF(fe_tta.bsDontTrimSpaces, "f_orm." + fe_tta.name + ".bsDontTrimSpaces");
   if(f_orm.bsGlobalTrimSpaces == "true")  {
     if(fe_tta.bsTrimSpaces == "true")  {
       return crashVF("Both f_orm.bsGlobalTrimSpaces and f_orm." + fe_tta.name + ".bsTrimSpaces equal "true".  Only one of these variables may be "true".");
     }
   }  else  if(fe_tta.bsDontTrimSpaces == "true")  {
     return crashVF("f_orm.bsGlobalTrimSpaces has *not* been provided (or is equal to "false"), but f_orm." + fe_tta.name + ".bsDontTrimSpaces equals "true".  ");
   }
 }
 function crashIfNBSSError(s_textPwName, b_noBadSubStrings, as_globalBadSubStrs, as_badSubStrs)  {
   if(b_noBadSubStrings == "true"  &&
      (as_badSubStrs  ||  !as_globalBadSubStrs))  {
     return crashVF("f_orm." + s_textPwName + ".bsNoBadSubStrings equals "true", but either , f_orm.asGlobalBadSubStrs has *not* been provided (currently " + as_globalBadSubStrs + ") or f_orm." + s_textPwName + ".asBadSubStrs *has* been provided (currently " + as_badSubStrs + ").  When bsNoBadSubStrings equals "true", it is required that or asBadSubStrs not be provided and f_orm.asGlobalBadSubStrs should be provided.");
   }
 }
 function getRqdMissingMsg(s_requiredMsg, s_value)  {
   crashIfMissing(s_value, "s_value ("missing" means empty string)", "validate_form.getRqdMissingMsg");
   if(!s_requiredMsg)  {
     //This value is not required.
     return "";
   }
   //This value *is* required...
   if(s_value == "")  {
     //...but has not been provided.
     return s_requiredMsg;
   }
   //...and has been provided.
   return "";
 }
 /**
   Crash If the provided bad-sub-string-array is bad.
  **/
 function crashIfBadBSSA(s_variableName, as_badSubStrs)  {
   if(!as_badSubStrs)  {
     return;
   }
   var sRule = " is not required, but when it is provided, it must be of type array, at least one element in length, and each element must be of type string, at least one character in length, and all elements must be unique.  Currently, ";
   if(!isArray(as_badSubStrs))  {
     return crashVF("crashIfBadBSSA:  " + s_variableName + sRule + "it is of type "" + typeof(as_badSubStrs) + "".");
   }
   if(as_badSubStrs.length < 1)  {
     return crashVF("crashIfBadBSSA:  " + s_variableName + sRule + "it is zero elements in length.");
   }
   for(var i = 0; i < as_badSubStrs.length; i++)  {
     if(typeof(as_badSubStrs[i]) != "string")  {
       return crashVF("crashIfBadBSSA:  " + s_variableName + sRule + " s_variableName[" + i + "] is of type "" + typeof(as_badSubStrs[i]) + "".");
     }
     if(as_badSubStrs[i].length < 1)  {
       return crashVF("crashIfBadBSSA:  " + s_variableName + sRule + " s_variableName[" + i + "] is zero characters in length.");
     }
     for(var j = i + 1; j < as_badSubStrs.length; j++)  {
       if(as_badSubStrs[i] == as_badSubStrs[j])  {
         return crashVF("crashIfBadBSSA:  " + s_variableName + sRule + " Element " + i + " (currently "" + as_badSubStrs[i] + "") is equal to element " + j + ".");
       }
     }
   }
   //All elements are definitely of type string.
   for(var i = 0; i < as_badSubStrs.length; i++)  {
     for(var j = i + 1; j < as_badSubStrs.length; j++)  {
       if(as_badSubStrs[i] == as_badSubStrs[j])  {
         return crashVF("crashIfBadBSSA:  " + s_variableName + sRule + " Element " + i + " (currently "" + as_badSubStrs[i] + "") is equal to element " + j + ".");
       }
     }
   }
 }
 function  wasRCBSMalreadyFound(s_elementName)  {
   return (getRCBSMTrackerArrIdx(s_elementName) != -1);
 }
 function  getFirstArrIdx(s_elementName)  {
   var iArrIdx = getAndValidateRCBSMTArrIdx("getFirstArrIdx", s_elementName);
   var iFirstArrIdx = aiRCBSM_TRACKER_ARR_IDX[iArrIdx];
   if(iFirstArrIdx == -1)  {
     return crashVF("getFirstArrIdx:  Element named "" + s_elementName + "" *was* found in the tracker array objects, but it is of type select-multiple, which does not have multiple instances, and is therefore invalid for this function.  SANITY CHECK.  SHOULD NEVER HAPPEN.");
   }
   return iFirstArrIdx;
 }
 function  getMCSelectedCount(s_elementName)  {
   var iArrIdx = getAndValidateRCBSMTArrIdx("getMCSelectedCount", s_elementName);
   var iSelCt = aiRCBSM_TRACKER_SEL_COUNT[iArrIdx];
   if(iSelCt == -1)  {
     return crashVF("getMCSelectedCount:  Element named "" + s_elementName + "" *was* found in the tracker array objects, but it is of type radio, which is a single-choice element, and is therefore invalid for this function.  SANITY CHECK.  SHOULD NEVER HAPPEN.");
   }
   return iSelCt;
 }
 function getAndValidateRCBSMTArrIdx(s_callingFunction, s_elementName)  {
   var iArrIdx = getRCBSMTrackerArrIdx(s_elementName);
   if(iArrIdx == -1)  {
     return crashVF("getAndValidateRCBSMTArrIdx ("" + s_callingFunction + ""):  Element named "" + s_elementName + "" was not found in the tracker array objects.  SANITY CHECK.  SHOULD NEVER HAPPEN.");
   }
   return iArrIdx;
 }
 function  getRCBSMTrackerArrIdx(s_elementName)  {
   for(var i = 0; i < asRCBSM_TRACKER_NAME.length; i++)  {
     if(asRCBSM_TRACKER_NAME[i] == s_elementName)  {
       return i;
     }
   }
   return -1;
 }
 function addRCBSMtoTracker(f_orm, fe_rcbsm, i_formArrIdx)  {
   if(asRCBSM_TRACKER_NAME.length < 1)  {
     //This is the first to be tracked.  Just create a new
     //array containing this name as the only element.
     asRCBSM_TRACKER_NAME = [fe_rcbsm.name];
     aiRCBSM_TRACKER_SEL_COUNT = [getMCSelectedCountForTracker(f_orm, fe_rcbsm)];
     aiRCBSM_TRACKER_ARR_IDX = [getRCBSMFirstArrIdx(fe_rcbsm, i_formArrIdx)];
     return;
   }
   //At least one element is already being tracked.  Add this
   //element to the existing tracking arrays.
   if(wasRCBSMalreadyFound(fe_rcbsm.name))  {
     return crashVF("addRCBSMtoTracker:  Element named "" + fe_rcbsm.name + "" already exists in the TRACKER arrays.  SANITY CHECK.  SHOULD NEVER HAPPEN.");
   }
   var asTrackerNames = new Array(asRCBSM_TRACKER_NAME.length + 1);
   for(var i = 0; i < asTrackerNames.length; i++)  {
     if(i < (asTrackerNames.length - 1))  {
       asTrackerNames[i] = asRCBSM_TRACKER_NAME[i];
     }  else  {
       asTrackerNames[i] = fe_rcbsm.name;
     }
   }
   asRCBSM_TRACKER_NAME = asTrackerNames;
   var aiTrackerCounts = new Array(aiRCBSM_TRACKER_SEL_COUNT.length + 1);
   for(var i = 0; i < aiTrackerCounts.length; i++)  {
     if(i < (aiTrackerCounts.length - 1))  {
       aiTrackerCounts[i] = aiRCBSM_TRACKER_SEL_COUNT[i];
     }  else  {
       aiTrackerCounts[i] = getMCSelectedCountForTracker(f_orm, fe_rcbsm);
     }
   }
   aiRCBSM_TRACKER_SEL_COUNT = aiTrackerCounts;
   var aiTrackerArrIdx = new Array(aiRCBSM_TRACKER_ARR_IDX.length + 1);
   for(var i = 0; i < aiTrackerArrIdx.length; i++)  {
     if(i < (aiTrackerArrIdx.length - 1))  {
       aiTrackerArrIdx[i] = aiRCBSM_TRACKER_ARR_IDX[i];
     }  else  {
       aiTrackerArrIdx[i] = getRCBSMFirstArrIdx(fe_rcbsm, i_formArrIdx);
     }
   }
   aiRCBSM_TRACKER_ARR_IDX = aiTrackerArrIdx;
 }
 function getRCBSMFirstArrIdx(fe_rcbsm, i_formArrIdx)  {
   if(fe_rcbsm.type == "select-multiple")  {
     //select-multiple only has one instance in the form.  -1 indicates that.
     return -1;
   }
   return i_formArrIdx;
 }
 function getMCSelectedCountForTracker(f_orm, fe_rcbsm)  {
   if(fe_rcbsm.type != "radio"  &&
      fe_rcbsm.type != "checkbox"  &&
      fe_rcbsm.type != "select-multiple")  {
     return crashVF("getMCSelectedCount:  Element named "" + fe_rcbsm.name + "" is not of type radio, checkbox or select-multiple.  Type of this element is "" + fe_rcbsm.type + "".  SANITY CHECK.  SHOULD NEVER HAPPEN.");
   }
   if(fe_rcbsm.type == "radio")  {
     //This is not a multiple choice type.  -1 indicates that.
     return -1;
   }
   var iMCSelectedCount = 0;
   if(fe_rcbsm.type == "checkbox")  {
     for(var i = 0; i < f_orm[fe_rcbsm.name].length; i++)  {
       if(f_orm[fe_rcbsm.name][i].checked)  {
         iMCSelectedCount++;
       }
     }
     return iMCSelectedCount;
   }
   //Type is definitely select-multiple.
   for(var i = 0; i < fe_rcbsm.length; i++)  {
     if(fe_rcbsm.options[i].selected)  {
       iMCSelectedCount++;
     }
   }
   return iMCSelectedCount;
 }
 function getOptBooleanStringVF(bs_potential, s_variableName)  {
   return getOptBooleanString(bs_potential, s_variableName, "validate_form.getFormErrorMsgs");
 }
 function crashVF(s_message)  {
   return crash("validate_form.getFormErrorMsgs:  " + s_message);
 }
 function initializeLocalVars()  {
   resetCrashedFlag();
   asRCBSM_TRACKER_NAME = [];
   aiRCBSM_TRACKER_SEL_COUNT = [];
   aiRCBSM_TRACKER_ARR_IDX = [];
   iELEMENT_COUNT = 0;
   bFIRST_DEBUG_SCREEN_SEEN = false;
 }
 /**
   For backwards compatibility only.  Only use getFormErrorMsgs.  This function will eventually be eliminated.
  **/
 function validateForm(f_orm, s_userErrorPrefix, i_debugPerScreen)  {
   return getFormErrorMsgs(f_orm, s_userErrorPrefix, i_debugPerScreen);
 }

/**

 PRIVATE FUNCTIONS...end
**/

/**************************************************************************************************

 util_string.js...START
 Do not edit this file.  This file is dynamically generated by the validate_form.js
 ant build process
**************************************************************************************************/

/**

 VALIDATE_FORM.JS
 Comprehensive solution for validating HTML forms.
 Copyright (C) 2002, Jeff Epstein, jeff_epstein@yahoo.ru, http://www.jeffyjeffy.ru#download
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 This program 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 General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
**/
 //PHONE NUMBER AND ZIP CODE FORMAT/RANGES
   //For documentation, see
   //    documentation/index.html#string_zip
   //
   //Demo/testing values exist at the bottom of
   //    documentation/vf_string_phone_zip.html
   //
   //To test these formats for validity, see
   //    documentation/unit_test.html#util_string_tests
 //PHONE NUMBER FORMATS/RANGES...start
   //US 3 then 7
     var siPHONE_1_MINIMUM = "1001001000";
     var siPHONE_1_MAXIMUM = "9999999999";
   //US 7 only
     var siPHONE_2_MINIMUM = "1001000";
     var siPHONE_2_MAXIMUM = "9999999";
   var siPHONE_3_MINIMUM = "1000";
   var siPHONE_3_MAXIMUM = "9999";
   var siPHONE_4_MINIMUM = "001000";
   var siPHONE_4_MAXIMUM = "999999";
   var siPHONE_5_MINIMUM = "00000000";
   var siPHONE_5_MAXIMUM = "99999999";
   var siPHONE_6_MINIMUM = "1000000000";
   var siPHONE_6_MAXIMUM = "5555555555";
   var siPHONE_7_MINIMUM = "0";
   var siPHONE_7_MAXIMUM = "1";
   var siPHONE_8_MINIMUM = "1";
   var siPHONE_8_MAXIMUM = "9";
   var siPHONE_9_MINIMUM = "000";
   var siPHONE_9_MAXIMUM = "000";
   var siPHONE_10_MINIMUM = "010101";
   var siPHONE_10_MAXIMUM = "787374";
 //PHONE NUMBER FORMATS/RANGES...end
 //ZIP CODE FORMATS/RANGES...start
   //US 5+4
     var siZIP_1_RQD_MINIMUM = "00000";
     var siZIP_1_RQD_MAXIMUM = "99999";
     var siZIP_1_ALT_MINIMUM = "0001";
     var siZIP_1_ALT_MAXIMUM = "9999";
   //US 5 only
     var siZIP_2_RQD_MINIMUM = "00001";
     var siZIP_2_RQD_MAXIMUM = "99999";
     var siZIP_2_ALT_MINIMUM = "";
     var siZIP_2_ALT_MAXIMUM = "";
   var siZIP_3_RQD_MINIMUM = "1";
   var siZIP_3_RQD_MAXIMUM = "1";
   var siZIP_3_ALT_MINIMUM = "2";
   var siZIP_3_ALT_MAXIMUM = "2";
   var siZIP_4_RQD_MINIMUM = "01";
   var siZIP_4_RQD_MAXIMUM = "99";
   var siZIP_4_ALT_MINIMUM = "0001";
   var siZIP_4_ALT_MAXIMUM = "9999";
   var siZIP_5_RQD_MINIMUM = "00";
   var siZIP_5_RQD_MAXIMUM = "55";
   var siZIP_5_ALT_MINIMUM = "0";
   var siZIP_5_ALT_MAXIMUM = "7";
   var siZIP_6_RQD_MINIMUM = "54321";
   var siZIP_6_RQD_MAXIMUM = "55555";
   var siZIP_6_ALT_MINIMUM = "";
   var siZIP_6_ALT_MAXIMUM = "";
   var siZIP_7_RQD_MINIMUM = "00001";
   var siZIP_7_RQD_MAXIMUM = "00001";
   var siZIP_7_ALT_MINIMUM = "0001";
   var siZIP_7_ALT_MAXIMUM = "0001";
   var siZIP_8_RQD_MINIMUM = "09000";
   var siZIP_8_RQD_MAXIMUM = "91111";
   var siZIP_8_ALT_MINIMUM = "0003873874038834";
   var siZIP_8_ALT_MAXIMUM = "0020837401092837";
   var siZIP_9_RQD_MINIMUM = "0003873874038834";
   var siZIP_9_RQD_MAXIMUM = "0020837401092837";
   var siZIP_9_ALT_MINIMUM = "09000";
   var siZIP_9_ALT_MAXIMUM = "91111";
   var siZIP_10_RQD_MINIMUM = "0";
   var siZIP_10_RQD_MAXIMUM = "7";
   var siZIP_10_ALT_MINIMUM = "00";
   var siZIP_10_ALT_MAXIMUM = "55";
 //ZIP CODE FORMATS/RANGES...end


/**

 Does the provided string start or end with a space?
 EQUAL TO
   isSurroundedByChar(s_tring, " ");
**/

function isSurroundedBySpace(s_tring) {

 return isSurroundedByChar(s_tring, " ");

} /**

 Does the provided string start or end with the provided character?
 PARAMETERS
   s_tring  The string to analyze.
   c_har    The character that is determined to exist at the start or end of s_tring.
 RETURNS
   true   If the first or last character in s_tring is c_har.
   false  If s_tring is null or zero characters in length.
        If both the first and last characters in s_tring are *not* c_har.
**/

function isSurroundedByChar(s_tring, char_toTrim) {

 if(!s_tring)  {
   return false;
 }
 if(!char_toTrim  ||  char_toTrim.length != 1)  {
   return crash("isSurroundedByChar:  char_toTrim parameter must be provided, and be exactly one character in length.");
 }
 if(s_tring.length < 1)  {
   return false;
 }
 if(s_tring.substring(0, 1) == char_toTrim)  {
   return true;
 }
 return (s_tring.substring(s_tring.length - 1, s_tring.length) == char_toTrim);

}

/**

 Is the provided string a legal integer?
 RETURNS
   isNumber(s_potentialInteger, "false")
**/

function isInteger(s_potentialInteger) {

 return isNumber(s_potentialInteger, "false");

}

/**

 Is the provided string a legal decimal?
 RETURNS
   isNumber(s_potenitalDecimal, "true")
**/

function isDecimal(s_potentialDecimal) {

 return isNumber(s_potentialDecimal, "true");

} /**

 Is the provided string a legal number?
 PARAMETERS
   s_potentialNumber
     The string to analyze.  Required.
   bs_decimalAllowed
     Is the potential number allowed to be a decimal?  If "true", then yes.  If "false", no.
 RETURNS
   true
     If s_potentialNumber is a legal integer (regardless the value of bs_decimalAllowed).  A legal integer is a string that...
       ...contains one or more zeros.  Note that 0 equals 0000 equals 0000000000 equals ...
       ...starts with zero or one dashes (indicating negative), followed by one or more digits (0-9), where at least one is greater than zero.
     If bs_decimalAllowed is "true" and s_potentialNumber is a legal decimal.  A legal decimal is a string that...
       ...is an integer.
       ...starts with zero or one dashes (indicating negative) followed by zero or more digits, followed by a decimal point ("."), followed by *one* or more digits.
     (Note that s_potentialNumber is checked to be an integer first.  If it is, then true is returned, regardless the value of bs_decimalAllowed.  If the string is an integer, it is not checked, specifically, to see if it"s a decimal.  Hence, the description of a legal decimal number says "a decimal point" instead of "zero or one decimal points".)
   false
     If otherwise.
 LEGAL EXAMPLES (both integers and decimals)
     -1
     0
     1
     -50
     8750328754
     00008750328754
     08750328754
     -487584758475235
     -0000000487584758475235
     -0487584758475235
 ILLEGAL EXAMPLES (both integers and decimals)
     4875847-58475235
     487584758475235-
     [EMPTY_STRING]
     a
     0-
     -0
     Not a number!!!
     Some 123 numbers 456
     123 456
     -0.0
     -.0
     -0.000000
     -.000000
     1.
     .
 LEGAL EXAMPLES (decimals, but only after it is determined that the value is *not* an integer)
     1.1
     1.000830847018374
     058763408562473.01837486564417308746
     .1
     .0
     .01
     -1.0
**/

function isNumber(s_potentialNumber, bs_decimalAllowed) {

 crashIfMissing("util_string.jsNumber", s_potentialNumber, "s_potentialNumber");
 crashIfBadBooleanString(bs_decimalAllowed, "bs_decimalAllowed", "util_string.jsNumber");
 if(s_potentialNumber.length < 1)  {
   return false;
 }
 if(s_potentialNumber == "-")  {
   //A negative sign only makes no sense.
   return false;
 }
 if(/^-[0]+$/.test(s_potentialNumber))  {
   //Negative zero makes no sense.
   return false;
 }
 if(/^[0]+$/.test(s_potentialNumber))  {
   //Zero is a legal number:
   //0  ==  0000000000000  ==  000
   return true;
 }
 //It is definitely not zero.
 //^         The start of the line.
 //[-]{0,1}  Zero or one dashes.
 //[0-9]+    One or more of any digit.
 //$         The end of the line.
 if(/^[-]{0,1}[0-9]+$/.test(s_potentialNumber))  {
   //No matter what, this is valid.  This is a leagal integer
   //and decimal.
   return true;
 }
 //It"s not an integer...
 if(bs_decimalAllowed == "false")  {
   //...but it must be.
   return false;
 }
 //...and that"s okay.  It might be a decimal
 //Due to precision:
 //10.0000000000001 is legal (12 zeros)
 //10.00000000000001 is not  (13 zeros)
 //^         The start of the line.
 //[-]{0,1}  Zero or one dashes.
 //[0-9]*    Zero or more digits.
 //[.]      A decimal point.
 //[0-9]+    One or more digits.
 //$         The end of the line.
 if(/^[-]{0,1}[0-9]*[.][0-9]+$/.test(s_potentialNumber))  {
   //It is a "raw" decimal.  The only thing that would make
   //this illegal is if it were -0.0 or -.0, or -0.0000 or
   //-.0000 or ...
   return !(/^-0*[.]0+$/.test(s_potentialNumber));
 }
 //It is not a legal decimal number.
 return false;

}

function isEmail(s_potentialEmail) {

 if(!s_potentialEmail  ||  s_potentialEmail.length < 1)  {
   return crash("isValidNumber:  s_potentialEmail must be defined, and at least one character in length.");
 }
 if(s_potentialEmail.indexOf(" ") != -1  ||
    s_potentialEmail.indexOf("/") != -1  ||
    s_potentialEmail.indexOf("\\") != -1  ||
    s_potentialEmail.indexOf(",") != -1)  {
   //A space, slash or comma was found.
   return false;
 }
 if(/[@.][@.]/.test(s_potentialEmail))  {
   //An @ or dot is followed by an @ or dot.
   return false;
 }
 if(/^[@.]/.test(s_potentialEmail))  {
   //The first character is an @ or dot.
   return false;
 }
 if(/[@.]$/.test(s_potentialEmail))  {
   //The last character may not be an @ or dot.
   return false;
 }
 if(!/^[^@]+@[^@]+$/.test(s_potentialEmail))  {
   //Only one @ allowed
   //    (Negative of:
   //     Must have one or more non-@ starting the line,
   //     exactly one @, and then
   //     one or more non-@ ending the line.)
   return false;
 }
 //There is exactly one @.
 if(!/@.*[.]/.test(s_potentialEmail))  {
   //At least one dot must follow the (single) @.
   return false;
 }
 //At least one dot follows the @.  We already determined
 //above that it does not immediately follow it,
 //No negative conditions were met.  This is a legal email address.
 //Cool, eh?  : )
 return true;

}

function removeNonNumbers(s_tring) {

 if(!s_tring  ||  s_tring.length < 1)  {
   return crash("removeNonNumbers:  s_tring must be defined, and at least one character in length.");
 }
 var reNonNumbers = /^\D$/;
 if(/^\D$/.test(s_tring))  {
   //There are no numbers at all.
   return "";
 }
 //There is at least one number.
 var asNumberParts = s_tring.split(/\D/);
 var sNumber = asNumberParts[0];
 for(var i = 1; i < asNumberParts.length; i++)  {
   sNumber += asNumberParts[i];
 }
 return sNumber;

} /**

 Are the provided phone format strings valid?
 See the documentation above, regarding PHONE NUMBER FORMATS/RANGES.  Specifically, under the "phone" section, under "--- RULES ---".
 Call this function manually, if you wish.  It is not called by any other function in this js file...except crashIfBadPhoneFormat.
 PARAMETER
   bs_crashIfBad
     Must equal either "true" or "false".  If "true", then if the formats are invalid, this function crashes with a descriptive message.  See utility.crash().
**/

function isPhoneFormatValid(bs_crashIfBad, si_minFormat, si_maxFormat) {

 return isFormatValid("Phone", bs_crashIfBad, "si_minFormat", "si_maxFormat", si_minFormat, si_maxFormat);

}

function getValidPhone(s_potentialPhone) {

 return getValidPhone1(s_potentialPhone);

} function getValidPhone1(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_1_MINIMUM, siPHONE_1_MAXIMUM, s_potentialPhone);

} function getValidPhone2(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_2_MINIMUM, siPHONE_2_MAXIMUM, s_potentialPhone);

} function getValidPhone3(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_3_MINIMUM, siPHONE_3_MAXIMUM, s_potentialPhone);

} function getValidPhone4(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_4_MINIMUM, siPHONE_4_MAXIMUM, s_potentialPhone);

} function getValidPhone5(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_5_MINIMUM, siPHONE_5_MAXIMUM, s_potentialPhone);

} function getValidPhone6(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_6_MINIMUM, siPHONE_6_MAXIMUM, s_potentialPhone);

} function getValidPhone7(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_7_MINIMUM, siPHONE_7_MAXIMUM, s_potentialPhone);

} function getValidPhone8(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_8_MINIMUM, siPHONE_8_MAXIMUM, s_potentialPhone);

} function getValidPhone9(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_9_MINIMUM, siPHONE_9_MAXIMUM, s_potentialPhone);

} function getValidPhone10(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_10_MINIMUM, siPHONE_10_MAXIMUM, s_potentialPhone);

} /**

 Get the phone number out of the provided string.
 PARAMETERS
   si_minFormat
     The format string representing the minimum allowable bound for a legal phone number.  It is *assumed* that this string is provided and valid.  Use isPhoneFormatValid() to validate this, along with si_maxFormat.  For specific information on this variable, see the documentation above, regarding PHONE NUMBER FORMATS/RANGES, under the "phone" section.
   si_maxFormat
     The format string representing the maximum allowable bound for a legal phone number.  It is *assumed* that this string is provided and valid.  Use isPhoneFormatValid() to validate this, along with si_maxFormat.  For specific information on this variable, see the documentation above, regarding PHONE NUMBER FORMATS/RANGES, under the "phone" section.
   s_potentialPhone
     The string containing the (potentially legal) phone number, including any surrounding text.  For example:
       (215) 555-1212
       215 555 1212
       2155551212
 RETURNS
   If the phone number is invalid, according to the format, empty string ("") is returned.  Otherwise, the non-digits are stripped from s_potentialPhone, and the digits alone are returned (but as a string, preserving leading zeros).  For example, all of the above examples (under s_potentialPhone) return "2155551212".
**/

function getValidPhoneFromFormat(si_minFormat, si_maxFormat, s_potentialPhone) {

 if(!s_potentialPhone  ||  s_potentialPhone.length < 1)  {
   return crash("isValidNumber:  s_potentialPhone must be defined, and at least one character in length.");
 }
 //This also removes dashes (negative symbols) and decimal points.
 var siPhoneNumber = removeNonNumbers(s_potentialPhone);
 if(!siPhoneNumber  ||  siPhoneNumber.length < 1  ||
      siPhoneNumber.length != si_minFormat.length)  {
   //The length is illegal.
   return "";
 }
 //Must supply radix=10
 var iMin = parseInt(si_minFormat, 10);
 var iMax = parseInt(si_maxFormat, 10);
 if(isValidNumber(siPhoneNumber, iMin, iMax))  {
   //The phone number is in bounds.
   return siPhoneNumber;
 }
 //It is not a valid phone number.
 return "";

}

/**

 Are the provided zip format strings valid?
 See the documentation above, regarding PHONE NUMBER FORMATS/RANGES.  Specifically, under the "zip code" section, under "--- RULES ---".
 Call this function manually, if you wish.  It is not called by any other function in this js file.
 PARAMETER
   bs_crashIfBad
     Must equal either "true" or "false".  If "true", then if the formats are invalid, this function crashes with a descriptive message.  See utility.crash().
**/

function isZipFormatValid(bs_crashIfBad, si_rqdMinFormat, si_rqdMaxFormat, si_altMinFormat, si_altMaxFormat) {

 if(!isFormatValid("Zip", bs_crashIfBad, "si_rqdMinFormat", "si_rqdMaxFormat", si_rqdMinFormat, si_rqdMaxFormat))  {
   return false;
 }
 //The required format is valid.
 if(!si_altMinFormat ^ !si_altMaxFormat)  {
   if(bs_crashIfBad == "true")  {
     return crash("util_string.jsZipFormatValid:  si_altMinFormat ("" + si_altMinFormat + "") and si_altMaxFormat ("" + si_altMaxFormat + "") must both be either undefined or defined.");
   }
   return false;
 }
 //Both are either undefined, or defined.
 if(!si_altMinFormat)  {
   //One is undefined, therefore both are undefined.
   return true;
 }
 //Both are defined.
 return isFormatValid("Zip", bs_crashIfBad, "si_altMinFormat", "si_altMaxFormat", si_altMinFormat, si_altMaxFormat)

}

function getValidZip(s_potentialZip) {

 return getValidZip1(s_potentialZip);

} function getValidZip1(s_potentialZip) {

 return getValidZipFromFormat(siZIP_1_RQD_MINIMUM, siZIP_1_RQD_MAXIMUM, siZIP_1_ALT_MINIMUM, siZIP_1_ALT_MAXIMUM, s_potentialZip);

} function getValidZip2(s_potentialZip) {

 return getValidZipFromFormat(siZIP_2_RQD_MINIMUM, siZIP_2_RQD_MAXIMUM, siZIP_2_ALT_MINIMUM, siZIP_2_ALT_MAXIMUM, s_potentialZip);

} function getValidZip3(s_potentialZip) {

 return getValidZipFromFormat(siZIP_3_RQD_MINIMUM, siZIP_3_RQD_MAXIMUM, siZIP_3_ALT_MINIMUM, siZIP_3_ALT_MAXIMUM, s_potentialZip);

} function getValidZip4(s_potentialZip) {

 return getValidZipFromFormat(siZIP_4_RQD_MINIMUM, siZIP_4_RQD_MAXIMUM, siZIP_4_ALT_MINIMUM, siZIP_4_ALT_MAXIMUM, s_potentialZip);

} function getValidZip5(s_potentialZip) {

 return getValidZipFromFormat(siZIP_5_RQD_MINIMUM, siZIP_5_RQD_MAXIMUM, siZIP_5_ALT_MINIMUM, siZIP_5_ALT_MAXIMUM, s_potentialZip);

} function getValidZip6(s_potentialZip) {

 return getValidZipFromFormat(siZIP_6_RQD_MINIMUM, siZIP_6_RQD_MAXIMUM, siZIP_6_ALT_MINIMUM, siZIP_6_ALT_MAXIMUM, s_potentialZip);

} function getValidZip7(s_potentialZip) {

 return getValidZipFromFormat(siZIP_7_RQD_MINIMUM, siZIP_7_RQD_MAXIMUM, siZIP_7_ALT_MINIMUM, siZIP_7_ALT_MAXIMUM, s_potentialZip);

} function getValidZip8(s_potentialZip) {

 return getValidZipFromFormat(siZIP_8_RQD_MINIMUM, siZIP_8_RQD_MAXIMUM, siZIP_8_ALT_MINIMUM, siZIP_8_ALT_MAXIMUM, s_potentialZip);

} function getValidZip9(s_potentialZip) {

 return getValidZipFromFormat(siZIP_9_RQD_MINIMUM, siZIP_9_RQD_MAXIMUM, siZIP_9_ALT_MINIMUM, siZIP_9_ALT_MAXIMUM, s_potentialZip);

} function getValidZip10(s_potentialZip) {

 return getValidZipFromFormat(siZIP_10_RQD_MINIMUM, siZIP_10_RQD_MAXIMUM, siZIP_10_ALT_MINIMUM, siZIP_10_ALT_MAXIMUM, s_potentialZip);

} /**

 Get the zip code out of the provided string.
 PARAMETERS
   si_rqdMinFormat
     The format string representing the minimum allowable bound for the required portion of a legal zip code.  It is *assumed* that this string is provided and valid.  Use isZipFormatValid() to validate this, along with si_maxFormat.  For specific information on this variable, see the documentation above, regarding PHONE NUMBER FORMATS/RANGES, under the "zip code" section.
   si_rqdMaxFormat
     The format string representing the maximum allowable bound for the required portion of a legal zip code.  It is *assumed* that this string is provided and valid.  Use isZipFormatValid() to validate this, along with si_maxFormat.  For specific information on this variable, see the documentation above, regarding PHONE NUMBER FORMATS/RANGES, under the "zip code" section.
   si_altMinFormat
     The format string representing the minimum allowable bound for the alternate portion of a legal zip code.  It is *assumed* that this string is provided and valid.  Use isZipFormatValid() to validate this, along with si_maxFormat.  For specific information on this variable, see the documentation above, regarding PHONE NUMBER FORMATS/RANGES, under the "zip code" section.
   si_altMaxFormat
     The format string representing the maximum allowable bound for the alternate portion of a legal zip code.  It is *assumed* that this string is provided and valid.  Use isZipFormatValid() to validate this, along with si_maxFormat.  For specific information on this variable, see the documentation above, regarding PHONE NUMBER FORMATS/RANGES, under the "zip code" section.
   s_potentialZip
     The string containing the (potentially legal) zip code, including any surrounding text.  For example:
       08052-3848
       19130 (0408)
       00483
 RETURNS
   If the zip code is invalid, according to the format, empty string ("") is returned.  Otherwise, the non-digits are stripped from s_potentialZip, and the digits alone are returned (but as a string, preserving leading zeros).  For example, the second example above (under s_potentialZip) returns "191300408".
**/

function getValidZipFromFormat(si_rqdMinFormat, si_rqdMaxFormat, si_altMinFormat, si_altMaxFormat, s_potentialZip) {

 if(!s_potentialZip  ||  s_potentialZip.length < 1)  {
   return crash("isValidNumber:  s_potentialZip must be defined, and at least one character in length.");
 }
 var siZip = removeNonNumbers(s_potentialZip);
 var bLegalLength = false;
 if(siZip)  {
   //There is at least one digit in the zip code...it does
   //exist and...
   if(siZip.length == si_rqdMinFormat.length)  {
     //...it is the required length.
     bLegalLength = true;
   }  else if(si_altMinFormat  &&  si_altMinFormat.length > 0  &&
                  siZip.length == (si_rqdMinFormat.length + si_altMinFormat.length))  {
     //...although it is not the required length, there is
     //an alternate length format, and the zip code has
     //the same length as it PLUS the required part.
     bLegalLength = true;
   }  //ELSE:  There is no alternate format.
 }
 if(!bLegalLength)  {
   return "";
 }
 //The length is legal, according to the format.
 var sRqdPart = siZip.substring(0, si_rqdMinFormat.length);
 //Must specify 10 as the radix (base).  If you don"t, and the
 //format has leading zeros, it may get confused and assume
 //that it has a different radix.
 var iMin = parseInt(si_rqdMinFormat, 10);
 var iMax = parseInt(si_rqdMaxFormat, 10);
 if(!isValidNumber(sRqdPart, iMin, iMax))  {
   //The zip is out of bounds.
   return "";
 }
 //The required part is legal.
 if(siZip.length > sRqdPart.length)  {
   //The length of the overall zip (siZip) is longer than the
   //length of the required part.  In other words, the
   //potential zip definitely has an alternate part.
   var sAltPart = siZip.substring(si_rqdMinFormat.length, siZip.length);
   //Must specify 10 as the radix (base).
   iMin = parseInt(si_altMinFormat, 10);
   iMax = parseInt(si_altMaxFormat, 10);
   if(!isValidNumber(sAltPart, iMin, iMax))  {
     //The zip is out of bounds.
     return "";
   }
 }
 //Every part is in range.
 return siZip;

}

/**

 Is the provided string (who"s value is a non-negative integer) legal?
 PARAMETERS
   s_potentialInt
     The string to analyze.  Required, and it is *assumed* that this only contains digits (0-9.  Decimal points ["."] and negative symbols ["-"] are not legal).  If it contains anything else, this function will behave unpredictably.
   bs_trailingZeroOk
     Required.  Must equal "true" or "false".  If "true", then s_potentialInt is considered legal if it starts with one or more zeros (regardless if it actually equals zero).  If "false", then when s_potentialInt starts with a zero, this function returns false.  This parameter is primary, over bs_zeroOk (see "NOTE").
   bs_zeroOk
     Required.  Must equal "true" or "false".  If "true", then s_potentialInt is considered legal if it is equal to zero ("0", "00", "00000", "0000000000", ...).  If "false", then when s_potentialInt equals zero, this function returns false.  No matter what, a non-zero value is okay, even if there are trailing zeros (however, this does not override bs_trailingZeroOk).  This parameter is secondary to bs_trailingZerosOk (see "NOTE").
   NOTE.
     Note which combinations of bs_trailingZeroOk and bs_zeroOk are legal:
     bs_trailingZeroOk     bs_zeroOk       LEGAL?
       true                 true            yes
       true                 false           yes
       false                true            NO
       false                false           yes
 RETURNS
   true
     If s_potentialInt conforms to the rules defined by bs_zeroOk and bs_trailingZeroOk parameters.
   false
     If otherwise.
**/

function isValidPosIntStr(s_potentialInt, bs_trailingZeroOk, bs_zeroOk) {

 crashIfMissing("util_string.jsValidPosIntStr", s_potentialInt, "s_potentialInt");
 crashIfBadBooleanString(bs_trailingZeroOk, "bs_trailingZeroOk", "util_string.jsValidPosIntStr");
 crashIfBadBooleanString(bs_zeroOk, "bs_zeroOk", "util_string.jsValidPosIntStr");
 if(bs_zeroOk == "true"  &&  bs_trailingZeroOk == "false")  {
   return crash("util_string.jsValidPosIntStr:  bs_trailingZero equals "false", but bs_zeroOk equals "true".");
 }
 if(bs_zeroOk == "true")  {
   //No matter what, s_potentialInt is valid.
   return true;
 }
 //Zero, as a whole, is not okay, however, trailing zeros may
 //be okay.
 var iTrailingZeros = 0;
 for(var i = 0; i < s_potentialInt.length; i++)  {
   var cDigit = s_potentialInt.substring(i, i + 1);
   if(cDigit == "0")  {
     iTrailingZeros++;
   }  else  {
     //We"ve reached the first non-zero.
     break;
   }
 }
 if(iTrailingZeros == 0)  {
   //There are no trailing zeros.  No further analysis
   //needed.
   return true;
 }
 //There is at least one trailing zero.
 if(iTrailingZeros == s_potentialInt.length)  {
   //EVERY digit is equal to zero.
   //s_potentialInt equals zero.
   //s_potentialInt contains only zeros.
   //If bs_zeroOk equals "true":  return true.
   //If bs_zeroOk equals "false":  return false.
   return (bs_zeroOk == "true");
 }
 //There is at least one non-zero digit, following the
 //initial trailing zero(s).
 //If bs_trailingZeroOk equals "true":  return true.
 //If bs_trailingZeroOk equals "false":  return false.
 return (bs_trailingZeroOk == "true");

}

function trimSpaces(s_tring) {

 return trimChar(" ", s_tring);

}

function trimChar(c_harToTrim, s_tring) {

 if(!c_harToTrim  ||  c_harToTrim.length != 1)  {
   return crash("util_sting.trimChar:  c_harToTrim must be provided, and must be exactly one character in length.  Currently "" + c_harToTrim + "".");
 }
 crashIfMissing("util_string.trimSpaces", s_tring, "s_tring");
 var i = 0;
 var iStartingSpaces = 0;
 while(s_tring.substring(i, (i + 1)) == c_harToTrim)  {
   iStartingSpaces++
   i++;
 }
 if(iStartingSpaces == s_tring.length)  {
   return "";
 }
 i = 0;
 var iEndingSpaces = 0;
 while(s_tring.substring((s_tring.length - i), (s_tring.length - (i + 1))) == c_harToTrim)  {
   iEndingSpaces++
   i++;
 }
 if(iStartingSpaces == 0  &&  iEndingSpaces == 0)  {
   return s_tring;
 }
 return s_tring.substring(iStartingSpaces, (s_tring.length - iEndingSpaces));

}

function isFormatValid(s_type, bs_crashIfBad, s_minDesc, s_maxDesc, si_minimum, si_maximum) {

 crashIfBadBooleanString(bs_crashIfBad, "bs_crashIfBad", "util_string.js" + s_type + "FormatValid");
 crashIfMissing("util_string.js" + s_type + "FormatValid", si_minimum, s_minDesc);
 crashIfMissing("util_string.js" + s_type + "FormatValid", si_maximum, s_maxDesc);
 if(si_minimum.length != si_maximum.length)  {
   if(bs_crashIfBad == "true")  {
     return crash("util_string.js." + s_type + "FormatValid:  " + s_minDesc + " ("" + si_minimum + "") must be the same length as " + s_maxDesc + " ("" + si_maximum + "").");
   }
   return false;
 }
 if(!isInteger(si_minimum)  ||  si_minimum < 0)  {
   if(bs_crashIfBad == "true")  {
     return crash("util_string.js." + s_type + "FormatValid:  " + s_minDesc + " (currently "" + si_minimum + "") must be an integer greater than or equal to zero.");
   }
   return false;
 }
 if(!isInteger(si_maximum)  ||  si_maximum < 0)  {
   if(bs_crashIfBad == "true")  {
     return crash("util_string.js." + s_type + "FormatValid:  " + s_maxDesc + " (currently "" + si_maximum + "") must be an integer greater than or equal to zero.");
   }
   return false;
 }
 //Must supply radix=10
 var iMin = parseInt(si_minimum, 10);
 var iMax = parseInt(si_maximum, 10);
 if(iMin > iMax)  {
   if(bs_crashIfBad == "true")  {
     return crash("util_string.js." + s_type + "FormatValid:  " + s_minDesc + " (" + si_minimum + ") is numerically greater than " + s_maxDesc + " (" + si_maximum + ").");
   }
   return false;
 }
 return true;

}

function getPadded(s_tring, i_padLength) {

 crashIfMissing("util_string.js.getPadded", s_tring, "s_tring");
 crashIfMissing("util_string.js.getPadded", i_padLength, "i_padLength");
 if(!isInteger(i_padLength))  {
   return crash("util_string.js.getPadded:  i_padLength ("" + i_padLength + "") must be an *integer* greater than or equal to zero.");
 }  else if(!isValidNumberOpt(i_padLength, 0, "true", -1, "false"))  {
   return crash("util_string.js.getPadded:  i_padLength ("" + i_padLength + "") must be an *integer* greater than or equal to zero.");
 }
 if(s_tring.length >= i_padLength)  {
   return s_tring;
 }
 for(var i = s_tring.length; i < (i_padLength + 1); i++)  {
   s_tring = s_tring + " ";
 }
 return s_tring;

} /**************************************************************************************************

 util_number.js...START
 Do not edit this file.  This file is dynamically generated by the validate_form.js
 ant build process
**************************************************************************************************/

/**

 VALIDATE_FORM.JS
 Comprehensive solution for validating HTML forms.
 Copyright (C) 2002, Jeff Epstein, jeff_epstein@yahoo.ru, http://www.jeffyjeffy.ru#download
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 This program 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 General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
**/

function isValidRangeOpt(i_min, bs_enforceMin, i_max, bs_enforceMax) {

 crashIfBadBooleanString(bs_enforceMin, "bs_enforceMin", "util_number.isValidRangeOpt");
 crashIfBadBooleanString(bs_enforceMax, "bs_enforceMax", "util_number.isValidRangeOpt");
 if(bs_enforceMin == "false"  ||  bs_enforceMax == "false")  {
   //At least one of the bounds are not being enforced.
   return true;
 }
 return !(i_min > i_max);

} function isValidRange(i_min, i_max) {

 return isValidRangeOpt(i_min, "true", i_max, "true");

} function isValidNumber(i_number, i_min, i_max) {

 return isValidNumberOpt(i_number, i_min, "true", i_max, "true");

} /**

 It is assumed that the range is valid.  You will get unpredictable results if it is not.
**/

function isValidNumberOpt(i_number, i_min, bs_enforceMin, i_max, bs_enforceMax) {

 crashIfMissing("util_number.isValidNumber", i_number, "i_number");
       //alert("isValidRangeOpt(" + i_number + ", " + i_min + ", " + bs_enforceMin + ", " + i_max + ", " + bs_enforceMax + ")...\n...isValidRangeOpt(" + i_min + ", " + bs_enforceMin + ", " + i_number + ", "true")=" + isValidRangeOpt(i_min, bs_enforceMin, i_number, "true") + "\n...isValidRangeOpt(" + i_number + ", "true", " + i_max + ", " + bs_enforceMax + ")=" + isValidRangeOpt(i_number, "true", i_max, bs_enforceMax));
 return (isValidRangeOpt(i_min, bs_enforceMin, i_number, "true")  &&
         isValidRangeOpt(i_number, "true", i_max, bs_enforceMax));

}

/**************************************************************************************************

 utility.js...START
 Do not edit this file.  This file is dynamically generated by the validate_form.js
 ant build process
**************************************************************************************************/

/**

 VALIDATE_FORM.JS
 Comprehensive solution for validating HTML forms.
 Copyright (C) 2002, Jeff Epstein, jeff_epstein@yahoo.ru, http://www.jeffyjeffy.ru#download
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 This program 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 General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
**/

//GLOBAL VARIABLES...start

 //A secret public global variable.  For testing purposes, you may want to
 //avoid re-displaying the error after the alert box (within H1 tags).
 //
 //This prevents the crash function from re-presenting the
 //error, after the alert box, within H1 tags.  It makes it so you
 //don"t have to press the back button between each error, in order
 //to get back to this page.
 var bCRASH_ONLY_ALERT_BOX = false;
 //This is automatically manipulated by this js file.  It is private
 //and should never be altered.
 var bCrashed = false;

//GLOBAL VARIABLES...end /**

 Present an error message in an alert box, and also print the provided error message to screen, surrounded by H1 tags.  This function is intended for programming errors, not user errors.
 Although execution is not truly interrupted, this should be significant enough to alert the programmer to an error.
 PARAMETERS
   s_callingFuncAndError
     The function name, followed by the error message.
 RETURNS
   false
     Always.
**/

function crash(s_callingFuncAndError) {

 alert("-------ERROR-------\n\nERROR in " + s_callingFuncAndError);
 if(!bCRASH_ONLY_ALERT_BOX)  {
document.writeln("

ERROR in " + s_callingFuncAndError + "

");
 }
 bCrashed = true;
 return false;

} /**

 Was crash() called?
 RETURNS
   true
     If crash() was called.
   false
     If crash() was never called...or when it was, but you since called resetCrashedFlag().
**/

function hasCrashed() {

 return bCrashed;

} /**

 Make it appear as if crash() was never called, regardless of whether or not it actually was.  This is probably only useful for testing purposes.
**/

function resetCrashedFlag() {

 bCrashed = false;

} /**

 Conditionally print the provided message in an alert box.
 PARAMETERS
   b_condition
     If true, present s_message in an alert box.  If false, do nothing.
   s_message
     The message to present in an alert box, should b_condition be true.  If b_condition is false, this parameter is ignored.
 RETURNS
   true
     If b_condition is true.
   false
     If b_condition is false.
**/

function calert(b_condition, s_message) {

 if(b_condition)  {
   alert(s_message);
   return false;
 }
 return true;

}

/**

 Convenience function to print an error message, should a required parameter not be provided.
 PARAMETERS
   s_callingFileFunc
     Passed directly to crash, if !o_param.  If o_param is true, this parameter is ignored.
   s_paramName
     The name of o_param, only for the potential error message.  If o_param is true, this parameter is ignored.
   o_param
     The required parameter.  If "false" (!o_param) the an error message is printed.
 RETURNS
   true
     If o_param is true.
   false
     If o_param is false.
**/

function crashIfMissing(s_callingFileFunc, s_paramName, o_param) {

 if(!o_param)  {
   return crash(s_callingFileFunc + ":  Required parameter " + s_paramName + " not provided.");
 }
 return true;

} /**

 A single unit test.  If the actual result differs from the actual, an error alert box is presented.
 PARAMETERS
   s_nameOfTest
     The name of the calling JavaScript file and function name, currently being tested.  Required.
   i_testNumber
     The number of the test, for potential error messages only.  Required.
   s_expected
     The expected response from this test.
   s_actual
     The actual response from this test.
 RETURNS
   true
     If s_expected equals s_actual.
   false
     If s_expected does not equal s_actual.
**/

function test(s_nameOfTest, i_testNumber, s_expected, s_actual) {

 crashIfMissing(s_nameOfTest, "s_nameOfTest", "utility.test");
 crashIfMissing(i_testNumber, "i_testNumber", "utility.test");
 if(s_expected != s_actual)  {
   alert("---ERROR---\n\n\tTest name:\t" + s_nameOfTest + "\n\tTest number:\t" + i_testNumber + "\n\tExpected:\t"" + s_expected + ""\n\tActual:\t\t"" + s_actual + """);
   return false;
 }
 return true;

} function crashIfBadBooleanString(bs_potential, s_variableName, s_callingFunc) {

 if(!bs_potential)  {
   return crash(s_callingFunc + ":  " + s_variableName + " must be a *string*, provided, and equal to either "true" or "false".  It is currently a *boolean* equal to "false".");
 }
 if(bs_potential != "true"  &&  bs_potential != "false")  {
   var sValue = "string equal to "" + bs_potential;
   if(typeof(bs_potential) == "boolean")  {
     //It is equal to *boolean* true.  It"s not a string.
     //Note that it"s NOT false, because the first line of this
     //function eliminated this possibility.
     sValue = "*boolean* equal to "" + bs_potential;
   }
   return crash(s_callingFunc + ":  " + s_variableName + " must be a string, provided, and equal to either "true" or "false".  It is currently a " + sValue + "".");
 }

} function crashIfBadBooleanStringOpt(bs_potential, s_variableName, s_callingFunc) {

 if(!bs_potential)  {
   return;
 }
 //bs_potential has been provided.
 if(bs_potential != "true"  &&  bs_potential != "false")  {
   var sValue = "string equal to "" + bs_potential + "";
   if(typeof(bs_potential) == "boolean")  {
     //It is equal to *boolean* true.  It"s not a string.
     //Note that it"s NOT false, because the first line of this
     //function eliminated this possibility.
     sValue = "*boolean* equal to "" + bs_potential + "";
   }
   return crash(s_callingFunc + ":  " + s_variableName + " is not required, but when provided it must be a string, and equal to either "true" or "false".  It is currently a " + sValue + "".");
 }

}

function getOptBooleanString(bs_potential, s_variableName, s_callingFunc) {

 if(bs_potential)  {
   crashIfBadBooleanStringOpt(bs_potential, s_variableName, s_callingFunc);
   return bs_potential;
 }  else  {
   return "false";
 }

}


/**

 Is the provided object an array?
 This concept comes from Kas Thomas, at
 http://www.planetpdf.ru/mainpage.asp?webpageid=1144
 PARAMETERS
   o_potentialArray
     The object that is analyzed to see if it is an array.  Required.
 RETURNS
   true
     If o_potentialArray is an array.
   false
     If o_potentialArray is anything but an array.
**/

function isArray(o_potentialArray) {

 crashIfMissing(o_potentialArray, "o_potentialArray", "utility.isArray");
 if(typeof o_potentialArray != "object")  {
   return false;
 }
 //It is definitely an object.
 return (o_potentialArray.constructor.toString().match(/array/i) != null);

} </SCRIPT> <SCRIPT LANGUAGE="JavaScript">

</SCRIPT> </HEAD> <BODY LINK="#0000FF" VLINK="#0000FF">

Example: Heavy Duty

This example pulls out all the stops. It also allows you to dynamically set the debugging amount, which is passed in as the third parameter to getUserErrorMsgs.

<FORM METHOD="post" action="#" name="form" onSubmit="

 return isFormValid(this);">
 <INPUT type="submit" name="Submit" value="Submit">
      <select name="debug_amount">
   <OPTION value="-1" SELECTED>----Select a debug amount----
   <OPTION value="1">1</OPTION>
   <OPTION value="2">2</OPTION>
   <OPTION value="3">3</OPTION>
   <OPTION value="4">4</OPTION>
   <OPTION value="5">5</OPTION>
   <OPTION value="6">6</OPTION>
   <OPTION value="7">7</OPTION>
   <OPTION value="8">8</OPTION>
   <OPTION value="9">9</OPTION>
   <OPTION value="10">10</OPTION>
   <OPTION value="11">11</OPTION>
   <OPTION value="12">12</OPTION>
   <OPTION value="13">13</OPTION>
   <OPTION value="14">14</OPTION>
   <OPTION value="15">15</OPTION>
   <OPTION value="16">16</OPTION>
   <OPTION value="17">17</OPTION>
   <OPTION value="18">18</OPTION>
   <OPTION value="19">19</OPTION>
   <OPTION value="20">20</OPTION>
   <OPTION value="21">21</OPTION>
   <OPTION value="22">22</OPTION>
   <OPTION value="23">23</OPTION>
   <OPTION value="24">24</OPTION>
   <OPTION value="25">25</OPTION>
   <OPTION value="26">26</OPTION>
   <OPTION value="27">27</OPTION>
   <OPTION value="28">28</OPTION>
   <OPTION value="29">29</OPTION>
   <OPTION value="30">30</OPTION>
   <OPTION value="31">31</OPTION>
   <OPTION value="32">32</OPTION></SELECT>
        (* = Required)
 
<INPUT type="button" name="Reeset" value="Clear all values" onClick=" resetValues(this.form);"> <INPUT type="button" value="Good values, only rqd" onClick=" goodValuesRqd(this.form);"> <INPUT type="button" value="Good values, all" onClick=" goodValuesRqd(this.form); goodValuesOther(this.form);"> <INPUT type="button" value="Bad values" onClick=" badValues(this.form);">
 <INPUT type="hidden" name="x" value="ex">
 <INPUT type="hidden" name="y" value="value of y">
 <INPUT type="hidden" name="z" value="Here is the ever-loving value of z">
 
 
* First Name: <INPUT type="text" name="first_name" size="40">
* Last Name: <INPUT type="text" name="last_name" size="40">
* Address line one: <INPUT type="text" name="address_line_one" size="40">
  Address line two: <INPUT type="text" name="address_line_two" size="40">
* City: <INPUT type="text" name="city" size="30">
* State: <select name="state_code"> <OPTION value="" SELECTED>Choose a State <OPTION value="AL">Alabama <OPTION value="AK">Alaska <OPTION value="AZ">Arizona <OPTION value="AR">Arkansas <OPTION value="CA">California <OPTION value="CO">Colorado <OPTION value="CT">Connecticut <OPTION value="DC">D.C. <OPTION value="DE">Delaware <OPTION value="FL">Florida <OPTION value="GA">Georgia <OPTION value="HI">Hawaii <OPTION value="ID">Idaho <OPTION value="IL">Illinois <OPTION value="IN">Indiana <OPTION value="IA">Iowa <OPTION value="KS">Kansas <OPTION value="KY">Kentucky <OPTION value="LA">Louisiana <OPTION value="ME">Maine <OPTION value="MD">Maryland <OPTION value="MA">Massachusetts <OPTION value="MI">Michigan <OPTION value="MN">Minnesota <OPTION value="MS">Mississippi <OPTION value="MO">Missouri <OPTION value="MT">Montana <OPTION value="NE">Nebraska <OPTION value="NV">Nevada <OPTION value="NH">New Hampshire <OPTION value="NJ">New Jersey <OPTION value="NM">New Mexico <OPTION value="NY">New York <OPTION value="NC">North Carolina <OPTION value="ND">North Dakota <OPTION value="OH">Ohio <OPTION value="OK">Oklahoma <OPTION value="OR">Oregon <OPTION value="PA">Pennsylvania <OPTION value="RI">Rhode Island <OPTION value="SC">South Carolina <OPTION value="SD">South Dakota <OPTION value="TN">Tennessee <OPTION value="TX">Texas <OPTION value="UT">Utah <OPTION value="VT">Vermont <OPTION value="VA">Virginia <OPTION value="WA">Washington <OPTION value="WV">West Virginia <OPTION value="WI">Wisconsin <OPTION value="WY">Wyoming</OPTION></SELECT>
* Zip code: <INPUT type="text" name="zip_code" size="12">
* Phone: <INPUT type="text" name="phone_text" size="20">
Fax: <INPUT type="text" name="fax" size="20">
* E-mail address: <INPUT type="text" name="email" size="20">
* What time do you usually go to bed?
      <INPUT type="radio" name="bed_time" value="8pm"> Eight at night
      <INPUT type="radio" name="bed_time" value="10pm"> Ten at night
      <INPUT type="radio" name="bed_time" value="4am"> Four in the morning
If you had to choose exactly three Baseball teams, which would you choose?
<INPUT type="checkbox" name="baseball_team" value="philadelphia_phillies_1"> Philadelphia Phillies


<INPUT type="checkbox" name="baseball_team" value="philadelphia_phillies_2"> Philadelphia Phillies
<INPUT type="checkbox" name="baseball_team" value="philadelphia_phillies_3"> Philadelphia Phillies


<INPUT type="checkbox" name="baseball_team" value="philadelphia_phillies_4"> Philadelphia Phillies
<INPUT type="checkbox" name="baseball_team" value="philadelphia_phillies_5"> Philadelphia Phillies


<INPUT type="checkbox" name="baseball_team" value="philadelphia_phillies_6"> Philadelphia Phillies


<INPUT type="checkbox" name="baseball_team" value="philadelphia_phillies_7"> Philadelphia Phillies
 
What is your first favorite integer, between 8 and 88?: <INPUT type="text" name="favorite_integer_1">
What is your second favorite integer, greater than 88?: <INPUT type="text" name="favorite_integer_2">
What is your first favorite decimal, between 8.008 and 88.008?: <INPUT type="text" name="favorite_decimal_1">
What is your second favorite decimal, greater than 88.008?: <INPUT type="text" name="favorite_decimal_2">
Favorite foods (pick at least two, as many as four):
          <SELECT NAME="favorite_foods" SIZE=5 MULTIPLE> <OPTION VALUE="aldos_pizza">Pizza from Aldo"s Pizzarama</OPTION> <OPTION VALUE="hot_dogs">Hot dogs</OPTION> <OPTION VALUE="lobster_bisque">Lobster Bisque</OPTION> <OPTION VALUE="shell_fish">Shellfish</OPTION> <OPTION VALUE="ritas_lemon">Rita"s lemon waterice</OPTION> <OPTION VALUE="green beans">Green beans with a splash of lemon</OPTION> <OPTION VALUE="garlic bread">Garlic bread</OPTION></SELECT>

What type of information do you want? Choose at least one of the following:

I would like to be contacted as new information becomes available. <INPUT type="radio" name="contact_new_info" value="YES"> yes <INPUT type="radio" name="contact_new_info" value="NO"> no
Specific information/items:
      <INPUT type="checkbox" name="specific_info_item" value="algorithm"> Algorithm
      <INPUT type="checkbox" name="specific_info_item" value="instructions"> Instructions
      <INPUT type="checkbox" name="specific_info_item" value="folder"> Folder
Please contact me by phone, every night, just as I"m serving the main course to my family. <INPUT type="radio" name="contact_me" value="YES"> yes <INPUT type="radio" name="contact_me" value="NO"> no

 
What is your question (required)?
<TEXTAREA NAME="question_rqd" ROWS="5" COLS="100"></TEXTAREA>
Ask "another" question (not rqd, but max len of 100 chars):
<TEXTAREA NAME="question_20_to_100" ROWS="5" COLS="100"></TEXTAREA>
Password: <INPUT type="text" name="password" size="15" MAXLENGTH="50">
Confirm your password: <INPUT type="password" name="password_confirm" size="15" MAXLENGTH="50">

</FORM> </body> </html>



 </source>
   
  


Email Address Validate

   <source lang="html4strict">
 

<HTML> <HEAD> <SCRIPT language="JavaScript">

</SCRIPT> </HEAD> <BODY> <FORM> <INPUT type="button" value="Click to enter an e-mail address" onClick="validateEmail();"> </BODY> </HTML>


 </source>
   
  


Email form validation

   <source lang="html4strict">
 

<html> <head> <title>JavaScript E-mail-form interface</title> <script language="JavaScript">

</script> </head> <body> <basefont size=3>

E-mail form

send mail button.

<form method="post" enctype="text/plain">

To: <input type="text" name="recipient" size=60>
Subject: <input type="text" name="subject" size=60>
<textarea name="message" rows=4 cols=60></textarea>

<input type="submit" value="Send mail" onClick="sendMail()"> </form> </body> </html>



 </source>
   
  


Form valiation for empty data, file name

   <source lang="html4strict">
 

/* Examples From JavaScript: The Definitive Guide, Fourth Edition Legal matters: these files were created by David Flanagan, and are Copyright (c) 2001 by David Flanagan. You may use, study, modify, and distribute them for any purpose. Please note that these examples are provided "as-is" and come with no warranty of any kind. David Flanagan

  • /

<html> <script language="JavaScript1.1"> // A utility function that returns true if a string contains only // whitespace characters. function isblank(s) {

   for(var i = 0; i < s.length; i++) {
       var c = s.charAt(i);
       if ((c != " ") && (c != "\n") && (c != "\t")) return false;
   }
   return true;

} // This is the function that performs form verification. It is invoked // from the onsubmit event handler. The handler should return whatever // value this function returns. function verify(f) {

   var msg;
   var empty_fields = "";
   var errors = "";
   // Loop through the elements of the form, looking for all 
   // text and textarea elements that don"t have an "optional" property
   // defined. Then, check for fields that are empty and make a list of them.
   // Also, if any of these elements have a "min" or a "max" property defined,
   // verify that they are numbers and in the right range.
   // If the element has a "numeric" property defined, verify that
   // it is a number, but don"t check its range.
   // Put together error messages for fields that are wrong.
   for(var i = 0; i < f.length; i++) {
       var e = f.elements[i];
       if (((e.type == "text") || (e.type == "textarea")) && !e.optional) {
           // first check if the field is empty
           if ((e.value == null) || (e.value == "") || isblank(e.value)) {
               empty_fields += "\n          " + e.name;
               continue;
           }
           // Now check for fields that are supposed to be numeric.
           if (e.numeric || (e.min != null) || (e.max != null)) { 
               var v = parseFloat(e.value);
               if (isNaN(v) || 
                   ((e.min != null) && (v < e.min)) || 
                   ((e.max != null) && (v > e.max))) {
                   errors += "- The field " + e.name + " must be a number";
                   if (e.min != null) 
                       errors += " that is greater than " + e.min;
                   if (e.max != null && e.min != null) 
                       errors += " and less than " + e.max;
                   else if (e.max != null)
                       errors += " that is less than " + e.max;
                   errors += ".\n";
               }
           }
       }
   }
   // Now, if there were any errors, display the messages, and
   // return false to prevent the form from being submitted. 
   // Otherwise return true.
   if (!empty_fields && !errors) return true;
   msg  = "______________________________________________________\n\n"
   msg += "The form was not submitted because of the following error(s).\n";
   msg += "Please correct these error(s) and re-submit.\n";
   msg += "______________________________________________________\n\n"
   if (empty_fields) {
       msg += "- The following required field(s) are empty:" 
               + empty_fields + "\n";
       if (errors) msg += "\n";
   }
   msg += errors;
   alert(msg);
   return false;

} </script>

<form onsubmit="

   this.firstname.optional = true;
   this.phonenumber.optional = true;
   this.zip.min = 0;
   this.zip.max = 99999;
   return verify(this);

"> First name: <input type="text" name="firstname"> Last name: <input type="text" name="lastname">
Address:
<textarea name="address" rows="4" cols="40"></textarea>
Zip Code: <input type="text" name="zip">
Phone Number: <input type="text" name="phonenumber">
<input type="submit"> </form> </html>


 </source>
   
  


Form Validate: is blank, is digit and is integer

   <source lang="html4strict">
 

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html>

   <head>
       <title>jsPro - Validator</title>
       
       <script type="text/javascript">

/**

* +-------------------------------------------------------------------------+
* | jsPro - Error                                                           |
* +-------------------------------------------------------------------------+
* | Copyright (C) 2001-2003 Stuart Wigley                                   |
* +-------------------------------------------------------------------------+
* | This library 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.1 of the License, or (at |
* | your option) any later version.                                         |
* |                                                                         |
* | This library 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 Lesser |
* | General Public License for more details.                                |
* |                                                                         |
* | You should have received a copy of the GNU Lesser General Public License|
* | along with this library; if not, write to the Free Software Foundation, |
* | Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA             |
* +-------------------------------------------------------------------------+
* | Authors:   Stuart Wigley <stuartwigley@yahoo.co.uk>                     |
* |            Randolph Fielding <gator4life@cinci.rr.ru>                  |
* +-------------------------------------------------------------------------+
* $Id: error.js,v 1.15 2003/09/22 04:41:10 gator4life Exp $
*/

/**

* Property used in Error.handleError to specify how errors are
* reported. Permissable values are:
*
* 0    No errors are reported.
* 1    Report the error name and error message using the status bar of the
*      active browser window.
* 2    Report the error name and error message using an alert box.
* 3    Report the error name, error message and debug message using an alert
*      box.
* 4    Report the error name, error message and debug message using a debug
*      window. An instance of the Debug() class must be available.
*/

Error.prototype.debugLevel = 4;

/**

* Uses Error.debugLevel to control how errors are reported. If
* Error.debugLevel is set to 4, you must substitute the name of
* your Debug() instance for oDebug in the line
* var jsProDebugWindow = oDebug.
*
* @summary             handles thrown exceptions
* @author              Stuart Wigley
* @author              Randolph Fielding
* @version             1.2, 09/03/03
* @interface           Error.handleError()
* @requires            Debug.print(vMixedValue, sMessageType)
* @see                 Debug()
* @see                 Debug.print()
*/

Error.prototype.handleError = function() {

   var sDebugMessage = this.debug;
   var sErrorMessage = (sDebugMessage) ? sDebugMessage : "";
   switch (this.debugLevel) {
       case 0 :
           break;
       case 1 :
           window.status = this.name + ": " + this.message;
           break;
       case 2 :
           window.alert(this.name + "\n\n" + this.message);
           break;
       case 3 :
           window.alert(this.name + "\n\n" + this.message + "\n\n" + sErrorMessage);
           break;
       case 4 :
           var jsProDebugWindow = oDebug;
           if (jsProDebugWindow) {
               var oDebugWindow = jsProDebugWindow.debugWindow;
               if (oDebugWindow && !oDebugWindow.closed) {
                   jsProDebugWindow.print(this.name + " " + this.message + " " + sErrorMessage, 1);
               }
           }
   }

}

/**

* Creates an object that is a subclass of Error for handling
* ArrayIndexOutOfBounds exceptions.
*
* @author              Stuart Wigley
* @author              Randolph Fielding
* @version             1.1, 06/27/03
* @interface           new ArrayIndexOutOfBoundsException(sMethodName,
*                      iIndex, iArrayLength)
* @param sMethodName   the name of the method where the exception was thrown
* @param iIndex        the index of a hypothetical array member attempting to
*                      be accessed
* @param iArrayLength  the length of the array
*/

function ArrayIndexOutOfBoundsException(sMethodName, iIndex, iArrayLength) {

   this.name = "ArrayIndexOutOfBoundsException";
   this.message = sMethodName + " has been accessed with an illegal index that is either negative or greater than the size of the array.";
   this.debug = "Attempting to access index " + iIndex.toString() + ", but array has an index range of 0 to " + (iArrayLength - 1).toString() + ".";

} ArrayIndexOutOfBoundsException.prototype = new Error();

/**

* Creates an object that is a subclass of Error for handling IllegalArgument
* exceptions.
*
* @author              Stuart Wigley
* @author              Randolph Fielding
* @version             1.2, 07/24/03
* @interface           new IllegalArgumentException(sMethodName,
*                      vExpectedArgs, iActualArgs)
* @param sMethodName   the name of the method where the exception was thrown
* @param vExpectedArgs the number of arguments expected
* @param iActualArgs   the number of arguments received
*/

function IllegalArgumentException(sMethodName, vExpectedArgs, iActualArgs) {

   this.name = "IllegalArgumentException";
   this.message = sMethodName + " has been passed an illegal number of arguments.";
   this.debug = "Expected " + vExpectedArgs.toString() + " argument(s), but received " + iActualArgs.toString() + " argument(s).";

} IllegalArgumentException.prototype = new Error();

/**

* Creates an object that is a subclass of Error for handling IllegalValue
* exceptions.
*
* @author              Randolph Fielding
* @version             1.0, 09/22/03
* @interface           new IllegalValueException(sMethodName,
*                      sVariableName, vExpectedVal, vActualVal)
* @param sMethodName   the name of the method where the exception was thrown
* @param sVariableName the name of the variable containing the illegal value
* @param vExpectedVal  the value expected in the variable containing the
*                      illegal value
* @param vActualVal    the value currently in the variable containing the
*                      illegal value
*/

function IllegalValueException(sMethodName, sVariableName, vExpectedVal, vActualVal) {

   this.name = "IllegalValueException";
   this.message = sMethodName + " has encountered an illegal value in variable " + sVariableName + "."
   this.debug = "Expected a value of " + vExpectedVal.toString() + ", but contains a value of " + vActualVal.toString() + "."

} IllegalValueException.prototype = new Error();

/**

* Creates an object that is a subclass of Error for handling
* MethodNotAvailable exceptions.
*
* @author              Stuart Wigley
* @author              Randolph Fielding
* @version             1.1, 06/27/03
* @interface           new MethodNotAvailableException(sMethodName,
*                      sMethodNameNA)
* @param sMethodName   the name of the method where the exception was thrown
* @param sMethodNameNA the name of the method that was not available
*/

function MethodNotAvailableException(sMethodName, sMethodNameNA) {

   this.name = "MethodNotAvailableException";
   this.message = "A method has been called that is not available.";
   this.debug = sMethodName + " attempted to call " + sMethodNameNA + ".";

} MethodNotAvailableException.prototype = new Error();

/**

* Creates an object that is a subclass of Error for handling
* PropertyNotAvailable exceptions.
*
* @author              Randolph Fielding
* @version             1.1, 08/01/03
* @interface           new PropertyNotAvailableException(sMethodName,
*                      sPropNameNA)
* @param sMethodName   the name of the method where the exception was thrown
* @param sPropNameNA   the name of the property that was not available
*/

function PropertyNotAvailableException(sMethodName, sPropNameNA) {

   this.name = "PropertyNotAvailableException";
   this.message = "A property has been accessed that is not available.";
   this.debug = sMethodName + " attempted to access " + sPropNameNA + ".";

} PropertyNotAvailableException.prototype = new Error();

/**

* Creates an object that is a subclass of Error for handling TypeMismatch
* exceptions.
*
* @author              Stuart Wigley
* @author              Randolph Fielding
* @version             1.2, 07/24/03
* @interface           new TypeMismatchException(sMethodName,
*                      sExpectedType, sActualType)
* @param sMethodName   the name of the method where the exception was thrown
* @param sExpectedType the name of the expected type of an argument
* @param sActualType   the name of the actual type of an argument
*/

function TypeMismatchException(sMethodName, sExpectedType, sActualType) {

   this.name = "TypeMismatchException";
   this.message = sMethodName + " has been passed an argument with an illegal or inappropriate type.";
   this.debug = "Expected an argument with a type of " + sExpectedType + ", but received an argument with a type of " + sActualType + ".";

} TypeMismatchException.prototype = new Error();

/**

* Creates an object that is a subclass of Error for handling Unknown
* exceptions.
*
* @author              Stuart Wigley
* @author              Randolph Fielding
* @version             1.1, 06/27/03
* @interface           new UnknownException(sMethodName)
* @param sMethodName   the name of the method where the exception was thrown
*/

function UnknownException(sMethodName) {

   this.name = "UnknownException";
   this.message = "An unknown error has occurred in " + sMethodName + ".";

} UnknownException.prototype = new Error();

       </script>
       
       <script type="text/javascript">

/**

* +-------------------------------------------------------------------------+
* | jsPro - Debug                                                           |
* +-------------------------------------------------------------------------+
* | Copyright (C) 2001-2003 Stuart Wigley                                   |
* +-------------------------------------------------------------------------+
* | This library 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.1 of the License, or (at |
* | your option) any later version.                                         |
* |                                                                         |
* | This library 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 Lesser |
* | General Public License for more details.                                |
* |                                                                         |
* | You should have received a copy of the GNU Lesser General Public License|
* | along with this library; if not, write to the Free Software Foundation, |
* | Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA             |
* +-------------------------------------------------------------------------+
* | Authors:   Stuart Wigley <stuartwigley@yahoo.co.uk>                     |
* |            Randolph Fielding <gator4life@cinci.rr.ru>                  |
* +-------------------------------------------------------------------------+
* $Id: debug.js,v 1.6 2003/09/22 05:07:41 gator4life Exp $
*/

/**

* Creates an object that opens a window for debugging.
*
* @author              Stuart Wigley
* @author              Randolph Fielding
* @version             1.1, 09/05/03
* @interface           new Debug()
*/

function Debug() {

   this.debugWindow = window.open("../debug/debug.html", "debug", "width=400,height=600,resizable=yes,scrollbars=yes");

}

/**

* Clears the contents of the debug window.
*
* @author              Stuart Wigley
* @author              Randolph Fielding
* @version             1.1, 09/05/03
* @interface           Debug.clear()
* @return              true if no exceptions are encountered
* @return              null if an exception is encountered
* @throws              IllegalArgumentException
* @throws              UnknownException
*/

Debug.prototype.clear = function() {

   try {
       var vError = null;
       var iNumArguments = arguments.length;
       if (iNumArguments != 0) {
           throw vError = new IllegalArgumentException("Debug.clear", 0, iNumArguments);
       }
       var oMessageContainer = document.getElementById("messageContainer");
       if (!oMessageContainer) {
           throw vError = new UnknownException("Debug.clear");
       }
       while (oMessageContainer.hasChildNodes()) {
           oMessageContainer.removeChild(oMessageContainer.firstChild);
       }
   }
   catch (vError) {
       if (vError instanceof Error) {
           vError.handleError();
       }
   }
   finally {
       return vError ? null : true;
   }

}

/**

* Displays content within the debug window.
*
* @author              Stuart Wigley
* @author              Randolph Fielding
* @version             1.2, 09/05/03
* @interface           Debug.print(vMixedValue)
* @interface           Debug.print(vMixedValue, iMessageType)
* @param vMixedValue   content to be displayed within the debug window
* @param iMessageType  an integer representing the type of content to display
*                      within the debug window (information: 0; error: 1)
*                      (optional)
* @return              true if no exceptions are encountered
* @return              null if an exception is encountered
* @throws              IllegalArgumentException
* @throws              IllegalValueException
* @throws              TypeMismatchException
* @throws              UnknownException
*/

Debug.prototype.print = function(vMixedValue) {

   try {
       var vError = null;
       var iNumArguments = arguments.length;
       var iMessageType = 0;
       if ((iNumArguments < 1) || (iNumArguments > 2)) {
           throw vError = new IllegalArgumentException("Debug.print", "1 or 2", iNumArguments);
       } else if (iNumArguments == 2) {
           iMessageType = arguments[1];
       }
       if ((typeof iMessageType != "number") || (iMessageType.toString().indexOf(".") != -1)) {
           throw vError = new TypeMismatchException("Debug.print", "integer", typeof iMessageType);
       }
       if ((iMessageType != 0) && (iMessageType != 1)) {
           throw vError = new IllegalValueException("Debug.print", "iMessageType", "0 or 1", iMessageType);
       }
       var oDebugWindow = this.debugWindow;
       if (!oDebugWindow || oDebugWindow.closed) {
           throw vError = new UnknownException("Debug.print");
       }
       var oDocument = oDebugWindow.document;
       if (!oDocument) {
           throw vError = new UnknownException("Debug.print");
       }
       var oMessageContainer = oDocument.getElementById("messageContainer");
       if (!oMessageContainer) {
           throw vError = new UnknownException("Debug.print");
       }
       var oTitleRow = oDocument.createElement("tr");
       var oTitleCell = oDocument.createElement("td");
       var oBodyRow = oDocument.createElement("tr");
       var oBodyCell = oDocument.createElement("td");
       if (!oTitleRow || !oTitleCell || !oBodyRow || !oBodyCell) {
           throw vError = new UnknownException("Debug.print");
       }
       var oTitleRowStyle = oTitleRow.style;
       if (oTitleRowStyle) {
           oTitleRowStyle.backgroundColor = "#EEE";
           oTitleRowStyle.fontWeight = 700;
       }
       var sOutputString = vMixedValue.toString();
       var sTitle = "info";
       var sBody = sOutputString;
       if (iMessageType == 1) {
           sTitle = sOutputString.match(/\w+/);
           sBody = sOutputString.replace(/\w+/, "");
           var oBodyCellStyle = oBodyCell.style;
           if (oBodyCellStyle) {
               oBodyCell.style.backgroundColor = "#FCC";
           }
       }
       oMessageContainer.appendChild(oTitleRow);
       oTitleRow.appendChild(oTitleCell);
       oTitleCell.appendChild(oDocument.createTextNode(sTitle));
       oMessageContainer.appendChild(oBodyRow);
       oBodyRow.appendChild(oBodyCell);
       oBodyCell.appendChild(oDocument.createTextNode(sBody));
       oDebugWindow.focus();
   }
   catch (vError) {
       if (vError instanceof Error) {
           vError.handleError();
       }
   }
   finally {
       return vError ? null : true;
   }

}

       </script>
       
       <script type="text/javascript">

/**

* +-------------------------------------------------------------------------+
* | jsPro - Test                                                            |
* +-------------------------------------------------------------------------+
* | Copyright (C) 2001-2003 Stuart Wigley                                   |
* +-------------------------------------------------------------------------+
* | This library 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.1 of the License, or (at |
* | your option) any later version.                                         |
* |                                                                         |
* | This library 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 Lesser |
* | General Public License for more details.                                |
* |                                                                         |
* | You should have received a copy of the GNU Lesser General Public License|
* | along with this library; if not, write to the Free Software Foundation, |
* | Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA             |
* +-------------------------------------------------------------------------+
* | Authors:   Stuart Wigley <stuartwigley@yahoo.co.uk>                     |
* |            Randolph Fielding <gator4life@cinci.rr.ru>                  |
* +-------------------------------------------------------------------------+
* $Id: test.js,v 1.6 2003/09/15 05:07:09 gator4life Exp $
*/

/**

* Creates an object that provides methods for testing all jsPro libraries.
*
* @author              Stuart Wigley
* @version             1.0, 07/24/03
* @interface           new Test()
*/

function Test() { }

/**

* Evaluates and returns the result of a jsPro method using assumptions about
* the structure and ids of HTML elements in the jsPro HTML test files.
*
* @author              Stuart Wigley
* @author              Randolph Fielding
* @version             1.1, 08/20/03
* @interface           Test.evaluateMethod(oButton, sClass)
* @param oButton       the HTML input-button element that is clicked
* @param sClass        the name of the jsPro class instance being tested
* @return              the result of attempting to evaluate a jsPro method
* @return              null if an exception is encountered
* @throws              IllegalArgumentException
* @throws              TypeMismatchException
*/

Test.prototype.evaluateMethod = function(oButton, sClass) {

   try {
       var vError = null;
       var iNumArguments = arguments.length;
       if (iNumArguments != 2) {
           throw vError = new IllegalArgumentException("Error.evaluateMethod", 2, iNumArguments);
       }
       if (typeof oButton != "object") {
           throw vError = new TypeMismatchException("Error.evaluateMethod", "object", typeof oButton);
       }
       if (typeof sClass != "string") {
           throw vError = new TypeMismatchException("Error.evaluateMethod", "string", typeof sClass);
       }
       var sMethodName = oButton.id;
       var oInput1 = document.getElementById(sMethodName + "1");
       var oInput2 = document.getElementById(sMethodName + "2");
       var oInput3 = document.getElementById(sMethodName + "3");
       var oOutput = document.getElementById(sMethodName + "Result");
       var sArguments = "";
       if (oInput1) {
           var sInput1Value = oInput1.value;
           if (sInput1Value != "") {
               var fInput1Value = parseFloat(sInput1Value);
               sArguments += (isNaN(fInput1Value)) ? "\"" + sInput1Value + "\"" : fInput1Value;
           }
       }
       if (oInput2) {
           var sInput2Value = oInput2.value;
           if (sInput2Value != "") {
               var fInput2Value = parseFloat(sInput2Value);
               sArguments += (isNaN(fInput2Value)) ? ", \"" + sInput2Value + "\"" : ", " + fInput2Value;
           }
       }
       if (oInput3) {
           var sInput3Value = oInput3.value;
           if (sInput3Value != "") {
               var fInput3Value = parseFloat(sInput3Value);
               sArguments += (isNaN(fInput3Value)) ? ", \"" + sInput3Value + "\"" : ", " + fInput3Value;
           }
       }
       var vResult = eval(sClass + "." + sMethodName + "(" + sArguments + ")");
   }
   catch (vError) {
       if (vError instanceof Error) {
           vError.handleError();
       }
   }
   finally {
       if (oOutput) {
           oOutput.value = vResult;
       }
   }

}

       </script>
       
       <script type="text/javascript">

/**

* +-------------------------------------------------------------------------+
* | jsPro - Validator                                                       |
* +-------------------------------------------------------------------------+
* | Copyright (C) 2001-2003 Stuart Wigley                                   |
* +-------------------------------------------------------------------------+
* | This library 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.1 of the License, or (at |
* | your option) any later version.                                         |
* |                                                                         |
* | This library 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 Lesser |
* | General Public License for more details.                                |
* |                                                                         |
* | You should have received a copy of the GNU Lesser General Public License|
* | along with this library; if not, write to the Free Software Foundation, |
* | Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA             |
* +-------------------------------------------------------------------------+
* | Authors:   Stuart Wigley <stuartwigley@yahoo.co.uk>                     |
* |            Randolph Fielding <gator4life@cinci.rr.ru>                  |
* +-------------------------------------------------------------------------+
* $Id: validator.js,v 1.2 2003/09/22 03:17:34 gator4life Exp $
*/

/**

* Creates an object that provides methods for performing boolean validations.
*
* @author              Stuart Wigley
* @version             1.0, 09/19/03
* @interface           new Validator()
*/

function Validator() { }

/**

* Determine if the specified value is an empty string or a string composed of
* only whitespace characters.
*
* @summary             is blank string?
* @author              Stuart Wigley
* @author              Randolph Fielding
* @version             1.1, 09/21/03
* @interface           Validator.isBlankString(vValue)
* @param vValue        a value of any datatype
* @return              true if vValue is a string
*                      and is either empty or composed of only whitespace
*                      characters
* @return              false if vValue is either
*                      not a string or is not an empty string and not a
*                      string composed of only whitespace characters
* @return              null if an exception is encountered
* @throws              IllegalArgumentException
*/

Validator.prototype.isBlankString = function(vValue) {

   try {
       var vError = null;
       var iNumArguments = arguments.length;
       if (iNumArguments != 1) {
           throw vError = new IllegalArgumentException("Validator.isBlankString", 1, iNumArguments);
       }
       var bIsBlankString = (typeof vValue != "string") ? false : (vValue.match(/\S/g)) ? false : true;
   }
   catch (vError) {
       if (vError instanceof Error) {
           vError.handleError();
       }
   }
   finally {
       return vError ? null : bIsBlankString;
   }

}

/**

* Determine if the specified value is a single digit.
*
* @summary             is single digit?
* @author              Stuart Wigley
* @author              Randolph Fielding
* @version             1.1, 09/21/03
* @interface           Validator.isDigit(vValue)
* @param vValue        a value of any datatype
* @return              true if vValue is a number
*                      and a single digit
* @return              false if vValue is either
*                      not a number or is not a single digit
* @return              null if an exception is encountered
* @throws              IllegalArgumentException
*/

Validator.prototype.isDigit = function(vValue) {

   try {
       var vError = null;
       var iNumArguments = arguments.length;
       if (iNumArguments != 1) {
           throw vError = new IllegalArgumentException("Validator.isDigit", 1, iNumArguments);
       }
       var bIsDigit = (typeof vValue != "number") ? false : ((vValue > 9) || (vValue.toString().length != 1)) ? false : true;
   }
   catch (vError) {
       if (vError instanceof Error) {
           vError.handleError();
       }
   }
   finally {
       return vError ? null : bIsDigit;
   }

}

/**

* Determine if the specified value is an integer.
*
* @summary             is integer?
* @author              Stuart Wigley
* @author              Randolph Fielding
* @version             1.1, 09/21/03
* @interface           Validator.isInteger(vValue)
* @param vValue        a value of any datatype
* @return              true if vValue is a number
*                      and an integer
* @return              false if vValue is either
*                      not a number or is not an integer
* @return              null if an exception is encountered
* @throws              IllegalArgumentException
*/

Validator.prototype.isInteger = function(vValue) {

   try {
       var vError = null;
       var iNumArguments = arguments.length;
       if (iNumArguments != 1) {
           throw vError = new IllegalArgumentException("Validator.isInteger", 1, iNumArguments);
       }
       var bIsInteger = (typeof vValue != "number") ? false : (vValue.toString().indexOf(".") != -1) ? false : true;
   }
   catch (vError) {
       if (vError instanceof Error) {
           vError.handleError();
       }
   }
   finally {
       return vError ? null : bIsInteger;
   }

}

       </script>        
       <script type="text/javascript">
           var oTest = new Test();
           var oDebug = new Debug();
           var oValidator = new Validator();
       </script>
   </head>
   <body>
<tbody> </tbody>
Validator.isBlankString() <input id="isBlankString1" name="input" type="text" size="5" /> <input id="isBlankString" type="button" value="Calculate >" onclick="oTest.evaluateMethod(this, "oValidator")" /> <input id="isBlankStringResult" name="output" type="text" size="30" readonly="readonly" />
Validator.isDigit() <input id="isDigit1" name="input" type="text" size="5" /> <input id="isDigit" type="button" value="Calculate >" onclick="oTest.evaluateMethod(this, "oValidator")" /> <input id="isDigitResult" name="output" type="text" size="30" readonly="readonly" />
Validator.isInteger() <input id="isInteger1" name="input" type="text" size="5" /> <input id="isInteger" type="button" value="Calculate >" onclick="oTest.evaluateMethod(this, "oValidator")" /> <input id="isIntegerResult" name="output" type="text" size="30" readonly="readonly" />
   </body>

</html>



 </source>
   
  


Form Validator

   <source lang="html4strict">
 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>Form Validator</title> <style type="text/css"> .link{font-family:verdana,arial,helvetica; font-size:8pt; color:#003399; font-weight:normal} .link:hover{font-family:verdana,arial,helvetica; font-size:8pt; color:#FF9900; font-weight:normal} .header{font-family:arial,verdana,helvetica; font-size:30pt; color:#CC0000; font-weight:bold} </style> </head> <body bgcolor="#FFFFFF">

Form Validator


<form name="main" method="get" action="http://www.YourServer.ru/cgi-bin/SomeCgiFile.cgi"> <input type="text" width="30" name="name" style="border:1 solid #000000"> << Name
<input type="text" width="30" name="address" style="border:1 solid #000000"> << Address
<input type="text" width="30" name="age" style="border:1 solid #000000"> << Age
<input type="text" width="30" name="zip" style="border:1 solid #000000"> << Zip

<input type="button" value="Submit" onClick="javascript:validate();" style="border:1 solid #000000; cursor:pointer; cursor:hand; width:120"> <input type="reset" style="border:1 solid #000000; cursor:hand; cursor:pointer; width:120">

</form>


<script language="JavaScript1.2"> /* Written by Premshree Pillai

  Created 2:22 PM 5/12/02
  http://www.qiksearch.ru
  premshree@hotmail.ru */

/* Visit http://www.qiksearch.ru/javascripts.htm for FREE scripts */ /* Location of script : http://www.qiksearch.ru/javascripts/form-validator.htm */ var alphaChars="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ "; var numChars="0123456789"; var error; var error_n; var error_ad; var error_a; var error_z; var errormsg; //--------------------------Customise------------------------------- var isNameReq=true; // True if Name field required else False var isAddressReq=true; // True if Address field required else False var isAgeReq=false; // True if Name Age required else False var isZipReq=true; // True if Name Zip required else False //------------------------------------------------------------------ function reset_error() {

error_n=false;
error_ad=false;
error_a=false;
error_z=false;
errormsg="Following Errors Occured ::\n_____________________________\n\n";

} function validate_name() {

if(isNameReq)
{
 if(document.main.name.value=="")
 {
  errormsg+="Please enter your Name.\n";
  error_n=true;
  document.main.name.focus();
 }
}
for(var i=0; i<document.main.name.value.length; i++)
{
 for(var j=0; j<alphaChars.length; j++)
 {
  if(alphaChars.charAt(j)==document.main.name.value.charAt(i))
  {
   break;
  }
  else
  {
   if(j==(alphaChars.length-1))
   {
    errormsg+=""" + document.main.name.value.charAt(i) + """ + " is an invalid character for Name.\n";
    error_n=true;
   }
  }
  if(error_n)
  {
   document.main.name.select();
  }
 }
}

} function validate_address() {

if(isAddressReq)
{
 if(document.main.address.value=="")
 {
  errormsg+="Please enter your Address.\n";
  error_ad=true;
  if(!error_n)
  {
   document.main.address.focus();
  }
 }
}

} function validate_age() {

if(isAgeReq)
{
 if(document.main.age.value=="")
 {
  errormsg+="Please enter your Age.\n";
  error_a=true;
  if((!error_n)&&(!error_ad))
  {
   document.main.age.focus();
  }
 }
}
for(var i=0; i<document.main.age.value.length; i++)
{
 for(var j=0; j<numChars.length; j++)
 {
  if(numChars.charAt(j)==document.main.age.value.charAt(i))
  {
   break;
  }
  else
  {
   if(j==(numChars.length-1))
   {
    errormsg+=""" + document.main.age.value.charAt(i) + """ + " is an invalid character for Age.\n";
    error_a=true;
   }
  }
  if(error_a)
  {
   if((!error_n)&&(!error_ad))
   {
    document.main.age.select();
   }
  }
 }
}

} function validate_zip() {

if(isZipReq)
{
 if(document.main.zip.value=="")
 {
  errormsg+="Please enter Zip.\n";
  error_z=true;
  if((!error_n)&&(!error_ad)&&(!error_a))
  {
   document.main.zip.focus();
  }
 }
}
for(var i=0; i<document.main.zip.value.length; i++)
{
 for(var j=0; j<numChars.length; j++)
 {
  if(numChars.charAt(j)==document.main.zip.value.charAt(i))
  {
   break;
  }
  else
  {
   if(j==(numChars.length-1))
   {
    errormsg+=""" + document.main.zip.value.charAt(i) + """ + " is an invalid character for Zip.\n";
    error_z=true;
   }
  }
  if(error_z)
  {
   if((!error_n)&&(!error_ad)&&(!error_a))
   {
    document.main.zip.select();
   }
  }
 }
}

} function validate() {

reset_error();
validate_name();
validate_address();
validate_age();
validate_zip();
if(error_n||error_ad||error_a||error_z)
{
 error=true;
}
else
{
 error=false;
}
if(!error)
{
 document.main.submit();
}
else
{
 alert(errormsg);
}

} </script>



This is a JavaScript Form validator. When you submit the form, it validates the data you entered in the various fields.

You are allowed to enter only alphabetical characters in the "Name" field. You can enter only numerical data in the "Age" and "Zip" fields.

You can also choose which fields are "required" by the user to be filled.


<a href="http://www.qiksearch.ru" class="link">&#169 2002 Premshree Pillai. All rights reserved.</a>

</body> </html>


 </source>
   
  


Form Validator: time, date email, phone number, age etc

   <source lang="html4strict">
 

/*

* JavaScript Validation file
*
* programmer: Jason Geissler
*
* purpose: To encapsulate the mundane date, ssn, phone number, and time validation
*          in one file
*
* date: March 19, 2002
*
*/


<HTML> <HEAD> <SCRIPT language="JavaScript">

</SCRIPT> <META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0"> <TITLE></TITLE> <Script language="javascript"> /******************************************************************************

* JavaScript Validation file
*
* programmer: Jason Geissler
*
* purpose: To encapsulate the mundane date, ssn, phone number, and time validation
*          in one file
*
* date: March 19, 2002
*
*****************************************************************************/

/******************************************************************************

* method: ValidateSSN
*
* author: Jason Geissler
*
* date: March 19, 2002
*
* parameters: ssn (Social Security number)
*
* purpose: To validate a social security number to make sure the number
*          is valid
*****************************************************************************/

function ValidateSSN(ssn) {

 if((ssn.length == 11) || (ssn.length == 9)) {     // Make sure it"s a valid length
   var segments = ssn.split("-")                   // Split the number into segments delimited by "-"
   if ((segments.length == 3)) {
     if ((segments[0].length == 3) && (segments[1].length == 2) && (segments[2].length == 4)) {
       for (var i = 0; i < 3; i++) {
         if (isNaN(segments[i]))                   // Check to see if the number is a valid number
           return false;
       }
       return true;
     }
   }
   else {
     if ((segments.length == 1) && (!isNaN(ssn)))  // Check to see if the number is a valid number
       return true;
   }
 }
 return false;

}

/******************************************************************************

* method: ValidatePhoneNumber
*
* author: Jason Geissler
*
* date: March 19, 2002
*
* parameters: phoneNum (Phone number)
*
* purpose: To validate a phone number to make sure the number
*          is valid. This is based from the American system of
*          3 digit area code 3 digit city code then the number.
*****************************************************************************/

function ValidatePhoneNumber(phoneNum) {

 var segments;    // Breaks up the phone numbers into area code, city code and number
 var i;
   
 // Check to see if they put any "( )" around the area code
 // If so we"ll strip those out.
 phoneNum = phoneNum.replace("(", "");
 phoneNum = phoneNum.replace(")", "");
 
 switch (phoneNum.length) {
   case 7:                                    /* The XXXXXXX case */
     if(!isNaN(phoneNum))                    // Check to see if they"re real numbers
       return true;
     break;
           
   case 8:                                    /* The XXX-XXXX case */
     segments = phoneNum.split("-");
     if (segments.length == 2) {
       if((segments[0].length == 3) && (segments[1].length == 4)) {
         for (i = 0; i < 2; i++) {            // Check to see if they"re real numbers
           if (isNaN(segments[i]))
             return false;
         }
         return true;
       }
     }
     break;
     
   case 10:                                  /* The XXXXXXXXXX case */
     if(!isNaN(phoneNum))                    // Check to see if they"re real numbers
       return true;
     break;
     
   case 12:                                  /* The XXX-XXX-XXXX case */
     segments = phoneNum.split("-");
     if (segments.length == 3) {
       if((segments[0].length == 3) && (segments[1].length == 3) && (segments[2].length == 4)) {
         for (i = 0; i < 3; i++) {            // Check to see if they"re real numbers
           if (isNaN(segments[i]))
             return false;
         }
         return true;
       }
     }
     break;
       
   default:                                  /* If non of the above then fail it */
     break;
 }
 return false;

}

/******************************************************************************

* method: ValidateTime
*
* author: Jason Geissler
*
* date: March 19, 2002
*
* parameters: time, formatType (1 - Standard format, 2- Military format)
*
* purpose: To validate a time in HH:MM format
*****************************************************************************/

function ValidateTime(time, formatType) {

 var segments;      // Break up of the time into hours and minutes
 var hour;          // The value of the entered hour
 var minute;        // The value of the entered minute
   
 time = time.replace(".", ":");
   
 if (formatType == 1) {                                          /* Validating standard time */
   segments = time.split(":");
   
   if (segments.length == 2) {
     segments[1] = segments[1].substring(0,2);
     hour = segments[0];                                          // Test the hour
     if ((hour > 12) || (hour < 1))  
       return false;
           
     minute = segments[1];                                        // Test the minute
     if (( minute <= 59) && (minute >= 0)) 
       return true;
   }
     
 }
 else {                                                          /* Validating military time */
   segments = time.split(":");
   
   if (segments.length == 2) {
     hour = segments[0];                                          // Test the hour
     if ((hour > 23) || (hour <= -1)) 
       return false;
       
     minute = segments[1];                                        // Test the minute
     if (( minute <= 59) && (minute >= 0)) 
       return true;
   }
 }
 return false;

}

/******************************************************************************

* method: ValidateAdvancedTime
*
* author: Jason Geissler
*
* date: March 20, 2002
*
* parameters: time, formattype(1- Standard, 2- military)
*
* purpose: Calls the ValidateTime for hours and minutes but this also 
*          calculates seconds. Time must be in XX:XX:XX style.
*****************************************************************************/

function ValidateAdvancedTime(time, formatType){

 time = time.replace(".", ":");
 var newTime = time.substring(0, (time.indexOf(":") + 3)); // Strip out the seconds
 var status = ValidateTime(newTime, formatType);
 
 if(status == false) 
   return false;
   
 var seconds = time.substring(time.indexOf(":") + 4, time.length);
 if(seconds.length > 2) 
   seconds = seconds.substring(0, 2);                      // Remove any AM/PM afterwards
   
 if(!isNaN(seconds)) {                                      // Make sure its a number and it"s between 0 and 59
   if((seconds <= 59) && (seconds >= 0)) 
     return true;
 }
 return false;  

}

/******************************************************************************

* method: ValidateDate
*
* author: Jason Geissler
*
* date: March 20, 2002
*
* parameters: date, formattype(1- US, 2- International)
*
* purpose: Validates the passed in date for accuarcy supports
*          US and international date format.
*****************************************************************************/ 

function ValidateDate(date, formattype) {

 var segments;
 var year;
 var month;
 var day;
 var status;
 var i;
 var leapYear = false;
 
 if(formattype == 1) {                                 /* Standard time validation note this doesn"t support a time */
   // check for time
   var spaceIndex = date.indexOf(" ");
   if (spaceIndex > 0) {
     time = date.substring(spaceIndex, date.length);
     date = date.substring(0, spaceIndex);
     status = ValidateAdvancedTime(time, 1);
     if (status == false) 
       return false;
   }
   // replace any "-" or "." or "/" with ""
   for (i = 0; i < 2; i++) {
     date = date.replace("-", "/");
     date = date.replace(".", "/");
   }
   var slashIndex = date.indexOf("/");
   if(slashIndex == -1) 
     date = HandleSlashes(date);
   
   // Check to see if the date is a valid length
   // Supports MMDDYY, MMDDYYYY, (M)M/(D)D/YY, (M)M/(D)D/YYYY
   segments = date.split("/");
   month = segments[0];
   day = segments[1];
   year = segments[2];
       
   // Start testing
   status = TestYear(year);
   if(status == false) 
     return false;
     
   if (year.length == 4) 
     leapYear = IsLeapYear(year);
       
   status = TestMonth(month);
   if(status == false) 
     return false;
       
   status = TestDay(day, month, leapYear);
   if(status == true) 
     return true;
 }
 else {                                                /* International Date Validation YYYY-MM-DD */
   if(date.length > 10) {
     var time = date.substring(10, date.length);
     status = ValidateAdvancedTime(time, 2);
     if (status == false) 
       return false;
     date = date.substring(0,10)
   } 
   // Get our date in a common format
   for (i = 0; i < 2; i++) {
     date = date.replace(".", "-");
     date = date.replace("/", "-");
   }
   
   var dashIndex = date.indexOf("-");
   
   if (dashIndex == -1) 
     date = HandleDashes(date);
       
   segments = date.split("-");
   year = segments[0];
   month = segments[1];
   day = segments[2];
   
   // Start testing
   if (year.length == 4) {
     status = TestYear(year);
     if(status == false) 
       return false;
     leapYear = IsLeapYear(year);
   }
   else 
     return false;
       
   status = TestMonth(month);
   if(status == false) 
     return false;
       
   status = TestDay(day, month, leapYear);
   if(status == true) 
     return true;
 }
 return false;

}

/******************************************************************************

* method: TestYear
*
* author: Jason Geissler
*
* date: March 21, 2002
*
* parameters: year
*
* purpose: Test for a valid year can be any number either YY or YYYY
*****************************************************************************/

function TestYear(year) {

 // Test the year
 if((year.length == 4) || (year.length == 2)) {
   // we won"t restrict what a user wants to enter for a date since this method is generic
    if (!isNaN(year)) 
     return true;
 }
 return false;

}

/******************************************************************************

* method: TestMonth
*
* author: Jason Geissler
*
* date: March 21, 2002
*
* parameters: month
*
* purpose: Test for a valid month has to be MM
*****************************************************************************/

function TestMonth(month) {

 // Test the month
 if ((isNaN(month)) || (month < 1) || (month > 12)){
   return false;
 }
 return true;

}

/******************************************************************************

* method: TestDay
*
* author: Jason Geissler
*
* date: March 21, 2002
*
* parameters: day
*
* purpose: Test for a valid day has to be DD
*****************************************************************************/

function TestDay(day, month, leapYear) {

 month -= 0;  // Convert the month into a Number for the case"s
 
 if(!isNaN(day)) {
   switch(month) {  // Test the days for a particular month
     case 1:
     case 3:
     case 5:
     case 7:
     case 8:
     case 10:
     case 12:
       if ((day >= 1) && (day <= 31)) 
         return true;
       break;
         
     case 4:
     case 6:
     case 9:
     case 11:
       if ((day >= 1) && (day <= 30)) 
         return true;
       break;
         
     case 2:
       if(leapYear) {
         if ((day >= 1) && (day <= 29)) 
           return true;
       }
       else {
         if ((day >= 1) && (day <= 28)) 
           return true;
       }
       break;
           
     default:
       break;
   }
 }  
 return false;  

}

/******************************************************************************

* method: ValidateEmailAddr
*
* author: Jason Geissler
*
* date: March 23, 2002
*
* parameters: emailAddress
*
* purpose: Makes sure the user entered a valid e-mail address. Supports the
*          extensions .ru, .org, .gov, .net, .edu
*****************************************************************************/

function ValidateEmailAddr(emailAddress){

 var atSymbol = emailAddress.indexOf("@");                                  // Get the index of the "@"
 var period = emailAddress.lastIndexOf(".");                                // Get the value of the last "."
 var suffix = emailAddress.substring(period + 1, emailAddress.length);
 
 // Make sure the "@" symbol and "." is in a valid location
 if (((atSymbol != 0) && (atSymbol != -1)) && (suffix.length == 3) && (atSymbol < period) && (atSymbol != period - 1)) { 
   if ((suffix == "com") || (suffix == "org") || (suffix == "gov") || (suffix == "net") || (suffix == "edu")) 
     return true;
 }
 return false;

}

/******************************************************************************

* method: IsLeapYear
*
* author: Jason Geissler
*
* date: April 28, 2002
*
* parameters: year
*
* purpose: Checks to see if the year is a leap year, we can do this
*          with 4 digit years
*****************************************************************************/

function IsLeapYear(year) {

 var betweenYears = 4;                  // We also know that there is 4 years between leap years
 var leapYear = 2000;
 year = leapYear - year;                // Set year to the difference see if it"s divisible by 4
 var remainder = year % betweenYears;
 if (remainder == 0) {
   return true;
 }
 return false;

}

/******************************************************************************

* method: HandleSlashes
*
* author: Jason Geissler
*
* date: September 12, 2002
*
* parameters: date
*
* purpose: Inserts a "/" into a date based on date size
*****************************************************************************/

function HandleSlashes(date) {

 date = date.substring(0, 2) + "/" + date.substring(2, 4) + "/" + date.substring(4, date.length);  
 return date;

}

/******************************************************************************

* method: HandleDashes
*
* author: Jason Geissler
*
* date: September 12, 2002
*
* parameters: date
*
* purpose: Inserts a "-" into a date based on date size
*****************************************************************************/

function HandleDashes(date) {

 date = date.substring(0, 4) + "-" + date.substring(4, 6) + "-" + date.substring(6, date.length);
 return date;

} /******************************************************************************

* method: CalculateAge
*
* author: Jason Geissler
*
* date: April 15, 2003
*
* parameters: date
*
* purpose: Calculates an age for a date
*****************************************************************************/

var format = ""; // Can be Years, Months, Days for age

function CalculateAge(date) {

 var slashIndex = date.indexOf("/");
 var birthday, birthmonth, birthyear;
 
 if (slashIndex != -1) { // With slashes
   var segments = date.split("/");
   birthmonth = segments[0];
   birthday = segments[1];
   birthyear = segments[2];
 }
 else {                  // No slashes
   birthmonth = date.substring(0, 2);
   birthday = date.substring(2, 4);
   birthyear = date.substring(4, date.length);
 }
 
 var today = new Date();
 var thisDay = today.getDate();        // Returns the day of the month
 var thisMonth = today.getMonth() + 1; // Need to add a one since the month is zero based - January
 var thisYear = today.getFullYear();   // Returns the year
 
 var yearsDiff = CalculateYear(birthyear, thisYear);
 var monthsDiff = CalculateMonth(birthmonth, thisMonth);
 var daysDiff = CalculateDay(birthday, thisDay);
 format = "Years"; // set the format to years
 
 // For the year is greater than zero
 if (yearsDiff > 0) {
   if (monthsDiff > 0) {    // Month is greater than zero so return we have our age
     return yearsDiff;
   }
   else if (monthsDiff < 0) { // Month is less than zero so return the age minus 1
     if (yearsDiff != 1) {
       return yearsDiff - 1;
     }
     else {
       if (monthsDiff == -11) { // Turn of the year
         if (daysDiff >= 0) {   // greater than one month
           format = "Months";
           return 1;
         }
         else {                // less than one month
           format = "Days";
           return thisDay - (31 - birthday);
         }
       }
       else {
         format = "Months";    // Next year but not quite a year old
         if (daysDiff >= 0) {
           return thisMonth + (12 - birthmonth);
         }
         else {
           return thisMonth + (12 - birthmonth) - 1;
         }
       }
     }      
   }  
   else {                 // We are in the persons birth month
     if (daysDiff >= 0) { // Today is greater or equal to the person"s birthdate
       return yearsDiff;
     }
     else if (daysDiff < 0 && yearsDiff != 1) { // Today is less than the person"s birthdate
       return yearsDiff - 1;
     }
     else {
       format = "Months";
       return 11;
     }
   }
 }
 else {  // For the year equaling zero or same year as birthdate
   format = "Months";
   if (monthsDiff > 0) { // Later in the same year
     if (daysDiff >= 0) {
       return monthsDiff;
     }
     else {
       if (monthsDiff != 1) {
         return monthsDiff - 1;
       }
       else {
         format = "Days";
         return thisDay + (DaysInMonth(birthmonth, birthyear) - birthday);
       }
     }
   }
   else {  // Same month as birth month
     format = "Days";
     if (daysDiff == 0) {
       return 1; // Today"s the birthdate
     }
     else {
       return daysDiff;
     }
   }
 }              

} /******************************************************************************

* method: CalculateYear
*
* author: Jason Geissler
*
* date: April 15, 2003
*
* parameters: birthYear, thisYear
*
* purpose: Calculates the year based on the offsets between the birthyear and 
*          thisYear
*****************************************************************************/

function CalculateYear(birthYear, thisYear) {

 return thisYear - birthYear;

} /******************************************************************************

* method: CalculateMonth
*
* author: Jason Geissler
*
* date: April 15, 2003
*
* parameters: birthMonth, thisMonth
*
* purpose: Calculates the month based on the offsets between the birthMonth and 
*          thisMonth
*****************************************************************************/

function CalculateMonth(birthMonth, thisMonth) {

 return thisMonth - birthMonth;

} /******************************************************************************

* method: CalculateDay
*
* author: Jason Geissler
*
* date: April 15, 2003
*
* parameters: birthday, thisday
*
* purpose: Calculates the month based on the offsets between the birthDay and 
*          thisDay
*****************************************************************************/

function CalculateDay(birthDay, thisDay) {

 return thisDay - birthDay;

} /******************************************************************************

* method: DaysInMonth
*
* author: Jason Geissler
*
* date: April 15, 2003
*
* parameters: birthday, thisday
*
* purpose: Calculates the days in the month based on month (year for leap year
*
*****************************************************************************/

function DaysInMonth(month, year) {

 month -= 0;
 if (month == 2) {
   var leapYear = IsLeapYear(year);
 }
 
 switch (month) {
   case 1:
   case 3:
   case 5:
   case 7:
   case 8:
   case 10:
   case 12:
     return 31;
   case 4:
   case 6:
   case 9:
   case 11:
     return 30;
   case 2:
     if (leapYear) {
       return 29;
     }
     else {
       return 28;
     }
 }

} </Script> </HEAD> <BODY>

<P>Phone Number: <INPUT id=text1 name=text1><INPUT id=button1 name=button1 type=button value="Phone Number" onclick="JavaScript:Tester(document.all.item("text1").value); return true;">

Social Security Number: <INPUT id=text2 name=text2><INPUT id=button2 name=button2 type=button value=SSN onclick="JavaScript:Tester2(document.all.item("text2").value); return true;">

Standard Date: <INPUT id=text3 name=text3><INPUT id=button3 name=button3 type=button value=Date onclick="JavaScript:Tester3(document.all.item("text3").value); return true;">

International Date: <INPUT id=text4 name=text4><INPUT id=button4 name=button4 type=button value=Date onclick="JavaScript:Tester4(document.all.item("text4").value); return true;">

Standard Time: <INPUT id=text5 name=text5><INPUT id=button5 name=button5 type=button value=Time onclick="JavaScript:Tester5(document.all.item("text5").value); return true;">

International Time: <INPUT id=text6 name=text6><INPUT id=button6 name=button6 type=button value=Time onclick="JavaScript:Tester6(document.all.item("text6").value); return true;">

Standard Time with seconds: <INPUT id=text7 name=text7><INPUT id=button7 name=button7 type=button value="Advanced Time" onclick="JavaScript:Tester7(document.all.item("text7").value); return true;">

International Time with seconds: <INPUT id=text8 name=text8><INPUT id=button8 name=button8 type=button value="Advanced Time" onclick="JavaScript:Tester8(document.all.item("text8").value); return true;">

Email Address: <INPUT id=text9 name=text9><INPUT id=button9 name=button9 type=button value="Email Address" onclick="JavaScript:Tester9(document.all.item("text9").value); return true;">

Age Calculation: <INPUT id=text10 name=text10><INPUT id=button10 name=button10 type=button value="Age Calculator" onclick="JavaScript:Tester10(document.all.item("text10").value); return true;">    <INPUT type=text name=age id=age disabled> <INPUT type=text name=format id=format disabled>

The Validator.js file is to be included in your HTML, ASP, JSP, or PHP pages. It"s a client-side validation file and listed below are the methods that a programmer can call to validate certain data. Note that I will be adding a e-mail validation method in the coming days. There are other methods in the file that can validate certain pieces of data ex: day, month, year. Also there are error handling methods that I will be taking out soon in another version and letting the webpage developer handle the error in their own liking.</P> <P align=left> To include this file just copy and paste this code.</P> <P align = left>    <Script language="JavaScript" src="../Validator.js"></Script> </P> <P align=left>Just make sure the file is in the same directory as your webpage.


   Methods</Font>
   </TD>
   
   Purpose</FONT>
   </Td>
 </TR>

</TD></TR>
 ValidateSSN(ssn)
 </TD>
   
   Validates a social security number in either 
XXX-XX-XXXX or XXXXXXXXX format.
</TD> </Tr>

</TD></TR>
 ValidatePhoneNumber(num)
 </TD>
 
 Validates an American style phone number in
either XXX-XXXX, XXXXXXX, XXX-XXX-XXXX,
or XXXXXXXXXX formats.
</TD> </TR>

</TD></TR>
 ValidateTime(time, format)
 </TD>
 
   Validates the time in HH:MM format. Supports
both Standard (1) or Military (2) time formats.
</TD> </TR>

</TD></TR>
  ValidateAdvancedTime(time, format)
 </TD>
 
   Just like ValidateTime but it checks for seconds
by using this format HH:MM:SS.
</Td> </TR>

</TD></TR>
 ValidateDate(date, format)
 </TD>
 
   Validates the date in two formats. US format
(1), can be MMDDYY, MM/DD/YY,
MM/DD/YYYY, and MMDDYYYY. The
international format (2) has YYYY-MM-DD </BR> after the date HH:MM:SS.
</TD> </TR>

</TD></TR>
   ValidateEmailAddr(EmailAddress)
 </TD>
 
   Validates an email address. Supports .ru, .net, 
.edu, .gov, and .org
</TD> </TR>

</TD></TR>
   CalculateAge(birthdate)
 </TD>
   
   Calculates an age return a number of years, months, or days
   depending on how old the person is. If older than one year the 
   age format will be in years, if older than 1 month but less than 
   one year the format will be in months. If born or less than one month 
   the format will be in days. Currently handles MM/DD/YYYY or MMDDYYYY formats.
   Use the ValidateDate method to make sure the user input is valid before using
   the CalculateAge method to ensure a valid birthdate and age.
   
 </TD>
 </TR>

</TD></TR>
 </Table>

</BODY> </HTML>



 </source>
   
  


Form value validation and onsubmit action

   <source lang="html4strict">

<html> <head> <title>Form Validation</title> <script type="text/javascript"> function checkValid() {

   var cityField = document.forms[0]["city"];
   if (cityField.value != "Van") {
       var cityDiv = document.getElementById("citydiv");
       cityDiv.style.fontWeight = "bold";
       return false;
   } else {
       return true;
   }

} </script> </head> <body> <form name="formexample" id="formexample" action="#">

City: <input id="city" name="city">
<input id="submit" type="submit">

</form> <script type="text/javascript">

   function init() {
       document.forms[0].onsubmit = function() { return checkValid(this) };
   }
   window.onload = init;

</script> </body> </html>

 </source>
   
  


Illegal sub string validation

   <source lang="html4strict">
 

<HTML> <HEAD> <TITLE>validate_form.js -- Example: Illegal Sub-Strings (2/2)</TITLE> <SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript"> /**

 VALIDATE_FORM.JS
 Comprehensive solution for validating HTML forms.
 Copyright (C) 2002, Jeff Epstein, jeff_epstein@yahoo.ru, http://www.jeffyjeffy.ru#download
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 This program 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 General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
**/

/**

 See validate_form_documentation.html for information.
 NOTES TO SELF
   //alert("The CODE for getRCBSMTrackerArrIdx=" + getRCBSMTrackerArrIdx);
   I would like to add a function to get the number of elements that have a (any) value.
**/

//GLOBAL VARIABLES...start (do not alter this section)

 var sDBG_INDENT = "     ";
 var asRCBSM_TRACKER_NAME = "";
 var aiRCBSM_TRACKER_SEL_COUNT = "";
 var aiRCBSM_TRACKER_ARR_IDX = "";
 var iELEMENT_COUNT = -1;
 var bFIRST_DEBUG_SCREEN_SEEN = false;
 var sCURRENT_LENGTH_FOR_TA = "~CURRLEN~";
 var bPHONE_ZIP_FORMATS_VALIDATED = false;

//GLOBAL VARIABLES...end /**

 All messages must be at least one character in length.  If they are empty string, its as if they do not exist.
**/

function getFormErrorMsgs(f_orm, s_userErrorPrefix, i_debugPerScreen) {

 //This initialization function must be the very first line.
 initializeLocalVars();
 if(!arePhoneZipFormatsValid())  {
   return;
 }
 crashIfBadConfiguration(f_orm);
 if(hasCrashed())  {
   //For whatever reason utility.crash() was called, indicating
   //an error has occured.  Get out.  Get out while you still
   //can.
   return;
 }
 outputDebugging(f_orm, i_debugPerScreen);
 return getUserErrors(f_orm, s_userErrorPrefix);

} /**

 PRIVATE FUNCTIONS...start
**/
 function arePhoneZipFormatsValid()  {
   if(bPHONE_ZIP_FORMATS_VALIDATED)  {
     //Phone and zip code formats are checked only once.
     //They"ve already been checked once and are all were
     //found to be valid.
     return true;
   }
   //The formats have not yet been checked, or they were, but
   //were found to be invalid.
   var i = -1;
   var siPMin = "";
   var siPMax = "";
   for(i = 1; i < 11; i++)  {
     siPMin = eval("siPHONE_" + i + "_MINIMUM");
     siPMax = eval("siPHONE_" + i + "_MAXIMUM");
     if(!isPhoneFormatValid("false", siPMin, siPMax))  {
       alert("---  validate_form.js ERROR  ---\n\nPhone number format invalid:\n\tsiPHONE_" + i + "_MINIMUM="" + eval("siPHONE_" + i + "_MINIMUM") + ""\n\tsiPHONE_" + i + "_MAXIMUM="" + eval("siPHONE_" + i + "_MAXIMUM") + ""\n\nThe specific error message follows...");
       isPhoneFormatValid("true", siPMin, siPMax);
       return false;
     }
   }
   var siZRMin = "";
   var siZRMax = "";
   var siZAMin = "";
   var siZAMax = "";
   for(i = 1; i < 11; i++)  {
     siZRMin = eval("siZIP_" + i + "_RQD_MINIMUM");
     siZRMax = eval("siZIP_" + i + "_RQD_MAXIMUM");
     siZAMin = eval("siZIP_" + i + "_ALT_MINIMUM");
     siZAMax = eval("siZIP_" + i + "_ALT_MAXIMUM");
     if(!isZipFormatValid("false", siZRMin, siZRMax, siZAMin, siZAMax))  {
       alert("---  validate_form.js ERROR  ---\n\nZip code format invalid:\n\tsiZIP_" + i + "_RQD_MINIMUM="" + eval("siZIP_" + i + "_RQD_MINIMUM") + ""\n\tsiZIP_" + i + "_RQD_MAXIMUM="" + eval("siZIP_" + i + "_RQD_MAXIMUM") + ""\n\tsiZIP_" + i + "_ALT_MINIMUM="" + eval("siZIP_" + i + "_ALT_MINIMUM") + ""\n\tsiZIP_" + i + "_ALT_MAXIMUM="" + eval("siZIP_" + i + "_ALT_MAXIMUM") + ""\n\nThe specific error message follows...");
       isZipFormatValid("true", siZRMin, siZRMax, siZAMin, siZAMax)
       return false;
     }
   }
   bPHONE_ZIP_FORMATS_VALIDATED = true;
   return true;
 }
  function crashIfBadConfiguration(f_orm)  {
   crashIfMissing(f_orm, "f_orm", "validate_form.getFormErrorMsgs");
   crashIfBadBSSA("f_orm.asGlobalBadSubStrs", f_orm.asGlobalBadSubStrs);
   f_orm.bsGlobalTrimSpaces = getOptBooleanStringVF(f_orm.bsGlobalTrimSpaces, "f_orm.bsGlobalTrimSpaces");
   if(hasCrashed())  {
     return;
   }
   for(var i = 0; i < f_orm.length; i++)  {
     if(f_orm[i].type == "text"  ||  f_orm[i].type == "password")  {
       crashIfBadCfg_text(f_orm, f_orm[i]);
     }  else if(f_orm[i].type == "textarea")  {
       crashIfBadCfg_textarea(f_orm, f_orm[i]);
     }  else if(f_orm[i].type == "checkbox"  ||  f_orm[i].type == "select-multiple")  {
       crashIfBadCfg_cbsm(f_orm, i);
     }  else if(f_orm[i].type == "radio"  ||  f_orm[i].type == "select-one")  {
       crashIfBadCfg_rso(f_orm, i);
     }
   }
 }
 function outputDebugging(f_orm, i_debugPerScreen)  {
   if(!i_debugPerScreen  ||  i_debugPerScreen == -1)  {
     //No debugging is requested
     return;
   }
   if(typeof(i_debugPerScreen) != "number"  ||  i_debugPerScreen < 1)  {
     return crashVF("i_debugPerScreen is not required (currently "" + i_debugPerScreen + ""), but when provided, it must be a number (currently "" + typeof(i_debugPerScreen) + "") either equal to -1, or greater than zero.");
   }
   var iDebugItemsTotal = 0;
   var iDebugItemsThisRound = 0;
   var sDebugBuffer = "";
   var sDebugThisItem = "";
   for(var i = 0; i < f_orm.length; i++)  {
     if(f_orm[i].type == "text"  ||  f_orm[i].type == "password")  {
       sDebugThisItem = getDebugging_text(f_orm, f_orm[i]);
     }  else if(f_orm[i].type == "textarea")  {
       sDebugThisItem = getDebugging_textarea(f_orm, f_orm[i]);
     }  else if(f_orm[i].type == "checkbox"  ||  f_orm[i].type == "select-multiple")  {
       sDebugThisItem = getDebugging_cbsm(f_orm, i);
     }  else if(f_orm[i].type == "radio"  ||  f_orm[i].type == "select-one")  {
       sDebugThisItem = getDebugging_rso(f_orm, i);
     }
     if(sDebugThisItem)  {
       iDebugItemsTotal++;
       iDebugItemsThisRound++;
       sDebugBuffer += sDebugThisItem + "\n";
       if(iDebugItemsThisRound >= i_debugPerScreen)  {
         sDebugBuffer = getGlobalDebugging(sDebugBuffer, f_orm);
         alert("---  validate_form.js  DEBUGGING  (" + (iDebugItemsTotal - iDebugItemsThisRound + 1) + " to " + iDebugItemsTotal + " of " + iELEMENT_COUNT + ")  ---\n\n" + sDebugBuffer);
         iDebugItemsThisRound = 0;
         sDebugBuffer = "";
       }
       sDebugThisItem = "";
     }
   }
   if(sDebugBuffer)  {
     sDebugBuffer = getGlobalDebugging(sDebugBuffer, f_orm);
     alert("---  validate_form.js  DEBUGGING  (" + (iDebugItemsTotal - iDebugItemsThisRound + 1) + " to " + iDebugItemsTotal + " of " + iELEMENT_COUNT + ")  ---\n\n" + sDebugBuffer);
   }
 }
 function getGlobalDebugging(s_debugBuffer, f_orm)  {
   if(!bFIRST_DEBUG_SCREEN_SEEN)  {
     bFIRST_DEBUG_SCREEN_SEEN = true;
     var sGlobalDebug = "";
     if(f_orm.asGlobalBadSubStrs)  {
       sGlobalDebug = sDBG_INDENT + "f_orm.asGlobalBadSubStrs=  [ " + f_orm.asGlobalBadSubStrs + " ]\n";
     }
     if(f_orm.bsGlobalTrimSpaces == "true")  {
       sGlobalDebug += sDBG_INDENT + "f_orm.bsGlobalTrimSpaces=  "true"\n";
     }
     if(sGlobalDebug)  {
       return "---  GLOBAL SETTINGS  ---\n" + sGlobalDebug + "\n\n" + s_debugBuffer;
     }
   }
   //Either the first debugging screen has already been displayed, or
   //this is the first screen, but there is no global settings
   return s_debugBuffer;
 }
 function getUserErrors(f_orm, s_prefix)  {
   var sUserErrors = "";
   for(var i = 0; i < f_orm.length; i++)  {
     if(f_orm[i].type == "text"  ||  f_orm[i].type == "password")  {
       sUserErrors += getUserErrors_text(f_orm, i, s_prefix);
     }  else if(f_orm[i].type == "textarea")  {
       sUserErrors += getUserErrors_textarea(f_orm, i, s_prefix);
     }  else if(f_orm[i].type == "checkbox"  ||  f_orm[i].type == "select-multiple")  {
       sUserErrors += getUserErrors_cbsm(f_orm, i, s_prefix);
     }  else if(f_orm[i].type == "radio"  ||  f_orm[i].type == "select-one")  {
       sUserErrors += getUserErrors_rso(f_orm, i, s_prefix);
     }
   }
   return sUserErrors;
 }
 /**
   form_element must be provided, and a form element...START
  **/
   function getDebuggingNameType(form_element)  {
     return "---  " + form_element.name + "  ---          [" + form_element.type + "]\n";
   }
   function getDebuggingMsgRequired(s_msgRequired)  {
     if(s_msgRequired)  {
       return sDBG_INDENT + "sMsgRequired:  "" + s_msgRequired + ""\n";
     }
     return "";
   }
   function getDebuggingValue(s_value)  {
     if(s_value)  {
       return sDBG_INDENT + "VALUE:  "" + s_value + ""\n";
     }
     return "";
   }
 /**
   form_element must be provided, and a form element...END
  **/
 /**
   Do not call this function without first calling crashIfBadCfg_cbsm for the form-and-form-element.
  **/
 function getUserErrors_cbsm(f_orm, i_arrIdx, s_prefix)  {
   var feCbsm = f_orm[i_arrIdx];
   var sMsgRequired = "";
   var sMsgMCRange = "";
   var iMCMin = "";
   var iMCMax = "";
   if(feCbsm.type == "checkbox")  {
     if(getFirstArrIdx(feCbsm.name) != i_arrIdx)  {
       //This checkbox has already had its user errors retrieved.
       return "";
     }
     //This checkbox has not yet had its user errors retrieved.
     sMsgRequired = f_orm[feCbsm.name + ".sMsgRequired"];
     sMsgMCRange = f_orm[feCbsm.name + ".sMsgMCRange"];
     iMCMin = f_orm[feCbsm.name + ".iMCMin"];
     iMCMax = f_orm[feCbsm.name + ".iMCMax"];
   }  else  {
     //this is a select-multiple type...which has not yet had its
     //user errors retrieved.
     sMsgRequired = feCbsm.sMsgRequired
     sMsgMCRange = feCbsm.sMsgMCRange
     iMCMin = feCbsm.iMCMin
     iMCMax = feCbsm.iMCMax
   }
   var iMCSelCount = getMCSelectedCount(feCbsm.name);
   if(sMsgRequired  &&  iMCSelCount < 1)  {
     return s_prefix + sMsgRequired + "\n";
   }
   //If its required, a value has been selected.
   if(iMCSelCount < 1)  {
     //Its not required, and no value has been selected,
     //which is okay.
     return "";
   }
   if((iMCMin  &&  iMCMin > iMCSelCount)  ||
      (iMCMax  &&  iMCMax < iMCSelCount))  {
     return s_prefix + sMsgMCRange + "\n";
   }
   return "";
 }
 /**
   Do not call this function without first calling crashIfBadCfg_cbsm for the form-and-form-element.
  **/
 function getDebugging_cbsm(f_orm, i_arrIdx)  {
   var feCbsm = f_orm[i_arrIdx];
   var sMsgRequired = "";
   var sMsgMCRange = "";
   var iMCMin = "";
   var iMCMax = "";
   if(feCbsm.type == "checkbox")  {
     if(getFirstArrIdx(feCbsm.name) != i_arrIdx)  {
       //This checkbox has already been debugged.
       return "";
     }
     //This checkbox has not yet been debugged
     sMsgRequired = f_orm[feCbsm.name + ".sMsgRequired"];
     sMsgMCRange = f_orm[feCbsm.name + ".sMsgMCRange"];
     iMCMin = f_orm[feCbsm.name + ".iMCMin"];
     iMCMax = f_orm[feCbsm.name + ".iMCMax"];
   }  else  {
     //this is a select-multiple type...which has not yet been debugged.
     sMsgRequired = feCbsm.sMsgRequired
     sMsgMCRange = feCbsm.sMsgMCRange
     iMCMin = feCbsm.iMCMin
     iMCMax = feCbsm.iMCMax
   }
   var s = getDebuggingNameType(feCbsm) + getDebuggingMsgRequired(sMsgRequired);
   if(sMsgMCRange)  {
     s += sDBG_INDENT + "sMsgMCRange:  "" + sMsgMCRange + ""\n";
     if(iMCMin)  {
       s += sDBG_INDENT + sDBG_INDENT + "iMCMin:  " + iMCMin + "\n";
     }
     if(iMCMax)  {
       s += sDBG_INDENT + sDBG_INDENT + "iMCMax:  " + iMCMax + "\n";
     }
   }
   var iMCSelCount = getMCSelectedCount(feCbsm.name);
   if(iMCSelCount > 0)  {
     s += sDBG_INDENT + "NUMBER OF CHOICES SELECTED:  " + iMCSelCount + "\n";
   }
   return s;
 }
 function crashIfBadCfg_cbsm(f_orm, i_arrIdx)  {
   conditionallyAddRCBSM(f_orm, i_arrIdx);
   var feCbsm = f_orm[i_arrIdx];
   var sMsgMCRange = "";
   var iMCMin = "";
   var iMCMax = "";
   var iTotalOptions = -1;
   var sErrVarPre = "";
   var sErrVarPost = "";
   if(feCbsm.type == "checkbox")  {
     if(getFirstArrIdx(feCbsm.name) != i_arrIdx)  {
       //This checkbox has already been validated.
       return "";
     }
     //This checkbox has not yet been validated
     sMsgMCRange = f_orm[feCbsm.name + ".sMsgMCRange"];
     iMCMin = f_orm[feCbsm.name + ".iMCMin"];
     iMCMax = f_orm[feCbsm.name + ".iMCMax"];
     iTotalOptions = f_orm[feCbsm.name].length;
     sErrVarPre = "f_orm["" + feCbsm.name;
     sErrVarPost = ""]";
   }  else  {
     //this is a select-multiple type...which has not yet been validated.
     sMsgMCRange = feCbsm.sMsgMCRange;
     iMCMin = feCbsm.iMCMin;
     iMCMax = feCbsm.iMCMax;
     iTotalOptions = feCbsm.length;
     sErrVarPre = feCbsm.name;
     sErrVarPost = "";
   }
   if(sMsgMCRange)  {
     if(!iMCMin  &&  !iMCMax)  {
       return crashVF(sErrVarPre + ".sMsgMCRange" + sErrVarPost + " has been provided (currently "" + sMsgMCRange + ""), but neither " + sErrVarPre + ".iMCMin" + sErrVarPost + " nor " + sErrVarPre + ".iMCMax" + sErrVarPost + " have been provided.  At least one of these bounds are required.");
     }
     if(iMCMin)  {
       if(!isInteger(iMCMin))  {
         return crashVF(sErrVarPre + ".iMCMin" + sErrVarPost + " has been provided, but is not of type number.  Currently of type "" + typeof(iMCMin) + "" and equal to "" + iMCMin + "".");
       }
       if(iMCMin < 1  ||  iMCMin > iTotalOptions)  {
         return crashVF(sErrVarPre + ".iMCMin" + sErrVarPost + " has been provided (currently " + iMCMin + "), but is either less than one, or greater than the total number of options (" + iTotalOptions + ").");
       }
     }
     if(iMCMax)  {
       if(!isInteger(iMCMax))  {
         return crashVF(sErrVarPre + ".iMCMax" + sErrVarPost + " has been provided, but is not of type number.  Currently of type "" + typeof(iMCMax) + "" and equal to "" + iMCMax + "".");
       }
       if(iMCMax < 1  ||  iMCMax > iTotalOptions)  {
         return crashVF(sErrVarPre + ".iMCMax" + sErrVarPost + " has been provided (currently " + iMCMax + "), but is either less than one, or greater than the total number of options (" + iTotalOptions + ").");
       }
     }
     if(iMCMin  &&  iMCMax  &&  iMCMin > iMCMax)  {
       return crashVF(sErrVarPre + ".sMsgMCRange" + sErrVarPost + " has been provided (currently "" + sMsgMCRange + ""), and both " + sErrVarPre + ".iMCMin" + sErrVarPost + " (currently " + iMCMin + ") and " + sErrVarPre + ".iMCMax" + sErrVarPost + " (currently " + iMCMax + ") have been provided.  However, iMCMin must be less than or equal to iMCMax, which it is not.");
     }
   }  else if(iMCMin  ||  iMCMax)  {
     return crashVF(sErrVarPre + ".sMsgMCRange" + sErrVarPost + " has *not* been provided, but at least one of " + sErrVarPre + ".iMCMin" + sErrVarPost + " (currently "" + iMCMin + "") or " + sErrVarPre + ".iMCMax" + sErrVarPost + " (currently "" + iMCMax + "") has been provided.");
   }
 }
 /**
   Do not call this function without first calling crashIfBadCfg_rso for the form-and-form-element.
  **/
 function getUserErrors_rso(f_orm, i_arrIdx, s_prefix)  {
   var feRso = f_orm[i_arrIdx];
   var sValue = "";
   var sMsgRequired = "";
   if(feRso.type == "radio")  {
     if(getFirstArrIdx(feRso.name) != i_arrIdx)  {
       //We already debugged this radio element.
       return "";
     }
     sMsgRequired = f_orm[feRso.name + ".sMsgRequired"];
     sValue = getRadioValue(f_orm, feRso.name);
   }  else if(feRso.selectedIndex > -1) {
     sMsgRequired = feRso.sMsgRequired;
     sValue = feRso[feRso.selectedIndex].value;
   }
   if(sMsgRequired  &&  !sValue)  {
     return s_prefix + sMsgRequired + "\n";
   }
   //If its required, a value has been provided.
   return "";
 }
 /**
   Do not call this function without first calling crashIfBadCfg_rso for the form-and-form-element.
  **/
 function getDebugging_rso(f_orm, i_arrIdx)  {
   var feRso = f_orm[i_arrIdx];
   var sValue = "";
   var sMsgRequired = "";
   if(feRso.type == "radio")  {
     if(getFirstArrIdx(feRso.name) != i_arrIdx)  {
       //We already debugged this radio element.
       return "";
     }
     sMsgRequired = f_orm[feRso.name + ".sMsgRequired"];
     sValue = getRadioValue(f_orm, feRso.name);
   }  else if(feRso.selectedIndex > -1) {
     sMsgRequired = feRso.sMsgRequired;
     sValue = feRso[feRso.selectedIndex].value;
   }
   return getDebuggingNameType(feRso) + getDebuggingMsgRequired(sMsgRequired) + getDebuggingValue(sValue);
 }
 function getRadioValue(f_orm, s_radioName)  {
   var feRadio = f_orm[s_radioName];
   for(var i = 0; i < feRadio.length; i++)  {
     if(feRadio[i].checked)  {
       return feRadio[i].value;
     }
   }
   return "";
 }
 function crashIfBadCfg_rso(f_orm, i_arrIdx)  {
   var feRso = f_orm[i_arrIdx];
   if(feRso.type == "radio")  {
     conditionallyAddRCBSM(f_orm, i_arrIdx);
   }  else  {
     iELEMENT_COUNT++;
   }
   //Nothing to validate.  The only attribute that
   //can be associated to a radio or select-one type
   //is sMsgRequired...  Which either is or isn"t...
   //doesn"t matter which.
 }
 function conditionallyAddRCBSM(f_orm, i_arrIdx)  {
   var feCbsm = f_orm[i_arrIdx];
   if(wasRCBSMalreadyFound(feCbsm.name))  {
     //We already analyzed this element.
     return;
   }
   iELEMENT_COUNT++;
   addRCBSMtoTracker(f_orm, feCbsm, i_arrIdx);
 }
 /**
   Do not call this function without first calling crashIfBadCfg_textarea for the form-and-form-element.
  **/
 function getUserErrors_textarea(f_orm, i_arrIdx, s_prefix)  {
   var feTA = f_orm[i_arrIdx];
   if(feTA.sMsgRequired  &&  !feTA.value)  {
     return s_prefix + feTA.sMsgRequired + "\n";
   }
   if(!feTA.value)  {
     return "";
   }
   if(needsToBeTrimmed(f_orm, feTA))  {
     feTA.value = trimSpaces(feTA.value);
   }
   if(feTA.sMsgBadLength  &&
      (feTA.value.length < feTA.iMinLength  ||
       feTA.value.length > feTA.iMaxLength))  {
     return s_prefix + getBadLengthMsg(feTA) + "\n";
   }
   return getBadSubStrMessage(feTA.value, f_orm, feTA.asBadSubStrs, feTA.bsNoBadSubStrings, s_prefix, feTA.sMsgBadSubStr);
 }
 function getBadLengthMsg(fe_tta)  {
   var sMsg = fe_tta.sMsgBadLength;
   var iCLArrIdx = sMsg.indexOf(sCURRENT_LENGTH_FOR_TA);
   if(iCLArrIdx != -1)  {
     sMsg = sMsg.substring(0, iCLArrIdx) + fe_tta.value.length + sMsg.substring((iCLArrIdx + sCURRENT_LENGTH_FOR_TA.length), (sMsg.length + 1));
   }
   return sMsg;
 }
 function getBadSubStrMessage(s_value, f_orm, as_badSubStrs, bs_noBadSubStrings, s_prefix, s_errorMessage)  {
   if(!s_value)  {
     //Theres no value, so it can"t have any illegal sub-string.
     return "";
   }
   if(bs_noBadSubStrings == "true")  {
     //This element is exempt.
     return "";
   }
   //"x" is important...1/2
   var asBadSubStrs = "x";
   if(f_orm.asGlobalBadSubStrs)  {
     asBadSubStrs = f_orm.asGlobalBadSubStrs;
   }
   if(as_badSubStrs)  {
     asBadSubStrs = as_badSubStrs;
   }
   //"x" is important...2/2
   if(asBadSubStrs == "x")  {
     //There are no sub-strings to consider illegal.
     return "";
   }
   //There *are* sub-strings to be considered illegal.
   for(var i = 0; i < asBadSubStrs.length; i++)  {
     if(s_value.indexOf(asBadSubStrs[i]) != -1)  {
       return s_prefix + s_errorMessage + "\n";
     }
   }
   return "";
 }
 /**
   Do not call this function without first calling crashIfBadCfg_textarea for the form-and-form-element.
  **/
 function getDebugging_textarea(f_orm, fe_textarea)  {
   var s = getDebuggingNameType(fe_textarea) + getDebuggingMsgRequired(fe_textarea.sMsgRequired);
   if(fe_textarea.bsNoBadSubStrings == "true")  {
     s += sDBG_INDENT + "bsNoBadSubStrings:  "" + fe_textarea.bsNoBadSubStrings + ""\n";
   }  else if(f_orm.asGlobalBadSubStrs  ||  fe_textarea.asBadSubStrs)  {
     if(fe_textarea.asBadSubStrs)  {
       s += sDBG_INDENT + "asBadSubStrs:  [" + fe_textarea.asBadSubStrs + "]\n";
     }  else if(f_orm.asGlobalBadSubStrs)  {
       s += sDBG_INDENT + "f_orm.asGlobalBadSubStrs:  [" + f_orm.asGlobalBadSubStrs + "]\n";
     }
     s += sDBG_INDENT + sDBG_INDENT + "sMsgBadSubStr:  "" + fe_textarea.sMsgBadSubStr + ""\n";
   }
   if(fe_textarea.sMsgBadLength)  {
     s += sDBG_INDENT + "sMsgBadLength:  "" + fe_textarea.sMsgBadLength + ""\n";
     if(fe_textarea.iMinLength)  {
       s += sDBG_INDENT + sDBG_INDENT + "iMinLength:  " + fe_textarea.iMinLength + "\n";
     }
     if(fe_textarea.iMaxLength)  {
       s += sDBG_INDENT + sDBG_INDENT + "iMaxLength:  " + fe_textarea.iMaxLength + "\n";
     }
   }
   s += getDebuggingValue(fe_textarea.value);
   return s;
 }
 function crashIfBadCfg_textarea(f_orm, fe_textarea)  {
   crashIfMissing(fe_textarea, "fe_textarea", "validate_form.crashIfBadCfg_textarea");
   if(fe_textarea.type != "textarea")  {
     return crashVF("fe_textarea must be of type "text".  Currently "" + fe_textarea.type + ""...SANITY CHECK.  SHOULD NEVER HAPPEN.");
   }
   iELEMENT_COUNT++;
   var sName = sName;
   fe_textarea.bsNoBadSubStrings = getOptBooleanStringVF(fe_textarea.bsNoBadSubStrings, "f_orm." + sName + ".bsNoBadSubStrings");
   crashIfNBSSError(sName, fe_textarea.bsNoBadSubStrings, f_orm.asGlobalBadSubStrs, fe_textarea.asBadSubStrs);
   if(fe_textarea.bsNoBadSubStrings == "false"  &&
     (f_orm.asGlobalBadSubStrs  ||  fe_textarea.asBadSubStrs)  &&
     !fe_textarea.sMsgBadSubStr)  {
     return crashVF("Either f_orm.asGlobalBadSubStrs (currently [" + f_orm.asGlobalBadSubStrs + "]) or f_orm." + sName + ".asBadSubStrs (currently [" + fe_textarea.asBadSubStrs + "]) have  been provided, AND f_orm." + sName + ".bsNoBadSubStrings equals "false" (meaning there are sub-strings that are illegal for this field).  This means that f_orm." + sName + ".sMsgBadSubStr is required.  However, f_orm." + sName + ".sMsgBadSubStr has not been provided.");
   }
   crashIfBadSpaceTrimConfig(f_orm, fe_textarea);
   var iMin = fe_textarea.iMinLength;
   var iMax = fe_textarea.iMaxLength;
   if(fe_textarea.sMsgBadLength)  {
     if(!iMin  &&  !iMax)  {
       return crashVF("f_orm." + sName + ".sMsgBadLength has been provided (currently "" + fe_textarea.sMsgBadLength + ""), but neither f_orm." + sName + ".iMinLength nor f_orm." + sName + ".iMaxLength have been provided.");
     }
     if(iMin  &&  (!isInteger(iMin)  ||  iMin < 1))  {
       return crashVF("Both f_orm." + sName + ".sMsgBadLength (currently "" + fe_textarea.sMsgBadLength + "") and f_orm." + sName + ".iMinLength (currently " + iMin + ") have been provided, but iMinLength must be an integer, and at least equal to one.  Additional information:  f_orm." + sName + ".iMaxLength currently equals " + iMax + ".");
     }
     if(iMax  &&  (!isInteger(iMax)  ||  iMax < 1))  {
       return crashVF("Both f_orm." + sName + ".sMsgBadLength (currently "" + fe_textarea.sMsgBadLength + "") and f_orm." + sName + ".iMaxLength (currently "" + iMax + "") have been provided, but iMaxLength must be an integer, and at least equal to one.  Additional information:  f_orm." + sName + ".iMinLength currently equals " + iMin + ".");
     }
     if(iMin  &&  iMax  &&  iMin > iMax)  {
       return crashVF("f_orm." + sName + ".sMsgBadLength (currently "" + fe_textarea.sMsgBadLength + ""), f_orm." + sName + ".iMinLength (currently " + iMin + ") and f_orm." + sName + ".iMaxLength (currently " + iMax + ") have all been provided, but iMinLength must be less than or equal to iMaxLength.");
     }
   }  else if(iMin  ||  iMax)  {
     return crashVF("f_orm." + sName + ".sMsgBadLength has *not* been provided, but at least one of f_orm." + sName + ".iMinLength (currently " + iMin + ") and f_orm." + sName + ".iMaxLength (currently " + iMax + ") have been provided.");
   }
 }
 /**
   Do not call this function without first calling crashIfBadCfg_textarea for the form-and-form-element.
  **/
 function getUserErrors_text(f_orm, i_arrIdx, s_prefix)  {
   var feText = f_orm[i_arrIdx];
   if(needsToBeTrimmed(f_orm, feText))  {
     feText.value = trimSpaces(feText.value);
   }
   if(feText.sMsgRequired  &&  !feText.value)  {
     return s_prefix + feText.sMsgRequired + "\n";
   }
   if(!feText.value)  {
     return "";
   }
   //It is assumed/expected that there is only one "sMsgTxt"
   //variables associated to feText.  The only reason that
   //the following ifs are not else-ifs, is because of the
   //for loop of eval statements.
   if(feText.sMsgTxtEmail)  {
     if(!isEmail(feText.value))  {
       return s_prefix + feText.sMsgTxtEmail + "\n";
     }
   }  else if(feText.sMsgTxtInt)  {
     if(!isInteger(feText.value)  ||
        (feText.iIntMin  &&  feText.iIntMin > feText.value)  ||
        (feText.iIntMax  &&  feText.iIntMax < feText.value))  {
       return s_prefix + feText.sMsgTxtInt + "\n";
     }
   }  else if(feText.sMsgTxtDec)  {
     if(!isDecimal(feText.value)  ||
        (feText.iDecMin  &&  feText.iDecMin > feText.value)  ||
        (feText.iDecMax  &&  feText.iDecMax < feText.value))  {
       return s_prefix + feText.sMsgTxtDec + "\n";
     }
   }  else if(feText.sMsgTxtPhone)  {
     var sPhoneStripped = getValidPhone1(feText.value);
     if(!sPhoneStripped)  {
       return s_prefix + feText.sMsgTxtPhone + "\n";
     }
     feText.value = sPhoneStripped;
   }  else if(feText.sMsgTxtZip)  {
     var sZipStripped = getValidZip1(feText.value);
     if(!sZipStripped)  {
       return s_prefix + feText.sMsgTxtZip + "\n";
     }
     feText.value = sZipStripped;
   }  else  {
     for(var i = 1; i < 11; i++)  {
       if(eval("feText.sMsgTxtPhone" + i))  {
         var sPhoneStripped = eval("getValidPhone" + i + "(feText.value)");
         if(!sPhoneStripped)  {
           return s_prefix + eval("feText.sMsgTxtPhone" + i) + "\n";
         }
         feText.value = sPhoneStripped;
         break;    //There is only one sMsgTxt* per element
       }
       if(eval("feText.sMsgTxtZip" + i))  {
         var sZipStripped = eval("getValidZip" + i + "(feText.value)");
         if(!sZipStripped)  {
           return s_prefix + eval("feText.sMsgTxtZip" + i) + "\n";
         }
         feText.value = sZipStripped;
         break;    //There is only one sMsgTxt* per element
       }
     }
   }
   if(feText.sMsgBadLength  &&  feText.value.length < feText.iMinLength)  {
     return s_prefix + getBadLengthMsg(feText) + "\n";
   }
   return getBadSubStrMessage(feText.value, f_orm, feText.asBadSubStrs, feText.bsNoBadSubStrings, s_prefix, feText.sMsgBadSubStr);
 }
 function needsToBeTrimmed(f_orm, fe_tta)  {
   if(!fe_tta.value)  {
     return false;
   }
   if(fe_tta.bsDontTrimSpaces == "true")  {
     return false;
   }
   if(f_orm.bsGlobalTrimSpaces == "true"  ||  fe_tta.bsTrimSpaces == "true")  {
     return isSurroundedBySpace(fe_tta.value);
   }
 }
 /**
   Do not call this function without first calling crashIfBadCfg_text for the form-and-form-element.
  **/
 function getDebugging_text(f_orm, fe_text)  {
   var sDBG_INDENT = "     ";
   var s = getDebuggingNameType(fe_text) + getDebuggingMsgRequired(fe_text.sMsgRequired);
   var bEM = fe_text.sMsgTxtEmail;
   var bInt = fe_text.sMsgTxtInt;
   var bDec = fe_text.sMsgTxtDec;
   var bZC = fe_text.sMsgTxtZip;
   var bZC1 = fe_text.sMsgTxtZip1;
   var bZC2 = fe_text.sMsgTxtZip2;
   var bZC3 = fe_text.sMsgTxtZip3;
   var bZC4 = fe_text.sMsgTxtZip4;
   var bZC5 = fe_text.sMsgTxtZip5;
   var bZC6 = fe_text.sMsgTxtZip6;
   var bZC7 = fe_text.sMsgTxtZip7;
   var bZC8 = fe_text.sMsgTxtZip8;
   var bZC9 = fe_text.sMsgTxtZip9;
   var bZC10 = fe_text.sMsgTxtZip10;
   var bPN = fe_text.sMsgTxtPhone;
   var bPN1 = fe_text.sMsgTxtPhone1;
   var bPN2 = fe_text.sMsgTxtPhone2;
   var bPN3 = fe_text.sMsgTxtPhone3;
   var bPN4 = fe_text.sMsgTxtPhone4;
   var bPN5 = fe_text.sMsgTxtPhone5;
   var bPN6 = fe_text.sMsgTxtPhone6;
   var bPN7 = fe_text.sMsgTxtPhone7;
   var bPN8 = fe_text.sMsgTxtPhone8;
   var bPN9 = fe_text.sMsgTxtPhone9;
   var bPN10 = fe_text.sMsgTxtPhone10;
   if(bEM)  {
     s += sDBG_INDENT + "sMsgTxtEmail:  "" + fe_text.sMsgTxtEmail + ""\n";
   }
   if(bZC)  {
     s += sDBG_INDENT + "sMsgTxtZip:  "" + fe_text.sMsgTxtZip + ""\n";
   }
   if(bPN)  {
     s += sDBG_INDENT + "sMsgTxtPhone:  "" + fe_text.sMsgTxtPhone + ""\n";
   }
   for(var i = 1; i < 11; i++)  {
     if(eval("bPN" + i))  {
       s += sDBG_INDENT + "sMsgTxtPhone" + i + ":  "" + eval("fe_text.sMsgTxtPhone" + i) + ""\n";
     }
     if(eval("bZC" + i))  {
       s += sDBG_INDENT + "sMsgTxtZip" + i + ":  "" + eval("fe_text.sMsgTxtZip" + i) + ""\n";
     }
   }
   if(bInt)  {
     s += sDBG_INDENT + "sMsgTxtInt:  "" + fe_text.sMsgTxtInt + ""\n";
     if(fe_text.iIntMin)  {
       s += sDBG_INDENT + sDBG_INDENT + "iIntMin:  "" + fe_text.iIntMin + ""\n";
     }
     if(fe_text.iIntMax)  {
       s += sDBG_INDENT + sDBG_INDENT + "iIntMax:  "" + fe_text.iIntMax + ""\n";
     }
   }
   if(bDec)  {
     s += sDBG_INDENT + "sMsgTxtDec:  "" + fe_text.sMsgTxtDec + ""\n";
     if(fe_text.iDecMin)  {
       s += sDBG_INDENT + sDBG_INDENT + "iDecMin:  "" + fe_text.iDecMin + ""\n";
     }
     if(fe_text.iDecMax)  {
       s += sDBG_INDENT + sDBG_INDENT + "iDecMax:  "" + fe_text.iDecMax + ""\n";
     }
   }
   if(fe_text.bsNoBadSubStrings == "true")  {
     s += sDBG_INDENT + "bsNoBadSubStrings:  "" + fe_text.bsNoBadSubStrings + ""\n";
   }  else if(!bInt  &&  !bDec  &&
                  !bZC   &&  !bZC1  &&  !bZC2  &&  !bZC3  &&  !bZC4  &&  !bZC5  &&
                  !bZC6  &&  !bZC7  &&  !bZC8  &&  !bZC9  &&  !bZC10  &&
                  !bPN   &&  !bPN1  &&  !bPN2  &&  !bPN3  &&  !bPN4  &&  !bPN5  &&
                  !bPN6  &&  !bPN7  &&  !bPN8  &&  !bPN9  &&  !bPN10  &&
              (f_orm.asGlobalBadSubStrs  ||  fe_text.asBadSubStrs))  {
     var sSecondIndent = "";
     if(fe_text.asBadSubStrs)  {
       s += sDBG_INDENT + "asBadSubStrs:  [" + fe_text.asBadSubStrs + "]\n";
       sSecondIndent = sDBG_INDENT;
     }
   }
   if(fe_text.sMsgBadLength)  {
     s += sDBG_INDENT + "sMsgBadLength:  "" + fe_text.sMsgBadLength + ""\n" + sDBG_INDENT + sDBG_INDENT + "iMinLength:  " + fe_text.iMinLength + "\n";
     if(fe_text.maxLength)  {
       s += sDBG_INDENT + sDBG_INDENT + "MAXLENGTH:  " + fe_text.MAXLENGTH + "\n";
     }
   }
   s += getDebuggingValue(fe_text.value);
   return s;
 }
 function crashIfBadCfg_text(f_orm, fe_text)  {
   crashIfMissing(fe_text, "fe_text", "validate_form.crashIfBadCfg_text");
   if(fe_text.type != "text"  &&  fe_text.type != "password")  {
     return crashVF("fe_text must be of type "text" or "password".  Currently "" + fe_text.type + ""...SANITY CHECK.  SHOULD NEVER HAPPEN.");
   }
   var sName = fe_text.name;
   iELEMENT_COUNT++;
   var bEM = fe_text.sMsgTxtEmail;
   var bInt = fe_text.sMsgTxtInt;
   var bDec = fe_text.sMsgTxtDec;
   var bZC = fe_text.sMsgTxtZip;
   var bPN = fe_text.sMsgTxtPhone;
   var iSpecialTypes = 0;
   var sSpecialTypes = "";
   if(bEM)  {
     iSpecialTypes++;
     sSpecialTypes += "sMsgTxtEmail...";
   }
   if(bInt)  {
     iSpecialTypes++;
     sSpecialTypes += "sMsgTxtInt...";
     crashIfBadIntDecCfg(fe_text.iIntMin, fe_text.iIntMax, "false", sName, "iIntMin", "iIntMax");
   }  else if(fe_text.iIntMin  ||  fe_text.iIntMax)  {
     return crashVF("f_orm." + sName + ".sMsgTxtInt has *not* been provided, but one or both of the sub-variables " + sName + ".iIntMin (currently "" + fe_text.iIntMin + "")/" + sName + ".iIntMax (currently "" + fe_text.iIntMax + "") have been provided.");
   }
   if(bDec)  {
     iSpecialTypes++;
     sSpecialTypes += "sMsgTxtDec...";
     crashIfBadIntDecCfg(fe_text.iDecMin, fe_text.iDecMax, "true", sName, "iDecMin", "iDecMax");
   }  else if(fe_text.iDecMin  ||  fe_text.iDecMax)  {
     return crashVF("f_orm." + sName + "." + sAnIntADec + " has *not* been provided, but one or both of the sub-variables " + sName + ".iDecMin (currently "" + fe_text.iDecMin + "")/" + sName + ".iDecMax (currently "" + fe_text.iDecMax + "") have been provided.");
   }
   if(bPN)  {
     iSpecialTypes++;
     sSpecialTypes += "sMsgTxtPhone...";
   }
   for(var i = 1; i < 11; i++)  {
     eval("var bPN" + i + " = fe_text.sMsgTxtPhone" + i);
     if(eval("bPN" + i))  {
       iSpecialTypes++;
       sSpecialTypes += "sMsgTxtPhone" + i + "...";
     }
   }
   if(bZC)  {
     iSpecialTypes++;
     sSpecialTypes += "sMsgTxtZip...";
   }
   for(var i = 1; i < 11; i++)  {
     eval("var bZC" + i + " = fe_text.sMsgTxtZip" + i);
     if(eval("bZC" + i))  {
       iSpecialTypes++;
       sSpecialTypes += "sMsgTxtZip" + i + "...";
     }
   }
   if(iSpecialTypes > 1)  {
     return crashVF("f_orm." + sName + " is of type "text", but has " + iSpecialTypes + " special text types associated to it.  Zero or one of the following special types may be used for a text form element:  sMsgTxtEmail, sMsgTxtInt, sMsgTxtDec, sMsgTxtZip, sMsgTxtZip1, sMsgTxtZip2, sMsgTxtZip3, sMsgTxtZip4, sMsgTxtZip5, sMsgTxtZip6, sMsgTxtZip7, sMsgTxtZip8, sMsgTxtZip9, sMsgTxtZip10, sMsgTxtPhone, sMsgTxtPhone1, sMsgTxtPhone2, sMsgTxtPhone3, sMsgTxtPhone4, sMsgTxtPhone5, sMsgTxtPhone6, sMsgTxtPhone7, sMsgTxtPhone8, sMsgTxtPhone9, sMsgTxtPhone10.\n\nActually existing special types found:  " + sSpecialTypes);
   }
   crashIfBadBSSA("f_orm." + sName + ".asBadSubStrs", fe_text.asBadSubStrs);
   fe_text.bsNoBadSubStrings = getOptBooleanStringVF(fe_text.bsNoBadSubStrings, "f_orm." + sName + ".bsNoBadSubStrings");
   crashIfNBSSError(sName, fe_text.bsNoBadSubStrings, f_orm.asGlobalBadSubStrs, fe_text.asBadSubStrs);
   if(fe_text.bsNoBadSubStrings == "false"  &&  !bInt  &&  !bDec  &&
        !bZC   &&  !bZC1  &&  !bZC2  &&  !bZC3  &&  !bZC4  &&  !bZC5  &&
        !bZC6  &&  !bZC7  &&  !bZC8  &&  !bZC9  &&  !bZC10  &&
        !bPN   &&  !bPN1  &&  !bPN2  &&  !bPN3  &&  !bPN4  &&  !bPN5  &&
        !bPN6  &&  !bPN7  &&  !bPN8  &&  !bPN9  &&  !bPN10  &&
     (f_orm.asGlobalBadSubStrs  ||  fe_text.asBadSubStrs)  &&
     !fe_text.sMsgBadSubStr)  {
     return crashVF("Either f_orm.asGlobalBadSubStrs (currently [" + f_orm.asGlobalBadSubStrs + "]) or f_orm." + sName + ".asBadSubStrs (currently [" + fe_text.asBadSubStrs + "]) have  been provided, AND f_orm." + sName + ".bsNoBadSubStrings equals "false" (meaning there are sub-strings that are illegal for this field) AND this text/password field does not have a "number" special type (sMsgTxtInt, sMsgTxtDec, sMsgTxtZip, sMsgTxtZip1, sMsgTxtZip2, sMsgTxtZip3, sMsgTxtZip4, sMsgTxtZip5, sMsgTxtZip6, sMsgTxtZip7, sMsgTxtZip8, sMsgTxtZip9, sMsgTxtZip10, sMsgTxtPhone, sMsgTxtPhone1, sMsgTxtPhone2, sMsgTxtPhone3, sMsgTxtPhone4, sMsgTxtPhone5, sMsgTxtPhone6, sMsgTxtPhone7, sMsgTxtPhone8, sMsgTxtPhone9, sMsgTxtPhone10).  This means that f_orm." + sName + ".sMsgBadSubStr is required.  However, f_orm." + sName + ".sMsgBadSubStr has not been provided.");
   }
   crashIfBadSpaceTrimConfig(f_orm, fe_text);
   var bIsSpecial = (bEM  ||  bInt  || bDec  ||
     bZC   ||  bZC1  ||  bZC2  ||  bZC3  ||  bZC4  ||  bZC5  ||
      bZC6  ||  bZC7  ||  bZC8  ||  bZC9  ||  bZC10  ||
      bPN   ||  bPN1  ||  bPN2  ||  bPN3  ||  bPN4  ||  bPN5  ||
      bPN6  ||  bPN7  ||  bPN8  ||  bPN9  ||  bPN10);
   if(bIsSpecial  &&
     (fe_text.bsTrimSpaces == "true"  ||  fe_text.bsDontTrimSpaces == "true"))  {
     return crashVF("Either f_orm." + sName + ".bsTrimSpaces (currently "" + fe_text.bsTrimSpaces + "") or f_orm." + sName + ".bsDontTrimSpaces (currently "" + fe_text.bsTrimSpaces + "") equal "true".  But this is illegal, because the element has these special types associated to it:  " + sSpecialTypes);
   }
   var iMin = fe_text.iMinLength;
   if(fe_text.sMsgBadLength)  {
     if(!iMin)  {
       return crashVF("f_orm." + sName + ".sMsgBadLength has been provided (currently "" + fe_text.sMsgBadLength + ""), but f_orm." + sName + ".iMinLength has not been provided");
     }
     if(iMin  &&  (!isInteger(iMin)  ||  iMin < 1))  {
       return crashVF("Both f_orm." + sName + ".sMsgBadLength (currently "" + fe_text.sMsgBadLength + "") and f_orm." + sName + ".iMinLength (currently "" + iMin + "") have been provided, but iMinLength must be an integer, and at least equal to one.");
     }
     //NOTE:  When MAXLENGTH is an attribute of the element,
     //fe_text.MAXLENGTH is undefined, but fe_text.maxLength
     //is not.  Things that make you go hmm.
     if(fe_text.maxLength  &&  fe_text.maxLength != -1  &&
        isInteger(fe_text.maxLength)  &&  iMin > fe_text.maxLength)  {
       return crashVF("Both f_orm." + sName + ".sMsgBadLength (currently "" + fe_text.sMsgBadLength + "") and f_orm." + sName + ".iMinLength (currently " + iMin + ") have been provided, but iMinLength must be an integer between one and f_orm." + sName + ".MAXLENGTH (currently " + fe_text.maxLength + "), inclusive.");
     }
   }  else if(iMin)  {
     return crashVF("f_orm." + sName + ".sMsgBadLength has *not* been provided, but the sub-attribute f_orm." + sName + ".iMinLength (currently " + iMin + ") has been provided.");
   }
   if(fe_text.iMaxLength)  {
     return crashVF("f_orm." + sName + ".iMaxLength (currently " + fe_text.iMaxLength + ") is only a legal sub-attribute for text elements.  To enforce maximum length in a text or password element, use the standard MAXLENGTH attribute.");
   }
 }
 //"di_" prefix stands for decimal-or-integer
 function crashIfBadIntDecCfg(di_min, di_max, bs_decimalAllowed, s_formLmntName, s_nameMin, s_nameMax)  {
   var sIntDecPostfix = "Int";
   var sAnIntADec = "an integer";
   var sIntDec = "integer";
   var sIsFuncName = "isInteger";
   if(bs_decimalAllowed == "true")  {
     sIntDecPostfix = "Dec";
     sAnIntADec = "a decimal";
     sIntDec = "decimal";
     sIsFuncName = "isDecimal";
   }
   if(di_min  &&  !isNumber(di_min, bs_decimalAllowed))  {
     return crashVF("f_orm." + s_formLmntName + ".sMsgTxt" + sIntDecPostfix + " has been provided, and the sub-variable " + s_formLmntName + "." + s_nameMin + " has also been provided.  However, " + s_nameMin + " must be " + sAnIntADec + ".  Currently "" + di_min + "".");
   }
   if(di_max  &&  !isNumber(di_max, bs_decimalAllowed))  {
     return crashVF("f_orm." + s_formLmntName + ".sMsgTxt" + sIntDecPostfix + " has been provided, and the sub-variable " + s_formLmntName + "." + s_nameMax + " has also been provided.  However, " + s_nameMax + " must be " + sAnIntADec + ".  Currently "" + di_max + "".");
   }
   if(di_min  &&  di_max  &&
     !isValidRange(di_min, di_max))  {
     return crashVF("f_orm." + s_formLmntName + ".sMsgTxt" + sIntDecPostfix + " has been provided, and both the sub-variables " + s_formLmntName + "." + s_nameMin + " and " + s_formLmntName + "." + s_nameMax + " have also been provided.  Both these variables are definitely legal " + sIntDec + "s (according to util_string." + sIsFuncName + "()), however, " + s_nameMin + " (currently "" + di_min + "") and " + s_nameMax + " (currently "" + di_max + "") are not a legal range according to util_number.isValidRange().");
   }
 }
 function crashIfBadSpaceTrimConfig(f_orm, fe_tta)  {
   fe_tta.bsTrimSpaces = getOptBooleanStringVF(fe_tta.bsTrimSpaces, "f_orm." + fe_tta.name + ".bsTrimSpaces");
   fe_tta.bsDontTrimSpaces = getOptBooleanStringVF(fe_tta.bsDontTrimSpaces, "f_orm." + fe_tta.name + ".bsDontTrimSpaces");
   if(f_orm.bsGlobalTrimSpaces == "true")  {
     if(fe_tta.bsTrimSpaces == "true")  {
       return crashVF("Both f_orm.bsGlobalTrimSpaces and f_orm." + fe_tta.name + ".bsTrimSpaces equal "true".  Only one of these variables may be "true".");
     }
   }  else  if(fe_tta.bsDontTrimSpaces == "true")  {
     return crashVF("f_orm.bsGlobalTrimSpaces has *not* been provided (or is equal to "false"), but f_orm." + fe_tta.name + ".bsDontTrimSpaces equals "true".  ");
   }
 }
 function crashIfNBSSError(s_textPwName, b_noBadSubStrings, as_globalBadSubStrs, as_badSubStrs)  {
   if(b_noBadSubStrings == "true"  &&
      (as_badSubStrs  ||  !as_globalBadSubStrs))  {
     return crashVF("f_orm." + s_textPwName + ".bsNoBadSubStrings equals "true", but either , f_orm.asGlobalBadSubStrs has *not* been provided (currently " + as_globalBadSubStrs + ") or f_orm." + s_textPwName + ".asBadSubStrs *has* been provided (currently " + as_badSubStrs + ").  When bsNoBadSubStrings equals "true", it is required that or asBadSubStrs not be provided and f_orm.asGlobalBadSubStrs should be provided.");
   }
 }
 function getRqdMissingMsg(s_requiredMsg, s_value)  {
   crashIfMissing(s_value, "s_value ("missing" means empty string)", "validate_form.getRqdMissingMsg");
   if(!s_requiredMsg)  {
     //This value is not required.
     return "";
   }
   //This value *is* required...
   if(s_value == "")  {
     //...but has not been provided.
     return s_requiredMsg;
   }
   //...and has been provided.
   return "";
 }
 /**
   Crash If the provided bad-sub-string-array is bad.
  **/
 function crashIfBadBSSA(s_variableName, as_badSubStrs)  {
   if(!as_badSubStrs)  {
     return;
   }
   var sRule = " is not required, but when it is provided, it must be of type array, at least one element in length, and each element must be of type string, at least one character in length, and all elements must be unique.  Currently, ";
   if(!isArray(as_badSubStrs))  {
     return crashVF("crashIfBadBSSA:  " + s_variableName + sRule + "it is of type "" + typeof(as_badSubStrs) + "".");
   }
   if(as_badSubStrs.length < 1)  {
     return crashVF("crashIfBadBSSA:  " + s_variableName + sRule + "it is zero elements in length.");
   }
   for(var i = 0; i < as_badSubStrs.length; i++)  {
     if(typeof(as_badSubStrs[i]) != "string")  {
       return crashVF("crashIfBadBSSA:  " + s_variableName + sRule + " s_variableName[" + i + "] is of type "" + typeof(as_badSubStrs[i]) + "".");
     }
     if(as_badSubStrs[i].length < 1)  {
       return crashVF("crashIfBadBSSA:  " + s_variableName + sRule + " s_variableName[" + i + "] is zero characters in length.");
     }
     for(var j = i + 1; j < as_badSubStrs.length; j++)  {
       if(as_badSubStrs[i] == as_badSubStrs[j])  {
         return crashVF("crashIfBadBSSA:  " + s_variableName + sRule + " Element " + i + " (currently "" + as_badSubStrs[i] + "") is equal to element " + j + ".");
       }
     }
   }
   //All elements are definitely of type string.
   for(var i = 0; i < as_badSubStrs.length; i++)  {
     for(var j = i + 1; j < as_badSubStrs.length; j++)  {
       if(as_badSubStrs[i] == as_badSubStrs[j])  {
         return crashVF("crashIfBadBSSA:  " + s_variableName + sRule + " Element " + i + " (currently "" + as_badSubStrs[i] + "") is equal to element " + j + ".");
       }
     }
   }
 }
 function  wasRCBSMalreadyFound(s_elementName)  {
   return (getRCBSMTrackerArrIdx(s_elementName) != -1);
 }
 function  getFirstArrIdx(s_elementName)  {
   var iArrIdx = getAndValidateRCBSMTArrIdx("getFirstArrIdx", s_elementName);
   var iFirstArrIdx = aiRCBSM_TRACKER_ARR_IDX[iArrIdx];
   if(iFirstArrIdx == -1)  {
     return crashVF("getFirstArrIdx:  Element named "" + s_elementName + "" *was* found in the tracker array objects, but it is of type select-multiple, which does not have multiple instances, and is therefore invalid for this function.  SANITY CHECK.  SHOULD NEVER HAPPEN.");
   }
   return iFirstArrIdx;
 }
 function  getMCSelectedCount(s_elementName)  {
   var iArrIdx = getAndValidateRCBSMTArrIdx("getMCSelectedCount", s_elementName);
   var iSelCt = aiRCBSM_TRACKER_SEL_COUNT[iArrIdx];
   if(iSelCt == -1)  {
     return crashVF("getMCSelectedCount:  Element named "" + s_elementName + "" *was* found in the tracker array objects, but it is of type radio, which is a single-choice element, and is therefore invalid for this function.  SANITY CHECK.  SHOULD NEVER HAPPEN.");
   }
   return iSelCt;
 }
 function getAndValidateRCBSMTArrIdx(s_callingFunction, s_elementName)  {
   var iArrIdx = getRCBSMTrackerArrIdx(s_elementName);
   if(iArrIdx == -1)  {
     return crashVF("getAndValidateRCBSMTArrIdx ("" + s_callingFunction + ""):  Element named "" + s_elementName + "" was not found in the tracker array objects.  SANITY CHECK.  SHOULD NEVER HAPPEN.");
   }
   return iArrIdx;
 }
 function  getRCBSMTrackerArrIdx(s_elementName)  {
   for(var i = 0; i < asRCBSM_TRACKER_NAME.length; i++)  {
     if(asRCBSM_TRACKER_NAME[i] == s_elementName)  {
       return i;
     }
   }
   return -1;
 }
 function addRCBSMtoTracker(f_orm, fe_rcbsm, i_formArrIdx)  {
   if(asRCBSM_TRACKER_NAME.length < 1)  {
     //This is the first to be tracked.  Just create a new
     //array containing this name as the only element.
     asRCBSM_TRACKER_NAME = [fe_rcbsm.name];
     aiRCBSM_TRACKER_SEL_COUNT = [getMCSelectedCountForTracker(f_orm, fe_rcbsm)];
     aiRCBSM_TRACKER_ARR_IDX = [getRCBSMFirstArrIdx(fe_rcbsm, i_formArrIdx)];
     return;
   }
   //At least one element is already being tracked.  Add this
   //element to the existing tracking arrays.
   if(wasRCBSMalreadyFound(fe_rcbsm.name))  {
     return crashVF("addRCBSMtoTracker:  Element named "" + fe_rcbsm.name + "" already exists in the TRACKER arrays.  SANITY CHECK.  SHOULD NEVER HAPPEN.");
   }
   var asTrackerNames = new Array(asRCBSM_TRACKER_NAME.length + 1);
   for(var i = 0; i < asTrackerNames.length; i++)  {
     if(i < (asTrackerNames.length - 1))  {
       asTrackerNames[i] = asRCBSM_TRACKER_NAME[i];
     }  else  {
       asTrackerNames[i] = fe_rcbsm.name;
     }
   }
   asRCBSM_TRACKER_NAME = asTrackerNames;
   var aiTrackerCounts = new Array(aiRCBSM_TRACKER_SEL_COUNT.length + 1);
   for(var i = 0; i < aiTrackerCounts.length; i++)  {
     if(i < (aiTrackerCounts.length - 1))  {
       aiTrackerCounts[i] = aiRCBSM_TRACKER_SEL_COUNT[i];
     }  else  {
       aiTrackerCounts[i] = getMCSelectedCountForTracker(f_orm, fe_rcbsm);
     }
   }
   aiRCBSM_TRACKER_SEL_COUNT = aiTrackerCounts;
   var aiTrackerArrIdx = new Array(aiRCBSM_TRACKER_ARR_IDX.length + 1);
   for(var i = 0; i < aiTrackerArrIdx.length; i++)  {
     if(i < (aiTrackerArrIdx.length - 1))  {
       aiTrackerArrIdx[i] = aiRCBSM_TRACKER_ARR_IDX[i];
     }  else  {
       aiTrackerArrIdx[i] = getRCBSMFirstArrIdx(fe_rcbsm, i_formArrIdx);
     }
   }
   aiRCBSM_TRACKER_ARR_IDX = aiTrackerArrIdx;
 }
 function getRCBSMFirstArrIdx(fe_rcbsm, i_formArrIdx)  {
   if(fe_rcbsm.type == "select-multiple")  {
     //select-multiple only has one instance in the form.  -1 indicates that.
     return -1;
   }
   return i_formArrIdx;
 }
 function getMCSelectedCountForTracker(f_orm, fe_rcbsm)  {
   if(fe_rcbsm.type != "radio"  &&
      fe_rcbsm.type != "checkbox"  &&
      fe_rcbsm.type != "select-multiple")  {
     return crashVF("getMCSelectedCount:  Element named "" + fe_rcbsm.name + "" is not of type radio, checkbox or select-multiple.  Type of this element is "" + fe_rcbsm.type + "".  SANITY CHECK.  SHOULD NEVER HAPPEN.");
   }
   if(fe_rcbsm.type == "radio")  {
     //This is not a multiple choice type.  -1 indicates that.
     return -1;
   }
   var iMCSelectedCount = 0;
   if(fe_rcbsm.type == "checkbox")  {
     for(var i = 0; i < f_orm[fe_rcbsm.name].length; i++)  {
       if(f_orm[fe_rcbsm.name][i].checked)  {
         iMCSelectedCount++;
       }
     }
     return iMCSelectedCount;
   }
   //Type is definitely select-multiple.
   for(var i = 0; i < fe_rcbsm.length; i++)  {
     if(fe_rcbsm.options[i].selected)  {
       iMCSelectedCount++;
     }
   }
   return iMCSelectedCount;
 }
 function getOptBooleanStringVF(bs_potential, s_variableName)  {
   return getOptBooleanString(bs_potential, s_variableName, "validate_form.getFormErrorMsgs");
 }
 function crashVF(s_message)  {
   return crash("validate_form.getFormErrorMsgs:  " + s_message);
 }
 function initializeLocalVars()  {
   resetCrashedFlag();
   asRCBSM_TRACKER_NAME = [];
   aiRCBSM_TRACKER_SEL_COUNT = [];
   aiRCBSM_TRACKER_ARR_IDX = [];
   iELEMENT_COUNT = 0;
   bFIRST_DEBUG_SCREEN_SEEN = false;
 }
 /**
   For backwards compatibility only.  Only use getFormErrorMsgs.  This function will eventually be eliminated.
  **/
 function validateForm(f_orm, s_userErrorPrefix, i_debugPerScreen)  {
   return getFormErrorMsgs(f_orm, s_userErrorPrefix, i_debugPerScreen);
 }

/**

 PRIVATE FUNCTIONS...end
**/

/**************************************************************************************************

 util_string.js...START
 Do not edit this file.  This file is dynamically generated by the validate_form.js
 ant build process
**************************************************************************************************/

/**

 VALIDATE_FORM.JS
 Comprehensive solution for validating HTML forms.
 Copyright (C) 2002, Jeff Epstein, jeff_epstein@yahoo.ru, http://www.jeffyjeffy.ru#download
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 This program 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 General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
**/
 //PHONE NUMBER AND ZIP CODE FORMAT/RANGES
   //For documentation, see
   //    documentation/index.html#string_zip
   //
   //Demo/testing values exist at the bottom of
   //    documentation/vf_string_phone_zip.html
   //
   //To test these formats for validity, see
   //    documentation/unit_test.html#util_string_tests
 //PHONE NUMBER FORMATS/RANGES...start
   //US 3 then 7
     var siPHONE_1_MINIMUM = "1001001000";
     var siPHONE_1_MAXIMUM = "9999999999";
   //US 7 only
     var siPHONE_2_MINIMUM = "1001000";
     var siPHONE_2_MAXIMUM = "9999999";
   var siPHONE_3_MINIMUM = "1000";
   var siPHONE_3_MAXIMUM = "9999";
   var siPHONE_4_MINIMUM = "001000";
   var siPHONE_4_MAXIMUM = "999999";
   var siPHONE_5_MINIMUM = "00000000";
   var siPHONE_5_MAXIMUM = "99999999";
   var siPHONE_6_MINIMUM = "1000000000";
   var siPHONE_6_MAXIMUM = "5555555555";
   var siPHONE_7_MINIMUM = "0";
   var siPHONE_7_MAXIMUM = "1";
   var siPHONE_8_MINIMUM = "1";
   var siPHONE_8_MAXIMUM = "9";
   var siPHONE_9_MINIMUM = "000";
   var siPHONE_9_MAXIMUM = "000";
   var siPHONE_10_MINIMUM = "010101";
   var siPHONE_10_MAXIMUM = "787374";
 //PHONE NUMBER FORMATS/RANGES...end
 //ZIP CODE FORMATS/RANGES...start
   //US 5+4
     var siZIP_1_RQD_MINIMUM = "00000";
     var siZIP_1_RQD_MAXIMUM = "99999";
     var siZIP_1_ALT_MINIMUM = "0001";
     var siZIP_1_ALT_MAXIMUM = "9999";
   //US 5 only
     var siZIP_2_RQD_MINIMUM = "00001";
     var siZIP_2_RQD_MAXIMUM = "99999";
     var siZIP_2_ALT_MINIMUM = "";
     var siZIP_2_ALT_MAXIMUM = "";
   var siZIP_3_RQD_MINIMUM = "1";
   var siZIP_3_RQD_MAXIMUM = "1";
   var siZIP_3_ALT_MINIMUM = "2";
   var siZIP_3_ALT_MAXIMUM = "2";
   var siZIP_4_RQD_MINIMUM = "01";
   var siZIP_4_RQD_MAXIMUM = "99";
   var siZIP_4_ALT_MINIMUM = "0001";
   var siZIP_4_ALT_MAXIMUM = "9999";
   var siZIP_5_RQD_MINIMUM = "00";
   var siZIP_5_RQD_MAXIMUM = "55";
   var siZIP_5_ALT_MINIMUM = "0";
   var siZIP_5_ALT_MAXIMUM = "7";
   var siZIP_6_RQD_MINIMUM = "54321";
   var siZIP_6_RQD_MAXIMUM = "55555";
   var siZIP_6_ALT_MINIMUM = "";
   var siZIP_6_ALT_MAXIMUM = "";
   var siZIP_7_RQD_MINIMUM = "00001";
   var siZIP_7_RQD_MAXIMUM = "00001";
   var siZIP_7_ALT_MINIMUM = "0001";
   var siZIP_7_ALT_MAXIMUM = "0001";
   var siZIP_8_RQD_MINIMUM = "09000";
   var siZIP_8_RQD_MAXIMUM = "91111";
   var siZIP_8_ALT_MINIMUM = "0003873874038834";
   var siZIP_8_ALT_MAXIMUM = "0020837401092837";
   var siZIP_9_RQD_MINIMUM = "0003873874038834";
   var siZIP_9_RQD_MAXIMUM = "0020837401092837";
   var siZIP_9_ALT_MINIMUM = "09000";
   var siZIP_9_ALT_MAXIMUM = "91111";
   var siZIP_10_RQD_MINIMUM = "0";
   var siZIP_10_RQD_MAXIMUM = "7";
   var siZIP_10_ALT_MINIMUM = "00";
   var siZIP_10_ALT_MAXIMUM = "55";
 //ZIP CODE FORMATS/RANGES...end


/**

 Does the provided string start or end with a space?
 EQUAL TO
   isSurroundedByChar(s_tring, " ");
**/

function isSurroundedBySpace(s_tring) {

 return isSurroundedByChar(s_tring, " ");

} /**

 Does the provided string start or end with the provided character?
 PARAMETERS
   s_tring  The string to analyze.
   c_har    The character that is determined to exist at the start or end of s_tring.
 RETURNS
   true   If the first or last character in s_tring is c_har.
   false  If s_tring is null or zero characters in length.
        If both the first and last characters in s_tring are *not* c_har.
**/

function isSurroundedByChar(s_tring, char_toTrim) {

 if(!s_tring)  {
   return false;
 }
 if(!char_toTrim  ||  char_toTrim.length != 1)  {
   return crash("isSurroundedByChar:  char_toTrim parameter must be provided, and be exactly one character in length.");
 }
 if(s_tring.length < 1)  {
   return false;
 }
 if(s_tring.substring(0, 1) == char_toTrim)  {
   return true;
 }
 return (s_tring.substring(s_tring.length - 1, s_tring.length) == char_toTrim);

}

/**

 Is the provided string a legal integer?
 RETURNS
   isNumber(s_potentialInteger, "false")
**/

function isInteger(s_potentialInteger) {

 return isNumber(s_potentialInteger, "false");

}

/**

 Is the provided string a legal decimal?
 RETURNS
   isNumber(s_potenitalDecimal, "true")
**/

function isDecimal(s_potentialDecimal) {

 return isNumber(s_potentialDecimal, "true");

} /**

 Is the provided string a legal number?
 PARAMETERS
   s_potentialNumber
     The string to analyze.  Required.
   bs_decimalAllowed
     Is the potential number allowed to be a decimal?  If "true", then yes.  If "false", no.
 RETURNS
   true
     If s_potentialNumber is a legal integer (regardless the value of bs_decimalAllowed).  A legal integer is a string that...
       ...contains one or more zeros.  Note that 0 equals 0000 equals 0000000000 equals ...
       ...starts with zero or one dashes (indicating negative), followed by one or more digits (0-9), where at least one is greater than zero.
     If bs_decimalAllowed is "true" and s_potentialNumber is a legal decimal.  A legal decimal is a string that...
       ...is an integer.
       ...starts with zero or one dashes (indicating negative) followed by zero or more digits, followed by a decimal point ("."), followed by *one* or more digits.
     (Note that s_potentialNumber is checked to be an integer first.  If it is, then true is returned, regardless the value of bs_decimalAllowed.  If the string is an integer, it is not checked, specifically, to see if it"s a decimal.  Hence, the description of a legal decimal number says "a decimal point" instead of "zero or one decimal points".)
   false
     If otherwise.
 LEGAL EXAMPLES (both integers and decimals)
     -1
     0
     1
     -50
     8750328754
     00008750328754
     08750328754
     -487584758475235
     -0000000487584758475235
     -0487584758475235
 ILLEGAL EXAMPLES (both integers and decimals)
     4875847-58475235
     487584758475235-
     [EMPTY_STRING]
     a
     0-
     -0
     Not a number!!!
     Some 123 numbers 456
     123 456
     -0.0
     -.0
     -0.000000
     -.000000
     1.
     .
 LEGAL EXAMPLES (decimals, but only after it is determined that the value is *not* an integer)
     1.1
     1.000830847018374
     058763408562473.01837486564417308746
     .1
     .0
     .01
     -1.0
**/

function isNumber(s_potentialNumber, bs_decimalAllowed) {

 crashIfMissing("util_string.jsNumber", s_potentialNumber, "s_potentialNumber");
 crashIfBadBooleanString(bs_decimalAllowed, "bs_decimalAllowed", "util_string.jsNumber");
 if(s_potentialNumber.length < 1)  {
   return false;
 }
 if(s_potentialNumber == "-")  {
   //A negative sign only makes no sense.
   return false;
 }
 if(/^-[0]+$/.test(s_potentialNumber))  {
   //Negative zero makes no sense.
   return false;
 }
 if(/^[0]+$/.test(s_potentialNumber))  {
   //Zero is a legal number:
   //0  ==  0000000000000  ==  000
   return true;
 }
 //It is definitely not zero.
 //^         The start of the line.
 //[-]{0,1}  Zero or one dashes.
 //[0-9]+    One or more of any digit.
 //$         The end of the line.
 if(/^[-]{0,1}[0-9]+$/.test(s_potentialNumber))  {
   //No matter what, this is valid.  This is a leagal integer
   //and decimal.
   return true;
 }
 //It"s not an integer...
 if(bs_decimalAllowed == "false")  {
   //...but it must be.
   return false;
 }
 //...and that"s okay.  It might be a decimal
 //Due to precision:
 //10.0000000000001 is legal (12 zeros)
 //10.00000000000001 is not  (13 zeros)
 //^         The start of the line.
 //[-]{0,1}  Zero or one dashes.
 //[0-9]*    Zero or more digits.
 //[.]      A decimal point.
 //[0-9]+    One or more digits.
 //$         The end of the line.
 if(/^[-]{0,1}[0-9]*[.][0-9]+$/.test(s_potentialNumber))  {
   //It is a "raw" decimal.  The only thing that would make
   //this illegal is if it were -0.0 or -.0, or -0.0000 or
   //-.0000 or ...
   return !(/^-0*[.]0+$/.test(s_potentialNumber));
 }
 //It is not a legal decimal number.
 return false;

}

function isEmail(s_potentialEmail) {

 if(!s_potentialEmail  ||  s_potentialEmail.length < 1)  {
   return crash("isValidNumber:  s_potentialEmail must be defined, and at least one character in length.");
 }
 if(s_potentialEmail.indexOf(" ") != -1  ||
    s_potentialEmail.indexOf("/") != -1  ||
    s_potentialEmail.indexOf("\\") != -1  ||
    s_potentialEmail.indexOf(",") != -1)  {
   //A space, slash or comma was found.
   return false;
 }
 if(/[@.][@.]/.test(s_potentialEmail))  {
   //An @ or dot is followed by an @ or dot.
   return false;
 }
 if(/^[@.]/.test(s_potentialEmail))  {
   //The first character is an @ or dot.
   return false;
 }
 if(/[@.]$/.test(s_potentialEmail))  {
   //The last character may not be an @ or dot.
   return false;
 }
 if(!/^[^@]+@[^@]+$/.test(s_potentialEmail))  {
   //Only one @ allowed
   //    (Negative of:
   //     Must have one or more non-@ starting the line,
   //     exactly one @, and then
   //     one or more non-@ ending the line.)
   return false;
 }
 //There is exactly one @.
 if(!/@.*[.]/.test(s_potentialEmail))  {
   //At least one dot must follow the (single) @.
   return false;
 }
 //At least one dot follows the @.  We already determined
 //above that it does not immediately follow it,
 //No negative conditions were met.  This is a legal email address.
 //Cool, eh?  : )
 return true;

}

function removeNonNumbers(s_tring) {

 if(!s_tring  ||  s_tring.length < 1)  {
   return crash("removeNonNumbers:  s_tring must be defined, and at least one character in length.");
 }
 var reNonNumbers = /^\D$/;
 if(/^\D$/.test(s_tring))  {
   //There are no numbers at all.
   return "";
 }
 //There is at least one number.
 var asNumberParts = s_tring.split(/\D/);
 var sNumber = asNumberParts[0];
 for(var i = 1; i < asNumberParts.length; i++)  {
   sNumber += asNumberParts[i];
 }
 return sNumber;

} /**

 Are the provided phone format strings valid?
 See the documentation above, regarding PHONE NUMBER FORMATS/RANGES.  Specifically, under the "phone" section, under "--- RULES ---".
 Call this function manually, if you wish.  It is not called by any other function in this js file...except crashIfBadPhoneFormat.
 PARAMETER
   bs_crashIfBad
     Must equal either "true" or "false".  If "true", then if the formats are invalid, this function crashes with a descriptive message.  See utility.crash().
**/

function isPhoneFormatValid(bs_crashIfBad, si_minFormat, si_maxFormat) {

 return isFormatValid("Phone", bs_crashIfBad, "si_minFormat", "si_maxFormat", si_minFormat, si_maxFormat);

}

function getValidPhone(s_potentialPhone) {

 return getValidPhone1(s_potentialPhone);

} function getValidPhone1(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_1_MINIMUM, siPHONE_1_MAXIMUM, s_potentialPhone);

} function getValidPhone2(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_2_MINIMUM, siPHONE_2_MAXIMUM, s_potentialPhone);

} function getValidPhone3(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_3_MINIMUM, siPHONE_3_MAXIMUM, s_potentialPhone);

} function getValidPhone4(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_4_MINIMUM, siPHONE_4_MAXIMUM, s_potentialPhone);

} function getValidPhone5(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_5_MINIMUM, siPHONE_5_MAXIMUM, s_potentialPhone);

} function getValidPhone6(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_6_MINIMUM, siPHONE_6_MAXIMUM, s_potentialPhone);

} function getValidPhone7(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_7_MINIMUM, siPHONE_7_MAXIMUM, s_potentialPhone);

} function getValidPhone8(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_8_MINIMUM, siPHONE_8_MAXIMUM, s_potentialPhone);

} function getValidPhone9(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_9_MINIMUM, siPHONE_9_MAXIMUM, s_potentialPhone);

} function getValidPhone10(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_10_MINIMUM, siPHONE_10_MAXIMUM, s_potentialPhone);

} /**

 Get the phone number out of the provided string.
 PARAMETERS
   si_minFormat
     The format string representing the minimum allowable bound for a legal phone number.  It is *assumed* that this string is provided and valid.  Use isPhoneFormatValid() to validate this, along with si_maxFormat.  For specific information on this variable, see the documentation above, regarding PHONE NUMBER FORMATS/RANGES, under the "phone" section.
   si_maxFormat
     The format string representing the maximum allowable bound for a legal phone number.  It is *assumed* that this string is provided and valid.  Use isPhoneFormatValid() to validate this, along with si_maxFormat.  For specific information on this variable, see the documentation above, regarding PHONE NUMBER FORMATS/RANGES, under the "phone" section.
   s_potentialPhone
     The string containing the (potentially legal) phone number, including any surrounding text.  For example:
       (215) 555-1212
       215 555 1212
       2155551212
 RETURNS
   If the phone number is invalid, according to the format, empty string ("") is returned.  Otherwise, the non-digits are stripped from s_potentialPhone, and the digits alone are returned (but as a string, preserving leading zeros).  For example, all of the above examples (under s_potentialPhone) return "2155551212".
**/

function getValidPhoneFromFormat(si_minFormat, si_maxFormat, s_potentialPhone) {

 if(!s_potentialPhone  ||  s_potentialPhone.length < 1)  {
   return crash("isValidNumber:  s_potentialPhone must be defined, and at least one character in length.");
 }
 //This also removes dashes (negative symbols) and decimal points.
 var siPhoneNumber = removeNonNumbers(s_potentialPhone);
 if(!siPhoneNumber  ||  siPhoneNumber.length < 1  ||
      siPhoneNumber.length != si_minFormat.length)  {
   //The length is illegal.
   return "";
 }
 //Must supply radix=10
 var iMin = parseInt(si_minFormat, 10);
 var iMax = parseInt(si_maxFormat, 10);
 if(isValidNumber(siPhoneNumber, iMin, iMax))  {
   //The phone number is in bounds.
   return siPhoneNumber;
 }
 //It is not a valid phone number.
 return "";

}

/**

 Are the provided zip format strings valid?
 See the documentation above, regarding PHONE NUMBER FORMATS/RANGES.  Specifically, under the "zip code" section, under "--- RULES ---".
 Call this function manually, if you wish.  It is not called by any other function in this js file.
 PARAMETER
   bs_crashIfBad
     Must equal either "true" or "false".  If "true", then if the formats are invalid, this function crashes with a descriptive message.  See utility.crash().
**/

function isZipFormatValid(bs_crashIfBad, si_rqdMinFormat, si_rqdMaxFormat, si_altMinFormat, si_altMaxFormat) {

 if(!isFormatValid("Zip", bs_crashIfBad, "si_rqdMinFormat", "si_rqdMaxFormat", si_rqdMinFormat, si_rqdMaxFormat))  {
   return false;
 }
 //The required format is valid.
 if(!si_altMinFormat ^ !si_altMaxFormat)  {
   if(bs_crashIfBad == "true")  {
     return crash("util_string.jsZipFormatValid:  si_altMinFormat ("" + si_altMinFormat + "") and si_altMaxFormat ("" + si_altMaxFormat + "") must both be either undefined or defined.");
   }
   return false;
 }
 //Both are either undefined, or defined.
 if(!si_altMinFormat)  {
   //One is undefined, therefore both are undefined.
   return true;
 }
 //Both are defined.
 return isFormatValid("Zip", bs_crashIfBad, "si_altMinFormat", "si_altMaxFormat", si_altMinFormat, si_altMaxFormat)

}

function getValidZip(s_potentialZip) {

 return getValidZip1(s_potentialZip);

} function getValidZip1(s_potentialZip) {

 return getValidZipFromFormat(siZIP_1_RQD_MINIMUM, siZIP_1_RQD_MAXIMUM, siZIP_1_ALT_MINIMUM, siZIP_1_ALT_MAXIMUM, s_potentialZip);

} function getValidZip2(s_potentialZip) {

 return getValidZipFromFormat(siZIP_2_RQD_MINIMUM, siZIP_2_RQD_MAXIMUM, siZIP_2_ALT_MINIMUM, siZIP_2_ALT_MAXIMUM, s_potentialZip);

} function getValidZip3(s_potentialZip) {

 return getValidZipFromFormat(siZIP_3_RQD_MINIMUM, siZIP_3_RQD_MAXIMUM, siZIP_3_ALT_MINIMUM, siZIP_3_ALT_MAXIMUM, s_potentialZip);

} function getValidZip4(s_potentialZip) {

 return getValidZipFromFormat(siZIP_4_RQD_MINIMUM, siZIP_4_RQD_MAXIMUM, siZIP_4_ALT_MINIMUM, siZIP_4_ALT_MAXIMUM, s_potentialZip);

} function getValidZip5(s_potentialZip) {

 return getValidZipFromFormat(siZIP_5_RQD_MINIMUM, siZIP_5_RQD_MAXIMUM, siZIP_5_ALT_MINIMUM, siZIP_5_ALT_MAXIMUM, s_potentialZip);

} function getValidZip6(s_potentialZip) {

 return getValidZipFromFormat(siZIP_6_RQD_MINIMUM, siZIP_6_RQD_MAXIMUM, siZIP_6_ALT_MINIMUM, siZIP_6_ALT_MAXIMUM, s_potentialZip);

} function getValidZip7(s_potentialZip) {

 return getValidZipFromFormat(siZIP_7_RQD_MINIMUM, siZIP_7_RQD_MAXIMUM, siZIP_7_ALT_MINIMUM, siZIP_7_ALT_MAXIMUM, s_potentialZip);

} function getValidZip8(s_potentialZip) {

 return getValidZipFromFormat(siZIP_8_RQD_MINIMUM, siZIP_8_RQD_MAXIMUM, siZIP_8_ALT_MINIMUM, siZIP_8_ALT_MAXIMUM, s_potentialZip);

} function getValidZip9(s_potentialZip) {

 return getValidZipFromFormat(siZIP_9_RQD_MINIMUM, siZIP_9_RQD_MAXIMUM, siZIP_9_ALT_MINIMUM, siZIP_9_ALT_MAXIMUM, s_potentialZip);

} function getValidZip10(s_potentialZip) {

 return getValidZipFromFormat(siZIP_10_RQD_MINIMUM, siZIP_10_RQD_MAXIMUM, siZIP_10_ALT_MINIMUM, siZIP_10_ALT_MAXIMUM, s_potentialZip);

} /**

 Get the zip code out of the provided string.
 PARAMETERS
   si_rqdMinFormat
     The format string representing the minimum allowable bound for the required portion of a legal zip code.  It is *assumed* that this string is provided and valid.  Use isZipFormatValid() to validate this, along with si_maxFormat.  For specific information on this variable, see the documentation above, regarding PHONE NUMBER FORMATS/RANGES, under the "zip code" section.
   si_rqdMaxFormat
     The format string representing the maximum allowable bound for the required portion of a legal zip code.  It is *assumed* that this string is provided and valid.  Use isZipFormatValid() to validate this, along with si_maxFormat.  For specific information on this variable, see the documentation above, regarding PHONE NUMBER FORMATS/RANGES, under the "zip code" section.
   si_altMinFormat
     The format string representing the minimum allowable bound for the alternate portion of a legal zip code.  It is *assumed* that this string is provided and valid.  Use isZipFormatValid() to validate this, along with si_maxFormat.  For specific information on this variable, see the documentation above, regarding PHONE NUMBER FORMATS/RANGES, under the "zip code" section.
   si_altMaxFormat
     The format string representing the maximum allowable bound for the alternate portion of a legal zip code.  It is *assumed* that this string is provided and valid.  Use isZipFormatValid() to validate this, along with si_maxFormat.  For specific information on this variable, see the documentation above, regarding PHONE NUMBER FORMATS/RANGES, under the "zip code" section.
   s_potentialZip
     The string containing the (potentially legal) zip code, including any surrounding text.  For example:
       08052-3848
       19130 (0408)
       00483
 RETURNS
   If the zip code is invalid, according to the format, empty string ("") is returned.  Otherwise, the non-digits are stripped from s_potentialZip, and the digits alone are returned (but as a string, preserving leading zeros).  For example, the second example above (under s_potentialZip) returns "191300408".
**/

function getValidZipFromFormat(si_rqdMinFormat, si_rqdMaxFormat, si_altMinFormat, si_altMaxFormat, s_potentialZip) {

 if(!s_potentialZip  ||  s_potentialZip.length < 1)  {
   return crash("isValidNumber:  s_potentialZip must be defined, and at least one character in length.");
 }
 var siZip = removeNonNumbers(s_potentialZip);
 var bLegalLength = false;
 if(siZip)  {
   //There is at least one digit in the zip code...it does
   //exist and...
   if(siZip.length == si_rqdMinFormat.length)  {
     //...it is the required length.
     bLegalLength = true;
   }  else if(si_altMinFormat  &&  si_altMinFormat.length > 0  &&
                  siZip.length == (si_rqdMinFormat.length + si_altMinFormat.length))  {
     //...although it is not the required length, there is
     //an alternate length format, and the zip code has
     //the same length as it PLUS the required part.
     bLegalLength = true;
   }  //ELSE:  There is no alternate format.
 }
 if(!bLegalLength)  {
   return "";
 }
 //The length is legal, according to the format.
 var sRqdPart = siZip.substring(0, si_rqdMinFormat.length);
 //Must specify 10 as the radix (base).  If you don"t, and the
 //format has leading zeros, it may get confused and assume
 //that it has a different radix.
 var iMin = parseInt(si_rqdMinFormat, 10);
 var iMax = parseInt(si_rqdMaxFormat, 10);
 if(!isValidNumber(sRqdPart, iMin, iMax))  {
   //The zip is out of bounds.
   return "";
 }
 //The required part is legal.
 if(siZip.length > sRqdPart.length)  {
   //The length of the overall zip (siZip) is longer than the
   //length of the required part.  In other words, the
   //potential zip definitely has an alternate part.
   var sAltPart = siZip.substring(si_rqdMinFormat.length, siZip.length);
   //Must specify 10 as the radix (base).
   iMin = parseInt(si_altMinFormat, 10);
   iMax = parseInt(si_altMaxFormat, 10);
   if(!isValidNumber(sAltPart, iMin, iMax))  {
     //The zip is out of bounds.
     return "";
   }
 }
 //Every part is in range.
 return siZip;

}

/**

 Is the provided string (who"s value is a non-negative integer) legal?
 PARAMETERS
   s_potentialInt
     The string to analyze.  Required, and it is *assumed* that this only contains digits (0-9.  Decimal points ["."] and negative symbols ["-"] are not legal).  If it contains anything else, this function will behave unpredictably.
   bs_trailingZeroOk
     Required.  Must equal "true" or "false".  If "true", then s_potentialInt is considered legal if it starts with one or more zeros (regardless if it actually equals zero).  If "false", then when s_potentialInt starts with a zero, this function returns false.  This parameter is primary, over bs_zeroOk (see "NOTE").
   bs_zeroOk
     Required.  Must equal "true" or "false".  If "true", then s_potentialInt is considered legal if it is equal to zero ("0", "00", "00000", "0000000000", ...).  If "false", then when s_potentialInt equals zero, this function returns false.  No matter what, a non-zero value is okay, even if there are trailing zeros (however, this does not override bs_trailingZeroOk).  This parameter is secondary to bs_trailingZerosOk (see "NOTE").
   NOTE.
     Note which combinations of bs_trailingZeroOk and bs_zeroOk are legal:
     bs_trailingZeroOk     bs_zeroOk       LEGAL?
       true                 true            yes
       true                 false           yes
       false                true            NO
       false                false           yes
 RETURNS
   true
     If s_potentialInt conforms to the rules defined by bs_zeroOk and bs_trailingZeroOk parameters.
   false
     If otherwise.
**/

function isValidPosIntStr(s_potentialInt, bs_trailingZeroOk, bs_zeroOk) {

 crashIfMissing("util_string.jsValidPosIntStr", s_potentialInt, "s_potentialInt");
 crashIfBadBooleanString(bs_trailingZeroOk, "bs_trailingZeroOk", "util_string.jsValidPosIntStr");
 crashIfBadBooleanString(bs_zeroOk, "bs_zeroOk", "util_string.jsValidPosIntStr");
 if(bs_zeroOk == "true"  &&  bs_trailingZeroOk == "false")  {
   return crash("util_string.jsValidPosIntStr:  bs_trailingZero equals "false", but bs_zeroOk equals "true".");
 }
 if(bs_zeroOk == "true")  {
   //No matter what, s_potentialInt is valid.
   return true;
 }
 //Zero, as a whole, is not okay, however, trailing zeros may
 //be okay.
 var iTrailingZeros = 0;
 for(var i = 0; i < s_potentialInt.length; i++)  {
   var cDigit = s_potentialInt.substring(i, i + 1);
   if(cDigit == "0")  {
     iTrailingZeros++;
   }  else  {
     //We"ve reached the first non-zero.
     break;
   }
 }
 if(iTrailingZeros == 0)  {
   //There are no trailing zeros.  No further analysis
   //needed.
   return true;
 }
 //There is at least one trailing zero.
 if(iTrailingZeros == s_potentialInt.length)  {
   //EVERY digit is equal to zero.
   //s_potentialInt equals zero.
   //s_potentialInt contains only zeros.
   //If bs_zeroOk equals "true":  return true.
   //If bs_zeroOk equals "false":  return false.
   return (bs_zeroOk == "true");
 }
 //There is at least one non-zero digit, following the
 //initial trailing zero(s).
 //If bs_trailingZeroOk equals "true":  return true.
 //If bs_trailingZeroOk equals "false":  return false.
 return (bs_trailingZeroOk == "true");

}

function trimSpaces(s_tring) {

 return trimChar(" ", s_tring);

}

function trimChar(c_harToTrim, s_tring) {

 if(!c_harToTrim  ||  c_harToTrim.length != 1)  {
   return crash("util_sting.trimChar:  c_harToTrim must be provided, and must be exactly one character in length.  Currently "" + c_harToTrim + "".");
 }
 crashIfMissing("util_string.trimSpaces", s_tring, "s_tring");
 var i = 0;
 var iStartingSpaces = 0;
 while(s_tring.substring(i, (i + 1)) == c_harToTrim)  {
   iStartingSpaces++
   i++;
 }
 if(iStartingSpaces == s_tring.length)  {
   return "";
 }
 i = 0;
 var iEndingSpaces = 0;
 while(s_tring.substring((s_tring.length - i), (s_tring.length - (i + 1))) == c_harToTrim)  {
   iEndingSpaces++
   i++;
 }
 if(iStartingSpaces == 0  &&  iEndingSpaces == 0)  {
   return s_tring;
 }
 return s_tring.substring(iStartingSpaces, (s_tring.length - iEndingSpaces));

}

function isFormatValid(s_type, bs_crashIfBad, s_minDesc, s_maxDesc, si_minimum, si_maximum) {

 crashIfBadBooleanString(bs_crashIfBad, "bs_crashIfBad", "util_string.js" + s_type + "FormatValid");
 crashIfMissing("util_string.js" + s_type + "FormatValid", si_minimum, s_minDesc);
 crashIfMissing("util_string.js" + s_type + "FormatValid", si_maximum, s_maxDesc);
 if(si_minimum.length != si_maximum.length)  {
   if(bs_crashIfBad == "true")  {
     return crash("util_string.js." + s_type + "FormatValid:  " + s_minDesc + " ("" + si_minimum + "") must be the same length as " + s_maxDesc + " ("" + si_maximum + "").");
   }
   return false;
 }
 if(!isInteger(si_minimum)  ||  si_minimum < 0)  {
   if(bs_crashIfBad == "true")  {
     return crash("util_string.js." + s_type + "FormatValid:  " + s_minDesc + " (currently "" + si_minimum + "") must be an integer greater than or equal to zero.");
   }
   return false;
 }
 if(!isInteger(si_maximum)  ||  si_maximum < 0)  {
   if(bs_crashIfBad == "true")  {
     return crash("util_string.js." + s_type + "FormatValid:  " + s_maxDesc + " (currently "" + si_maximum + "") must be an integer greater than or equal to zero.");
   }
   return false;
 }
 //Must supply radix=10
 var iMin = parseInt(si_minimum, 10);
 var iMax = parseInt(si_maximum, 10);
 if(iMin > iMax)  {
   if(bs_crashIfBad == "true")  {
     return crash("util_string.js." + s_type + "FormatValid:  " + s_minDesc + " (" + si_minimum + ") is numerically greater than " + s_maxDesc + " (" + si_maximum + ").");
   }
   return false;
 }
 return true;

}

function getPadded(s_tring, i_padLength) {

 crashIfMissing("util_string.js.getPadded", s_tring, "s_tring");
 crashIfMissing("util_string.js.getPadded", i_padLength, "i_padLength");
 if(!isInteger(i_padLength))  {
   return crash("util_string.js.getPadded:  i_padLength ("" + i_padLength + "") must be an *integer* greater than or equal to zero.");
 }  else if(!isValidNumberOpt(i_padLength, 0, "true", -1, "false"))  {
   return crash("util_string.js.getPadded:  i_padLength ("" + i_padLength + "") must be an *integer* greater than or equal to zero.");
 }
 if(s_tring.length >= i_padLength)  {
   return s_tring;
 }
 for(var i = s_tring.length; i < (i_padLength + 1); i++)  {
   s_tring = s_tring + " ";
 }
 return s_tring;

} /**************************************************************************************************

 util_number.js...START
 Do not edit this file.  This file is dynamically generated by the validate_form.js
 ant build process
**************************************************************************************************/

/**

 VALIDATE_FORM.JS
 Comprehensive solution for validating HTML forms.
 Copyright (C) 2002, Jeff Epstein, jeff_epstein@yahoo.ru, http://www.jeffyjeffy.ru#download
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 This program 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 General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
**/

function isValidRangeOpt(i_min, bs_enforceMin, i_max, bs_enforceMax) {

 crashIfBadBooleanString(bs_enforceMin, "bs_enforceMin", "util_number.isValidRangeOpt");
 crashIfBadBooleanString(bs_enforceMax, "bs_enforceMax", "util_number.isValidRangeOpt");
 if(bs_enforceMin == "false"  ||  bs_enforceMax == "false")  {
   //At least one of the bounds are not being enforced.
   return true;
 }
 return !(i_min > i_max);

} function isValidRange(i_min, i_max) {

 return isValidRangeOpt(i_min, "true", i_max, "true");

} function isValidNumber(i_number, i_min, i_max) {

 return isValidNumberOpt(i_number, i_min, "true", i_max, "true");

} /**

 It is assumed that the range is valid.  You will get unpredictable results if it is not.
**/

function isValidNumberOpt(i_number, i_min, bs_enforceMin, i_max, bs_enforceMax) {

 crashIfMissing("util_number.isValidNumber", i_number, "i_number");
       //alert("isValidRangeOpt(" + i_number + ", " + i_min + ", " + bs_enforceMin + ", " + i_max + ", " + bs_enforceMax + ")...\n...isValidRangeOpt(" + i_min + ", " + bs_enforceMin + ", " + i_number + ", "true")=" + isValidRangeOpt(i_min, bs_enforceMin, i_number, "true") + "\n...isValidRangeOpt(" + i_number + ", "true", " + i_max + ", " + bs_enforceMax + ")=" + isValidRangeOpt(i_number, "true", i_max, bs_enforceMax));
 return (isValidRangeOpt(i_min, bs_enforceMin, i_number, "true")  &&
         isValidRangeOpt(i_number, "true", i_max, bs_enforceMax));

}

/**************************************************************************************************

 utility.js...START
 Do not edit this file.  This file is dynamically generated by the validate_form.js
 ant build process
**************************************************************************************************/

/**

 VALIDATE_FORM.JS
 Comprehensive solution for validating HTML forms.
 Copyright (C) 2002, Jeff Epstein, jeff_epstein@yahoo.ru, http://www.jeffyjeffy.ru#download
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 This program 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 General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
**/

//GLOBAL VARIABLES...start

 //A secret public global variable.  For testing purposes, you may want to
 //avoid re-displaying the error after the alert box (within H1 tags).
 //
 //This prevents the crash function from re-presenting the
 //error, after the alert box, within H1 tags.  It makes it so you
 //don"t have to press the back button between each error, in order
 //to get back to this page.
 var bCRASH_ONLY_ALERT_BOX = false;
 //This is automatically manipulated by this js file.  It is private
 //and should never be altered.
 var bCrashed = false;

//GLOBAL VARIABLES...end /**

 Present an error message in an alert box, and also print the provided error message to screen, surrounded by H1 tags.  This function is intended for programming errors, not user errors.
 Although execution is not truly interrupted, this should be significant enough to alert the programmer to an error.
 PARAMETERS
   s_callingFuncAndError
     The function name, followed by the error message.
 RETURNS
   false
     Always.
**/

function crash(s_callingFuncAndError) {

 alert("-------ERROR-------\n\nERROR in " + s_callingFuncAndError);
 if(!bCRASH_ONLY_ALERT_BOX)  {
document.writeln("

ERROR in " + s_callingFuncAndError + "

");
 }
 bCrashed = true;
 return false;

} /**

 Was crash() called?
 RETURNS
   true
     If crash() was called.
   false
     If crash() was never called...or when it was, but you since called resetCrashedFlag().
**/

function hasCrashed() {

 return bCrashed;

} /**

 Make it appear as if crash() was never called, regardless of whether or not it actually was.  This is probably only useful for testing purposes.
**/

function resetCrashedFlag() {

 bCrashed = false;

} /**

 Conditionally print the provided message in an alert box.
 PARAMETERS
   b_condition
     If true, present s_message in an alert box.  If false, do nothing.
   s_message
     The message to present in an alert box, should b_condition be true.  If b_condition is false, this parameter is ignored.
 RETURNS
   true
     If b_condition is true.
   false
     If b_condition is false.
**/

function calert(b_condition, s_message) {

 if(b_condition)  {
   alert(s_message);
   return false;
 }
 return true;

}

/**

 Convenience function to print an error message, should a required parameter not be provided.
 PARAMETERS
   s_callingFileFunc
     Passed directly to crash, if !o_param.  If o_param is true, this parameter is ignored.
   s_paramName
     The name of o_param, only for the potential error message.  If o_param is true, this parameter is ignored.
   o_param
     The required parameter.  If "false" (!o_param) the an error message is printed.
 RETURNS
   true
     If o_param is true.
   false
     If o_param is false.
**/

function crashIfMissing(s_callingFileFunc, s_paramName, o_param) {

 if(!o_param)  {
   return crash(s_callingFileFunc + ":  Required parameter " + s_paramName + " not provided.");
 }
 return true;

} /**

 A single unit test.  If the actual result differs from the actual, an error alert box is presented.
 PARAMETERS
   s_nameOfTest
     The name of the calling JavaScript file and function name, currently being tested.  Required.
   i_testNumber
     The number of the test, for potential error messages only.  Required.
   s_expected
     The expected response from this test.
   s_actual
     The actual response from this test.
 RETURNS
   true
     If s_expected equals s_actual.
   false
     If s_expected does not equal s_actual.
**/

function test(s_nameOfTest, i_testNumber, s_expected, s_actual) {

 crashIfMissing(s_nameOfTest, "s_nameOfTest", "utility.test");
 crashIfMissing(i_testNumber, "i_testNumber", "utility.test");
 if(s_expected != s_actual)  {
   alert("---ERROR---\n\n\tTest name:\t" + s_nameOfTest + "\n\tTest number:\t" + i_testNumber + "\n\tExpected:\t"" + s_expected + ""\n\tActual:\t\t"" + s_actual + """);
   return false;
 }
 return true;

} function crashIfBadBooleanString(bs_potential, s_variableName, s_callingFunc) {

 if(!bs_potential)  {
   return crash(s_callingFunc + ":  " + s_variableName + " must be a *string*, provided, and equal to either "true" or "false".  It is currently a *boolean* equal to "false".");
 }
 if(bs_potential != "true"  &&  bs_potential != "false")  {
   var sValue = "string equal to "" + bs_potential;
   if(typeof(bs_potential) == "boolean")  {
     //It is equal to *boolean* true.  It"s not a string.
     //Note that it"s NOT false, because the first line of this
     //function eliminated this possibility.
     sValue = "*boolean* equal to "" + bs_potential;
   }
   return crash(s_callingFunc + ":  " + s_variableName + " must be a string, provided, and equal to either "true" or "false".  It is currently a " + sValue + "".");
 }

} function crashIfBadBooleanStringOpt(bs_potential, s_variableName, s_callingFunc) {

 if(!bs_potential)  {
   return;
 }
 //bs_potential has been provided.
 if(bs_potential != "true"  &&  bs_potential != "false")  {
   var sValue = "string equal to "" + bs_potential + "";
   if(typeof(bs_potential) == "boolean")  {
     //It is equal to *boolean* true.  It"s not a string.
     //Note that it"s NOT false, because the first line of this
     //function eliminated this possibility.
     sValue = "*boolean* equal to "" + bs_potential + "";
   }
   return crash(s_callingFunc + ":  " + s_variableName + " is not required, but when provided it must be a string, and equal to either "true" or "false".  It is currently a " + sValue + "".");
 }

}

function getOptBooleanString(bs_potential, s_variableName, s_callingFunc) {

 if(bs_potential)  {
   crashIfBadBooleanStringOpt(bs_potential, s_variableName, s_callingFunc);
   return bs_potential;
 }  else  {
   return "false";
 }

}


/**

 Is the provided object an array?
 This concept comes from Kas Thomas, at
 http://www.planetpdf.ru/mainpage.asp?webpageid=1144
 PARAMETERS
   o_potentialArray
     The object that is analyzed to see if it is an array.  Required.
 RETURNS
   true
     If o_potentialArray is an array.
   false
     If o_potentialArray is anything but an array.
**/

function isArray(o_potentialArray) {

 crashIfMissing(o_potentialArray, "o_potentialArray", "utility.isArray");
 if(typeof o_potentialArray != "object")  {
   return false;
 }
 //It is definitely an object.
 return (o_potentialArray.constructor.toString().match(/array/i) != null);

} </SCRIPT> <SCRIPT LANGUAGE="JavaScript">

</SCRIPT> </HEAD> <BODY LINK="#0000FF" VLINK="#0000FF">

Example: Illegal Sub-Strings (2/2)


<FORM METHOD="post" action="#" name="form" onSubmit="

 return isFormValid(this);">


Textbox one (Nothing illegal): <INPUT TYPE="text" SIZE="20" NAME="textbox_one">
Textbox two (xxx, yyy, zzz): <INPUT TYPE="text" SIZE="20" NAME="textbox_two">
Textarea one (aaa bbb ccc): <TEXTAREA NAME="textarea_one" ROWS="2" COLS="30"></TEXTAREA>
Textarea two (Nothing illegal): <TEXTAREA NAME="textarea_two" ROWS="2" COLS="30"></TEXTAREA>

<P><INPUT TYPE="submit">     <INPUT TYPE="reset">

    <INPUT TYPE="button" onClick="return setGoodValues();" VALUE="Good">     <INPUT TYPE="button" onClick="return setBadValues();" VALUE="Bad">

</FORM> </BODY> </HTML>



 </source>
   
  


Log in email validation

   <source lang="html4strict">
 

<HTML> <HEAD>

  <TITLE>validate_form.js  --  Realistic Example:  Email Login</TITLE>

<SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript"> /**

 VALIDATE_FORM.JS
 Comprehensive solution for validating HTML forms.
 Copyright (C) 2002, Jeff Epstein, jeff_epstein@yahoo.ru, http://www.jeffyjeffy.ru#download
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 This program 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 General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
**/

/**

 See validate_form_documentation.html for information.
 NOTES TO SELF
   //alert("The CODE for getRCBSMTrackerArrIdx=" + getRCBSMTrackerArrIdx);
   I would like to add a function to get the number of elements that have a (any) value.
**/

//GLOBAL VARIABLES...start (do not alter this section)

 var sDBG_INDENT = "     ";
 var asRCBSM_TRACKER_NAME = "";
 var aiRCBSM_TRACKER_SEL_COUNT = "";
 var aiRCBSM_TRACKER_ARR_IDX = "";
 var iELEMENT_COUNT = -1;
 var bFIRST_DEBUG_SCREEN_SEEN = false;
 var sCURRENT_LENGTH_FOR_TA = "~CURRLEN~";
 var bPHONE_ZIP_FORMATS_VALIDATED = false;

//GLOBAL VARIABLES...end /**

 All messages must be at least one character in length.  If they are empty string, its as if they do not exist.
**/

function getFormErrorMsgs(f_orm, s_userErrorPrefix, i_debugPerScreen) {

 //This initialization function must be the very first line.
 initializeLocalVars();
 if(!arePhoneZipFormatsValid())  {
   return;
 }
 crashIfBadConfiguration(f_orm);
 if(hasCrashed())  {
   //For whatever reason utility.crash() was called, indicating
   //an error has occured.  Get out.  Get out while you still
   //can.
   return;
 }
 outputDebugging(f_orm, i_debugPerScreen);
 return getUserErrors(f_orm, s_userErrorPrefix);

} /**

 PRIVATE FUNCTIONS...start
**/
 function arePhoneZipFormatsValid()  {
   if(bPHONE_ZIP_FORMATS_VALIDATED)  {
     //Phone and zip code formats are checked only once.
     //They"ve already been checked once and are all were
     //found to be valid.
     return true;
   }
   //The formats have not yet been checked, or they were, but
   //were found to be invalid.
   var i = -1;
   var siPMin = "";
   var siPMax = "";
   for(i = 1; i < 11; i++)  {
     siPMin = eval("siPHONE_" + i + "_MINIMUM");
     siPMax = eval("siPHONE_" + i + "_MAXIMUM");
     if(!isPhoneFormatValid("false", siPMin, siPMax))  {
       alert("---  validate_form.js ERROR  ---\n\nPhone number format invalid:\n\tsiPHONE_" + i + "_MINIMUM="" + eval("siPHONE_" + i + "_MINIMUM") + ""\n\tsiPHONE_" + i + "_MAXIMUM="" + eval("siPHONE_" + i + "_MAXIMUM") + ""\n\nThe specific error message follows...");
       isPhoneFormatValid("true", siPMin, siPMax);
       return false;
     }
   }
   var siZRMin = "";
   var siZRMax = "";
   var siZAMin = "";
   var siZAMax = "";
   for(i = 1; i < 11; i++)  {
     siZRMin = eval("siZIP_" + i + "_RQD_MINIMUM");
     siZRMax = eval("siZIP_" + i + "_RQD_MAXIMUM");
     siZAMin = eval("siZIP_" + i + "_ALT_MINIMUM");
     siZAMax = eval("siZIP_" + i + "_ALT_MAXIMUM");
     if(!isZipFormatValid("false", siZRMin, siZRMax, siZAMin, siZAMax))  {
       alert("---  validate_form.js ERROR  ---\n\nZip code format invalid:\n\tsiZIP_" + i + "_RQD_MINIMUM="" + eval("siZIP_" + i + "_RQD_MINIMUM") + ""\n\tsiZIP_" + i + "_RQD_MAXIMUM="" + eval("siZIP_" + i + "_RQD_MAXIMUM") + ""\n\tsiZIP_" + i + "_ALT_MINIMUM="" + eval("siZIP_" + i + "_ALT_MINIMUM") + ""\n\tsiZIP_" + i + "_ALT_MAXIMUM="" + eval("siZIP_" + i + "_ALT_MAXIMUM") + ""\n\nThe specific error message follows...");
       isZipFormatValid("true", siZRMin, siZRMax, siZAMin, siZAMax)
       return false;
     }
   }
   bPHONE_ZIP_FORMATS_VALIDATED = true;
   return true;
 }
  function crashIfBadConfiguration(f_orm)  {
   crashIfMissing(f_orm, "f_orm", "validate_form.getFormErrorMsgs");
   crashIfBadBSSA("f_orm.asGlobalBadSubStrs", f_orm.asGlobalBadSubStrs);
   f_orm.bsGlobalTrimSpaces = getOptBooleanStringVF(f_orm.bsGlobalTrimSpaces, "f_orm.bsGlobalTrimSpaces");
   if(hasCrashed())  {
     return;
   }
   for(var i = 0; i < f_orm.length; i++)  {
     if(f_orm[i].type == "text"  ||  f_orm[i].type == "password")  {
       crashIfBadCfg_text(f_orm, f_orm[i]);
     }  else if(f_orm[i].type == "textarea")  {
       crashIfBadCfg_textarea(f_orm, f_orm[i]);
     }  else if(f_orm[i].type == "checkbox"  ||  f_orm[i].type == "select-multiple")  {
       crashIfBadCfg_cbsm(f_orm, i);
     }  else if(f_orm[i].type == "radio"  ||  f_orm[i].type == "select-one")  {
       crashIfBadCfg_rso(f_orm, i);
     }
   }
 }
 function outputDebugging(f_orm, i_debugPerScreen)  {
   if(!i_debugPerScreen  ||  i_debugPerScreen == -1)  {
     //No debugging is requested
     return;
   }
   if(typeof(i_debugPerScreen) != "number"  ||  i_debugPerScreen < 1)  {
     return crashVF("i_debugPerScreen is not required (currently "" + i_debugPerScreen + ""), but when provided, it must be a number (currently "" + typeof(i_debugPerScreen) + "") either equal to -1, or greater than zero.");
   }
   var iDebugItemsTotal = 0;
   var iDebugItemsThisRound = 0;
   var sDebugBuffer = "";
   var sDebugThisItem = "";
   for(var i = 0; i < f_orm.length; i++)  {
     if(f_orm[i].type == "text"  ||  f_orm[i].type == "password")  {
       sDebugThisItem = getDebugging_text(f_orm, f_orm[i]);
     }  else if(f_orm[i].type == "textarea")  {
       sDebugThisItem = getDebugging_textarea(f_orm, f_orm[i]);
     }  else if(f_orm[i].type == "checkbox"  ||  f_orm[i].type == "select-multiple")  {
       sDebugThisItem = getDebugging_cbsm(f_orm, i);
     }  else if(f_orm[i].type == "radio"  ||  f_orm[i].type == "select-one")  {
       sDebugThisItem = getDebugging_rso(f_orm, i);
     }
     if(sDebugThisItem)  {
       iDebugItemsTotal++;
       iDebugItemsThisRound++;
       sDebugBuffer += sDebugThisItem + "\n";
       if(iDebugItemsThisRound >= i_debugPerScreen)  {
         sDebugBuffer = getGlobalDebugging(sDebugBuffer, f_orm);
         alert("---  validate_form.js  DEBUGGING  (" + (iDebugItemsTotal - iDebugItemsThisRound + 1) + " to " + iDebugItemsTotal + " of " + iELEMENT_COUNT + ")  ---\n\n" + sDebugBuffer);
         iDebugItemsThisRound = 0;
         sDebugBuffer = "";
       }
       sDebugThisItem = "";
     }
   }
   if(sDebugBuffer)  {
     sDebugBuffer = getGlobalDebugging(sDebugBuffer, f_orm);
     alert("---  validate_form.js  DEBUGGING  (" + (iDebugItemsTotal - iDebugItemsThisRound + 1) + " to " + iDebugItemsTotal + " of " + iELEMENT_COUNT + ")  ---\n\n" + sDebugBuffer);
   }
 }
 function getGlobalDebugging(s_debugBuffer, f_orm)  {
   if(!bFIRST_DEBUG_SCREEN_SEEN)  {
     bFIRST_DEBUG_SCREEN_SEEN = true;
     var sGlobalDebug = "";
     if(f_orm.asGlobalBadSubStrs)  {
       sGlobalDebug = sDBG_INDENT + "f_orm.asGlobalBadSubStrs=  [ " + f_orm.asGlobalBadSubStrs + " ]\n";
     }
     if(f_orm.bsGlobalTrimSpaces == "true")  {
       sGlobalDebug += sDBG_INDENT + "f_orm.bsGlobalTrimSpaces=  "true"\n";
     }
     if(sGlobalDebug)  {
       return "---  GLOBAL SETTINGS  ---\n" + sGlobalDebug + "\n\n" + s_debugBuffer;
     }
   }
   //Either the first debugging screen has already been displayed, or
   //this is the first screen, but there is no global settings
   return s_debugBuffer;
 }
 function getUserErrors(f_orm, s_prefix)  {
   var sUserErrors = "";
   for(var i = 0; i < f_orm.length; i++)  {
     if(f_orm[i].type == "text"  ||  f_orm[i].type == "password")  {
       sUserErrors += getUserErrors_text(f_orm, i, s_prefix);
     }  else if(f_orm[i].type == "textarea")  {
       sUserErrors += getUserErrors_textarea(f_orm, i, s_prefix);
     }  else if(f_orm[i].type == "checkbox"  ||  f_orm[i].type == "select-multiple")  {
       sUserErrors += getUserErrors_cbsm(f_orm, i, s_prefix);
     }  else if(f_orm[i].type == "radio"  ||  f_orm[i].type == "select-one")  {
       sUserErrors += getUserErrors_rso(f_orm, i, s_prefix);
     }
   }
   return sUserErrors;
 }
 /**
   form_element must be provided, and a form element...START
  **/
   function getDebuggingNameType(form_element)  {
     return "---  " + form_element.name + "  ---          [" + form_element.type + "]\n";
   }
   function getDebuggingMsgRequired(s_msgRequired)  {
     if(s_msgRequired)  {
       return sDBG_INDENT + "sMsgRequired:  "" + s_msgRequired + ""\n";
     }
     return "";
   }
   function getDebuggingValue(s_value)  {
     if(s_value)  {
       return sDBG_INDENT + "VALUE:  "" + s_value + ""\n";
     }
     return "";
   }
 /**
   form_element must be provided, and a form element...END
  **/
 /**
   Do not call this function without first calling crashIfBadCfg_cbsm for the form-and-form-element.
  **/
 function getUserErrors_cbsm(f_orm, i_arrIdx, s_prefix)  {
   var feCbsm = f_orm[i_arrIdx];
   var sMsgRequired = "";
   var sMsgMCRange = "";
   var iMCMin = "";
   var iMCMax = "";
   if(feCbsm.type == "checkbox")  {
     if(getFirstArrIdx(feCbsm.name) != i_arrIdx)  {
       //This checkbox has already had its user errors retrieved.
       return "";
     }
     //This checkbox has not yet had its user errors retrieved.
     sMsgRequired = f_orm[feCbsm.name + ".sMsgRequired"];
     sMsgMCRange = f_orm[feCbsm.name + ".sMsgMCRange"];
     iMCMin = f_orm[feCbsm.name + ".iMCMin"];
     iMCMax = f_orm[feCbsm.name + ".iMCMax"];
   }  else  {
     //this is a select-multiple type...which has not yet had its
     //user errors retrieved.
     sMsgRequired = feCbsm.sMsgRequired
     sMsgMCRange = feCbsm.sMsgMCRange
     iMCMin = feCbsm.iMCMin
     iMCMax = feCbsm.iMCMax
   }
   var iMCSelCount = getMCSelectedCount(feCbsm.name);
   if(sMsgRequired  &&  iMCSelCount < 1)  {
     return s_prefix + sMsgRequired + "\n";
   }
   //If its required, a value has been selected.
   if(iMCSelCount < 1)  {
     //Its not required, and no value has been selected,
     //which is okay.
     return "";
   }
   if((iMCMin  &&  iMCMin > iMCSelCount)  ||
      (iMCMax  &&  iMCMax < iMCSelCount))  {
     return s_prefix + sMsgMCRange + "\n";
   }
   return "";
 }
 /**
   Do not call this function without first calling crashIfBadCfg_cbsm for the form-and-form-element.
  **/
 function getDebugging_cbsm(f_orm, i_arrIdx)  {
   var feCbsm = f_orm[i_arrIdx];
   var sMsgRequired = "";
   var sMsgMCRange = "";
   var iMCMin = "";
   var iMCMax = "";
   if(feCbsm.type == "checkbox")  {
     if(getFirstArrIdx(feCbsm.name) != i_arrIdx)  {
       //This checkbox has already been debugged.
       return "";
     }
     //This checkbox has not yet been debugged
     sMsgRequired = f_orm[feCbsm.name + ".sMsgRequired"];
     sMsgMCRange = f_orm[feCbsm.name + ".sMsgMCRange"];
     iMCMin = f_orm[feCbsm.name + ".iMCMin"];
     iMCMax = f_orm[feCbsm.name + ".iMCMax"];
   }  else  {
     //this is a select-multiple type...which has not yet been debugged.
     sMsgRequired = feCbsm.sMsgRequired
     sMsgMCRange = feCbsm.sMsgMCRange
     iMCMin = feCbsm.iMCMin
     iMCMax = feCbsm.iMCMax
   }
   var s = getDebuggingNameType(feCbsm) + getDebuggingMsgRequired(sMsgRequired);
   if(sMsgMCRange)  {
     s += sDBG_INDENT + "sMsgMCRange:  "" + sMsgMCRange + ""\n";
     if(iMCMin)  {
       s += sDBG_INDENT + sDBG_INDENT + "iMCMin:  " + iMCMin + "\n";
     }
     if(iMCMax)  {
       s += sDBG_INDENT + sDBG_INDENT + "iMCMax:  " + iMCMax + "\n";
     }
   }
   var iMCSelCount = getMCSelectedCount(feCbsm.name);
   if(iMCSelCount > 0)  {
     s += sDBG_INDENT + "NUMBER OF CHOICES SELECTED:  " + iMCSelCount + "\n";
   }
   return s;
 }
 function crashIfBadCfg_cbsm(f_orm, i_arrIdx)  {
   conditionallyAddRCBSM(f_orm, i_arrIdx);
   var feCbsm = f_orm[i_arrIdx];
   var sMsgMCRange = "";
   var iMCMin = "";
   var iMCMax = "";
   var iTotalOptions = -1;
   var sErrVarPre = "";
   var sErrVarPost = "";
   if(feCbsm.type == "checkbox")  {
     if(getFirstArrIdx(feCbsm.name) != i_arrIdx)  {
       //This checkbox has already been validated.
       return "";
     }
     //This checkbox has not yet been validated
     sMsgMCRange = f_orm[feCbsm.name + ".sMsgMCRange"];
     iMCMin = f_orm[feCbsm.name + ".iMCMin"];
     iMCMax = f_orm[feCbsm.name + ".iMCMax"];
     iTotalOptions = f_orm[feCbsm.name].length;
     sErrVarPre = "f_orm["" + feCbsm.name;
     sErrVarPost = ""]";
   }  else  {
     //this is a select-multiple type...which has not yet been validated.
     sMsgMCRange = feCbsm.sMsgMCRange;
     iMCMin = feCbsm.iMCMin;
     iMCMax = feCbsm.iMCMax;
     iTotalOptions = feCbsm.length;
     sErrVarPre = feCbsm.name;
     sErrVarPost = "";
   }
   if(sMsgMCRange)  {
     if(!iMCMin  &&  !iMCMax)  {
       return crashVF(sErrVarPre + ".sMsgMCRange" + sErrVarPost + " has been provided (currently "" + sMsgMCRange + ""), but neither " + sErrVarPre + ".iMCMin" + sErrVarPost + " nor " + sErrVarPre + ".iMCMax" + sErrVarPost + " have been provided.  At least one of these bounds are required.");
     }
     if(iMCMin)  {
       if(!isInteger(iMCMin))  {
         return crashVF(sErrVarPre + ".iMCMin" + sErrVarPost + " has been provided, but is not of type number.  Currently of type "" + typeof(iMCMin) + "" and equal to "" + iMCMin + "".");
       }
       if(iMCMin < 1  ||  iMCMin > iTotalOptions)  {
         return crashVF(sErrVarPre + ".iMCMin" + sErrVarPost + " has been provided (currently " + iMCMin + "), but is either less than one, or greater than the total number of options (" + iTotalOptions + ").");
       }
     }
     if(iMCMax)  {
       if(!isInteger(iMCMax))  {
         return crashVF(sErrVarPre + ".iMCMax" + sErrVarPost + " has been provided, but is not of type number.  Currently of type "" + typeof(iMCMax) + "" and equal to "" + iMCMax + "".");
       }
       if(iMCMax < 1  ||  iMCMax > iTotalOptions)  {
         return crashVF(sErrVarPre + ".iMCMax" + sErrVarPost + " has been provided (currently " + iMCMax + "), but is either less than one, or greater than the total number of options (" + iTotalOptions + ").");
       }
     }
     if(iMCMin  &&  iMCMax  &&  iMCMin > iMCMax)  {
       return crashVF(sErrVarPre + ".sMsgMCRange" + sErrVarPost + " has been provided (currently "" + sMsgMCRange + ""), and both " + sErrVarPre + ".iMCMin" + sErrVarPost + " (currently " + iMCMin + ") and " + sErrVarPre + ".iMCMax" + sErrVarPost + " (currently " + iMCMax + ") have been provided.  However, iMCMin must be less than or equal to iMCMax, which it is not.");
     }
   }  else if(iMCMin  ||  iMCMax)  {
     return crashVF(sErrVarPre + ".sMsgMCRange" + sErrVarPost + " has *not* been provided, but at least one of " + sErrVarPre + ".iMCMin" + sErrVarPost + " (currently "" + iMCMin + "") or " + sErrVarPre + ".iMCMax" + sErrVarPost + " (currently "" + iMCMax + "") has been provided.");
   }
 }
 /**
   Do not call this function without first calling crashIfBadCfg_rso for the form-and-form-element.
  **/
 function getUserErrors_rso(f_orm, i_arrIdx, s_prefix)  {
   var feRso = f_orm[i_arrIdx];
   var sValue = "";
   var sMsgRequired = "";
   if(feRso.type == "radio")  {
     if(getFirstArrIdx(feRso.name) != i_arrIdx)  {
       //We already debugged this radio element.
       return "";
     }
     sMsgRequired = f_orm[feRso.name + ".sMsgRequired"];
     sValue = getRadioValue(f_orm, feRso.name);
   }  else if(feRso.selectedIndex > -1) {
     sMsgRequired = feRso.sMsgRequired;
     sValue = feRso[feRso.selectedIndex].value;
   }
   if(sMsgRequired  &&  !sValue)  {
     return s_prefix + sMsgRequired + "\n";
   }
   //If its required, a value has been provided.
   return "";
 }
 /**
   Do not call this function without first calling crashIfBadCfg_rso for the form-and-form-element.
  **/
 function getDebugging_rso(f_orm, i_arrIdx)  {
   var feRso = f_orm[i_arrIdx];
   var sValue = "";
   var sMsgRequired = "";
   if(feRso.type == "radio")  {
     if(getFirstArrIdx(feRso.name) != i_arrIdx)  {
       //We already debugged this radio element.
       return "";
     }
     sMsgRequired = f_orm[feRso.name + ".sMsgRequired"];
     sValue = getRadioValue(f_orm, feRso.name);
   }  else if(feRso.selectedIndex > -1) {
     sMsgRequired = feRso.sMsgRequired;
     sValue = feRso[feRso.selectedIndex].value;
   }
   return getDebuggingNameType(feRso) + getDebuggingMsgRequired(sMsgRequired) + getDebuggingValue(sValue);
 }
 function getRadioValue(f_orm, s_radioName)  {
   var feRadio = f_orm[s_radioName];
   for(var i = 0; i < feRadio.length; i++)  {
     if(feRadio[i].checked)  {
       return feRadio[i].value;
     }
   }
   return "";
 }
 function crashIfBadCfg_rso(f_orm, i_arrIdx)  {
   var feRso = f_orm[i_arrIdx];
   if(feRso.type == "radio")  {
     conditionallyAddRCBSM(f_orm, i_arrIdx);
   }  else  {
     iELEMENT_COUNT++;
   }
   //Nothing to validate.  The only attribute that
   //can be associated to a radio or select-one type
   //is sMsgRequired...  Which either is or isn"t...
   //doesn"t matter which.
 }
 function conditionallyAddRCBSM(f_orm, i_arrIdx)  {
   var feCbsm = f_orm[i_arrIdx];
   if(wasRCBSMalreadyFound(feCbsm.name))  {
     //We already analyzed this element.
     return;
   }
   iELEMENT_COUNT++;
   addRCBSMtoTracker(f_orm, feCbsm, i_arrIdx);
 }
 /**
   Do not call this function without first calling crashIfBadCfg_textarea for the form-and-form-element.
  **/
 function getUserErrors_textarea(f_orm, i_arrIdx, s_prefix)  {
   var feTA = f_orm[i_arrIdx];
   if(feTA.sMsgRequired  &&  !feTA.value)  {
     return s_prefix + feTA.sMsgRequired + "\n";
   }
   if(!feTA.value)  {
     return "";
   }
   if(needsToBeTrimmed(f_orm, feTA))  {
     feTA.value = trimSpaces(feTA.value);
   }
   if(feTA.sMsgBadLength  &&
      (feTA.value.length < feTA.iMinLength  ||
       feTA.value.length > feTA.iMaxLength))  {
     return s_prefix + getBadLengthMsg(feTA) + "\n";
   }
   return getBadSubStrMessage(feTA.value, f_orm, feTA.asBadSubStrs, feTA.bsNoBadSubStrings, s_prefix, feTA.sMsgBadSubStr);
 }
 function getBadLengthMsg(fe_tta)  {
   var sMsg = fe_tta.sMsgBadLength;
   var iCLArrIdx = sMsg.indexOf(sCURRENT_LENGTH_FOR_TA);
   if(iCLArrIdx != -1)  {
     sMsg = sMsg.substring(0, iCLArrIdx) + fe_tta.value.length + sMsg.substring((iCLArrIdx + sCURRENT_LENGTH_FOR_TA.length), (sMsg.length + 1));
   }
   return sMsg;
 }
 function getBadSubStrMessage(s_value, f_orm, as_badSubStrs, bs_noBadSubStrings, s_prefix, s_errorMessage)  {
   if(!s_value)  {
     //Theres no value, so it can"t have any illegal sub-string.
     return "";
   }
   if(bs_noBadSubStrings == "true")  {
     //This element is exempt.
     return "";
   }
   //"x" is important...1/2
   var asBadSubStrs = "x";
   if(f_orm.asGlobalBadSubStrs)  {
     asBadSubStrs = f_orm.asGlobalBadSubStrs;
   }
   if(as_badSubStrs)  {
     asBadSubStrs = as_badSubStrs;
   }
   //"x" is important...2/2
   if(asBadSubStrs == "x")  {
     //There are no sub-strings to consider illegal.
     return "";
   }
   //There *are* sub-strings to be considered illegal.
   for(var i = 0; i < asBadSubStrs.length; i++)  {
     if(s_value.indexOf(asBadSubStrs[i]) != -1)  {
       return s_prefix + s_errorMessage + "\n";
     }
   }
   return "";
 }
 /**
   Do not call this function without first calling crashIfBadCfg_textarea for the form-and-form-element.
  **/
 function getDebugging_textarea(f_orm, fe_textarea)  {
   var s = getDebuggingNameType(fe_textarea) + getDebuggingMsgRequired(fe_textarea.sMsgRequired);
   if(fe_textarea.bsNoBadSubStrings == "true")  {
     s += sDBG_INDENT + "bsNoBadSubStrings:  "" + fe_textarea.bsNoBadSubStrings + ""\n";
   }  else if(f_orm.asGlobalBadSubStrs  ||  fe_textarea.asBadSubStrs)  {
     if(fe_textarea.asBadSubStrs)  {
       s += sDBG_INDENT + "asBadSubStrs:  [" + fe_textarea.asBadSubStrs + "]\n";
     }  else if(f_orm.asGlobalBadSubStrs)  {
       s += sDBG_INDENT + "f_orm.asGlobalBadSubStrs:  [" + f_orm.asGlobalBadSubStrs + "]\n";
     }
     s += sDBG_INDENT + sDBG_INDENT + "sMsgBadSubStr:  "" + fe_textarea.sMsgBadSubStr + ""\n";
   }
   if(fe_textarea.sMsgBadLength)  {
     s += sDBG_INDENT + "sMsgBadLength:  "" + fe_textarea.sMsgBadLength + ""\n";
     if(fe_textarea.iMinLength)  {
       s += sDBG_INDENT + sDBG_INDENT + "iMinLength:  " + fe_textarea.iMinLength + "\n";
     }
     if(fe_textarea.iMaxLength)  {
       s += sDBG_INDENT + sDBG_INDENT + "iMaxLength:  " + fe_textarea.iMaxLength + "\n";
     }
   }
   s += getDebuggingValue(fe_textarea.value);
   return s;
 }
 function crashIfBadCfg_textarea(f_orm, fe_textarea)  {
   crashIfMissing(fe_textarea, "fe_textarea", "validate_form.crashIfBadCfg_textarea");
   if(fe_textarea.type != "textarea")  {
     return crashVF("fe_textarea must be of type "text".  Currently "" + fe_textarea.type + ""...SANITY CHECK.  SHOULD NEVER HAPPEN.");
   }
   iELEMENT_COUNT++;
   var sName = sName;
   fe_textarea.bsNoBadSubStrings = getOptBooleanStringVF(fe_textarea.bsNoBadSubStrings, "f_orm." + sName + ".bsNoBadSubStrings");
   crashIfNBSSError(sName, fe_textarea.bsNoBadSubStrings, f_orm.asGlobalBadSubStrs, fe_textarea.asBadSubStrs);
   if(fe_textarea.bsNoBadSubStrings == "false"  &&
     (f_orm.asGlobalBadSubStrs  ||  fe_textarea.asBadSubStrs)  &&
     !fe_textarea.sMsgBadSubStr)  {
     return crashVF("Either f_orm.asGlobalBadSubStrs (currently [" + f_orm.asGlobalBadSubStrs + "]) or f_orm." + sName + ".asBadSubStrs (currently [" + fe_textarea.asBadSubStrs + "]) have  been provided, AND f_orm." + sName + ".bsNoBadSubStrings equals "false" (meaning there are sub-strings that are illegal for this field).  This means that f_orm." + sName + ".sMsgBadSubStr is required.  However, f_orm." + sName + ".sMsgBadSubStr has not been provided.");
   }
   crashIfBadSpaceTrimConfig(f_orm, fe_textarea);
   var iMin = fe_textarea.iMinLength;
   var iMax = fe_textarea.iMaxLength;
   if(fe_textarea.sMsgBadLength)  {
     if(!iMin  &&  !iMax)  {
       return crashVF("f_orm." + sName + ".sMsgBadLength has been provided (currently "" + fe_textarea.sMsgBadLength + ""), but neither f_orm." + sName + ".iMinLength nor f_orm." + sName + ".iMaxLength have been provided.");
     }
     if(iMin  &&  (!isInteger(iMin)  ||  iMin < 1))  {
       return crashVF("Both f_orm." + sName + ".sMsgBadLength (currently "" + fe_textarea.sMsgBadLength + "") and f_orm." + sName + ".iMinLength (currently " + iMin + ") have been provided, but iMinLength must be an integer, and at least equal to one.  Additional information:  f_orm." + sName + ".iMaxLength currently equals " + iMax + ".");
     }
     if(iMax  &&  (!isInteger(iMax)  ||  iMax < 1))  {
       return crashVF("Both f_orm." + sName + ".sMsgBadLength (currently "" + fe_textarea.sMsgBadLength + "") and f_orm." + sName + ".iMaxLength (currently "" + iMax + "") have been provided, but iMaxLength must be an integer, and at least equal to one.  Additional information:  f_orm." + sName + ".iMinLength currently equals " + iMin + ".");
     }
     if(iMin  &&  iMax  &&  iMin > iMax)  {
       return crashVF("f_orm." + sName + ".sMsgBadLength (currently "" + fe_textarea.sMsgBadLength + ""), f_orm." + sName + ".iMinLength (currently " + iMin + ") and f_orm." + sName + ".iMaxLength (currently " + iMax + ") have all been provided, but iMinLength must be less than or equal to iMaxLength.");
     }
   }  else if(iMin  ||  iMax)  {
     return crashVF("f_orm." + sName + ".sMsgBadLength has *not* been provided, but at least one of f_orm." + sName + ".iMinLength (currently " + iMin + ") and f_orm." + sName + ".iMaxLength (currently " + iMax + ") have been provided.");
   }
 }
 /**
   Do not call this function without first calling crashIfBadCfg_textarea for the form-and-form-element.
  **/
 function getUserErrors_text(f_orm, i_arrIdx, s_prefix)  {
   var feText = f_orm[i_arrIdx];
   if(needsToBeTrimmed(f_orm, feText))  {
     feText.value = trimSpaces(feText.value);
   }
   if(feText.sMsgRequired  &&  !feText.value)  {
     return s_prefix + feText.sMsgRequired + "\n";
   }
   if(!feText.value)  {
     return "";
   }
   //It is assumed/expected that there is only one "sMsgTxt"
   //variables associated to feText.  The only reason that
   //the following ifs are not else-ifs, is because of the
   //for loop of eval statements.
   if(feText.sMsgTxtEmail)  {
     if(!isEmail(feText.value))  {
       return s_prefix + feText.sMsgTxtEmail + "\n";
     }
   }  else if(feText.sMsgTxtInt)  {
     if(!isInteger(feText.value)  ||
        (feText.iIntMin  &&  feText.iIntMin > feText.value)  ||
        (feText.iIntMax  &&  feText.iIntMax < feText.value))  {
       return s_prefix + feText.sMsgTxtInt + "\n";
     }
   }  else if(feText.sMsgTxtDec)  {
     if(!isDecimal(feText.value)  ||
        (feText.iDecMin  &&  feText.iDecMin > feText.value)  ||
        (feText.iDecMax  &&  feText.iDecMax < feText.value))  {
       return s_prefix + feText.sMsgTxtDec + "\n";
     }
   }  else if(feText.sMsgTxtPhone)  {
     var sPhoneStripped = getValidPhone1(feText.value);
     if(!sPhoneStripped)  {
       return s_prefix + feText.sMsgTxtPhone + "\n";
     }
     feText.value = sPhoneStripped;
   }  else if(feText.sMsgTxtZip)  {
     var sZipStripped = getValidZip1(feText.value);
     if(!sZipStripped)  {
       return s_prefix + feText.sMsgTxtZip + "\n";
     }
     feText.value = sZipStripped;
   }  else  {
     for(var i = 1; i < 11; i++)  {
       if(eval("feText.sMsgTxtPhone" + i))  {
         var sPhoneStripped = eval("getValidPhone" + i + "(feText.value)");
         if(!sPhoneStripped)  {
           return s_prefix + eval("feText.sMsgTxtPhone" + i) + "\n";
         }
         feText.value = sPhoneStripped;
         break;    //There is only one sMsgTxt* per element
       }
       if(eval("feText.sMsgTxtZip" + i))  {
         var sZipStripped = eval("getValidZip" + i + "(feText.value)");
         if(!sZipStripped)  {
           return s_prefix + eval("feText.sMsgTxtZip" + i) + "\n";
         }
         feText.value = sZipStripped;
         break;    //There is only one sMsgTxt* per element
       }
     }
   }
   if(feText.sMsgBadLength  &&  feText.value.length < feText.iMinLength)  {
     return s_prefix + getBadLengthMsg(feText) + "\n";
   }
   return getBadSubStrMessage(feText.value, f_orm, feText.asBadSubStrs, feText.bsNoBadSubStrings, s_prefix, feText.sMsgBadSubStr);
 }
 function needsToBeTrimmed(f_orm, fe_tta)  {
   if(!fe_tta.value)  {
     return false;
   }
   if(fe_tta.bsDontTrimSpaces == "true")  {
     return false;
   }
   if(f_orm.bsGlobalTrimSpaces == "true"  ||  fe_tta.bsTrimSpaces == "true")  {
     return isSurroundedBySpace(fe_tta.value);
   }
 }
 /**
   Do not call this function without first calling crashIfBadCfg_text for the form-and-form-element.
  **/
 function getDebugging_text(f_orm, fe_text)  {
   var sDBG_INDENT = "     ";
   var s = getDebuggingNameType(fe_text) + getDebuggingMsgRequired(fe_text.sMsgRequired);
   var bEM = fe_text.sMsgTxtEmail;
   var bInt = fe_text.sMsgTxtInt;
   var bDec = fe_text.sMsgTxtDec;
   var bZC = fe_text.sMsgTxtZip;
   var bZC1 = fe_text.sMsgTxtZip1;
   var bZC2 = fe_text.sMsgTxtZip2;
   var bZC3 = fe_text.sMsgTxtZip3;
   var bZC4 = fe_text.sMsgTxtZip4;
   var bZC5 = fe_text.sMsgTxtZip5;
   var bZC6 = fe_text.sMsgTxtZip6;
   var bZC7 = fe_text.sMsgTxtZip7;
   var bZC8 = fe_text.sMsgTxtZip8;
   var bZC9 = fe_text.sMsgTxtZip9;
   var bZC10 = fe_text.sMsgTxtZip10;
   var bPN = fe_text.sMsgTxtPhone;
   var bPN1 = fe_text.sMsgTxtPhone1;
   var bPN2 = fe_text.sMsgTxtPhone2;
   var bPN3 = fe_text.sMsgTxtPhone3;
   var bPN4 = fe_text.sMsgTxtPhone4;
   var bPN5 = fe_text.sMsgTxtPhone5;
   var bPN6 = fe_text.sMsgTxtPhone6;
   var bPN7 = fe_text.sMsgTxtPhone7;
   var bPN8 = fe_text.sMsgTxtPhone8;
   var bPN9 = fe_text.sMsgTxtPhone9;
   var bPN10 = fe_text.sMsgTxtPhone10;
   if(bEM)  {
     s += sDBG_INDENT + "sMsgTxtEmail:  "" + fe_text.sMsgTxtEmail + ""\n";
   }
   if(bZC)  {
     s += sDBG_INDENT + "sMsgTxtZip:  "" + fe_text.sMsgTxtZip + ""\n";
   }
   if(bPN)  {
     s += sDBG_INDENT + "sMsgTxtPhone:  "" + fe_text.sMsgTxtPhone + ""\n";
   }
   for(var i = 1; i < 11; i++)  {
     if(eval("bPN" + i))  {
       s += sDBG_INDENT + "sMsgTxtPhone" + i + ":  "" + eval("fe_text.sMsgTxtPhone" + i) + ""\n";
     }
     if(eval("bZC" + i))  {
       s += sDBG_INDENT + "sMsgTxtZip" + i + ":  "" + eval("fe_text.sMsgTxtZip" + i) + ""\n";
     }
   }
   if(bInt)  {
     s += sDBG_INDENT + "sMsgTxtInt:  "" + fe_text.sMsgTxtInt + ""\n";
     if(fe_text.iIntMin)  {
       s += sDBG_INDENT + sDBG_INDENT + "iIntMin:  "" + fe_text.iIntMin + ""\n";
     }
     if(fe_text.iIntMax)  {
       s += sDBG_INDENT + sDBG_INDENT + "iIntMax:  "" + fe_text.iIntMax + ""\n";
     }
   }
   if(bDec)  {
     s += sDBG_INDENT + "sMsgTxtDec:  "" + fe_text.sMsgTxtDec + ""\n";
     if(fe_text.iDecMin)  {
       s += sDBG_INDENT + sDBG_INDENT + "iDecMin:  "" + fe_text.iDecMin + ""\n";
     }
     if(fe_text.iDecMax)  {
       s += sDBG_INDENT + sDBG_INDENT + "iDecMax:  "" + fe_text.iDecMax + ""\n";
     }
   }
   if(fe_text.bsNoBadSubStrings == "true")  {
     s += sDBG_INDENT + "bsNoBadSubStrings:  "" + fe_text.bsNoBadSubStrings + ""\n";
   }  else if(!bInt  &&  !bDec  &&
                  !bZC   &&  !bZC1  &&  !bZC2  &&  !bZC3  &&  !bZC4  &&  !bZC5  &&
                  !bZC6  &&  !bZC7  &&  !bZC8  &&  !bZC9  &&  !bZC10  &&
                  !bPN   &&  !bPN1  &&  !bPN2  &&  !bPN3  &&  !bPN4  &&  !bPN5  &&
                  !bPN6  &&  !bPN7  &&  !bPN8  &&  !bPN9  &&  !bPN10  &&
              (f_orm.asGlobalBadSubStrs  ||  fe_text.asBadSubStrs))  {
     var sSecondIndent = "";
     if(fe_text.asBadSubStrs)  {
       s += sDBG_INDENT + "asBadSubStrs:  [" + fe_text.asBadSubStrs + "]\n";
       sSecondIndent = sDBG_INDENT;
     }
   }
   if(fe_text.sMsgBadLength)  {
     s += sDBG_INDENT + "sMsgBadLength:  "" + fe_text.sMsgBadLength + ""\n" + sDBG_INDENT + sDBG_INDENT + "iMinLength:  " + fe_text.iMinLength + "\n";
     if(fe_text.maxLength)  {
       s += sDBG_INDENT + sDBG_INDENT + "MAXLENGTH:  " + fe_text.MAXLENGTH + "\n";
     }
   }
   s += getDebuggingValue(fe_text.value);
   return s;
 }
 function crashIfBadCfg_text(f_orm, fe_text)  {
   crashIfMissing(fe_text, "fe_text", "validate_form.crashIfBadCfg_text");
   if(fe_text.type != "text"  &&  fe_text.type != "password")  {
     return crashVF("fe_text must be of type "text" or "password".  Currently "" + fe_text.type + ""...SANITY CHECK.  SHOULD NEVER HAPPEN.");
   }
   var sName = fe_text.name;
   iELEMENT_COUNT++;
   var bEM = fe_text.sMsgTxtEmail;
   var bInt = fe_text.sMsgTxtInt;
   var bDec = fe_text.sMsgTxtDec;
   var bZC = fe_text.sMsgTxtZip;
   var bPN = fe_text.sMsgTxtPhone;
   var iSpecialTypes = 0;
   var sSpecialTypes = "";
   if(bEM)  {
     iSpecialTypes++;
     sSpecialTypes += "sMsgTxtEmail...";
   }
   if(bInt)  {
     iSpecialTypes++;
     sSpecialTypes += "sMsgTxtInt...";
     crashIfBadIntDecCfg(fe_text.iIntMin, fe_text.iIntMax, "false", sName, "iIntMin", "iIntMax");
   }  else if(fe_text.iIntMin  ||  fe_text.iIntMax)  {
     return crashVF("f_orm." + sName + ".sMsgTxtInt has *not* been provided, but one or both of the sub-variables " + sName + ".iIntMin (currently "" + fe_text.iIntMin + "")/" + sName + ".iIntMax (currently "" + fe_text.iIntMax + "") have been provided.");
   }
   if(bDec)  {
     iSpecialTypes++;
     sSpecialTypes += "sMsgTxtDec...";
     crashIfBadIntDecCfg(fe_text.iDecMin, fe_text.iDecMax, "true", sName, "iDecMin", "iDecMax");
   }  else if(fe_text.iDecMin  ||  fe_text.iDecMax)  {
     return crashVF("f_orm." + sName + "." + sAnIntADec + " has *not* been provided, but one or both of the sub-variables " + sName + ".iDecMin (currently "" + fe_text.iDecMin + "")/" + sName + ".iDecMax (currently "" + fe_text.iDecMax + "") have been provided.");
   }
   if(bPN)  {
     iSpecialTypes++;
     sSpecialTypes += "sMsgTxtPhone...";
   }
   for(var i = 1; i < 11; i++)  {
     eval("var bPN" + i + " = fe_text.sMsgTxtPhone" + i);
     if(eval("bPN" + i))  {
       iSpecialTypes++;
       sSpecialTypes += "sMsgTxtPhone" + i + "...";
     }
   }
   if(bZC)  {
     iSpecialTypes++;
     sSpecialTypes += "sMsgTxtZip...";
   }
   for(var i = 1; i < 11; i++)  {
     eval("var bZC" + i + " = fe_text.sMsgTxtZip" + i);
     if(eval("bZC" + i))  {
       iSpecialTypes++;
       sSpecialTypes += "sMsgTxtZip" + i + "...";
     }
   }
   if(iSpecialTypes > 1)  {
     return crashVF("f_orm." + sName + " is of type "text", but has " + iSpecialTypes + " special text types associated to it.  Zero or one of the following special types may be used for a text form element:  sMsgTxtEmail, sMsgTxtInt, sMsgTxtDec, sMsgTxtZip, sMsgTxtZip1, sMsgTxtZip2, sMsgTxtZip3, sMsgTxtZip4, sMsgTxtZip5, sMsgTxtZip6, sMsgTxtZip7, sMsgTxtZip8, sMsgTxtZip9, sMsgTxtZip10, sMsgTxtPhone, sMsgTxtPhone1, sMsgTxtPhone2, sMsgTxtPhone3, sMsgTxtPhone4, sMsgTxtPhone5, sMsgTxtPhone6, sMsgTxtPhone7, sMsgTxtPhone8, sMsgTxtPhone9, sMsgTxtPhone10.\n\nActually existing special types found:  " + sSpecialTypes);
   }
   crashIfBadBSSA("f_orm." + sName + ".asBadSubStrs", fe_text.asBadSubStrs);
   fe_text.bsNoBadSubStrings = getOptBooleanStringVF(fe_text.bsNoBadSubStrings, "f_orm." + sName + ".bsNoBadSubStrings");
   crashIfNBSSError(sName, fe_text.bsNoBadSubStrings, f_orm.asGlobalBadSubStrs, fe_text.asBadSubStrs);
   if(fe_text.bsNoBadSubStrings == "false"  &&  !bInt  &&  !bDec  &&
        !bZC   &&  !bZC1  &&  !bZC2  &&  !bZC3  &&  !bZC4  &&  !bZC5  &&
        !bZC6  &&  !bZC7  &&  !bZC8  &&  !bZC9  &&  !bZC10  &&
        !bPN   &&  !bPN1  &&  !bPN2  &&  !bPN3  &&  !bPN4  &&  !bPN5  &&
        !bPN6  &&  !bPN7  &&  !bPN8  &&  !bPN9  &&  !bPN10  &&
     (f_orm.asGlobalBadSubStrs  ||  fe_text.asBadSubStrs)  &&
     !fe_text.sMsgBadSubStr)  {
     return crashVF("Either f_orm.asGlobalBadSubStrs (currently [" + f_orm.asGlobalBadSubStrs + "]) or f_orm." + sName + ".asBadSubStrs (currently [" + fe_text.asBadSubStrs + "]) have  been provided, AND f_orm." + sName + ".bsNoBadSubStrings equals "false" (meaning there are sub-strings that are illegal for this field) AND this text/password field does not have a "number" special type (sMsgTxtInt, sMsgTxtDec, sMsgTxtZip, sMsgTxtZip1, sMsgTxtZip2, sMsgTxtZip3, sMsgTxtZip4, sMsgTxtZip5, sMsgTxtZip6, sMsgTxtZip7, sMsgTxtZip8, sMsgTxtZip9, sMsgTxtZip10, sMsgTxtPhone, sMsgTxtPhone1, sMsgTxtPhone2, sMsgTxtPhone3, sMsgTxtPhone4, sMsgTxtPhone5, sMsgTxtPhone6, sMsgTxtPhone7, sMsgTxtPhone8, sMsgTxtPhone9, sMsgTxtPhone10).  This means that f_orm." + sName + ".sMsgBadSubStr is required.  However, f_orm." + sName + ".sMsgBadSubStr has not been provided.");
   }
   crashIfBadSpaceTrimConfig(f_orm, fe_text);
   var bIsSpecial = (bEM  ||  bInt  || bDec  ||
     bZC   ||  bZC1  ||  bZC2  ||  bZC3  ||  bZC4  ||  bZC5  ||
      bZC6  ||  bZC7  ||  bZC8  ||  bZC9  ||  bZC10  ||
      bPN   ||  bPN1  ||  bPN2  ||  bPN3  ||  bPN4  ||  bPN5  ||
      bPN6  ||  bPN7  ||  bPN8  ||  bPN9  ||  bPN10);
   if(bIsSpecial  &&
     (fe_text.bsTrimSpaces == "true"  ||  fe_text.bsDontTrimSpaces == "true"))  {
     return crashVF("Either f_orm." + sName + ".bsTrimSpaces (currently "" + fe_text.bsTrimSpaces + "") or f_orm." + sName + ".bsDontTrimSpaces (currently "" + fe_text.bsTrimSpaces + "") equal "true".  But this is illegal, because the element has these special types associated to it:  " + sSpecialTypes);
   }
   var iMin = fe_text.iMinLength;
   if(fe_text.sMsgBadLength)  {
     if(!iMin)  {
       return crashVF("f_orm." + sName + ".sMsgBadLength has been provided (currently "" + fe_text.sMsgBadLength + ""), but f_orm." + sName + ".iMinLength has not been provided");
     }
     if(iMin  &&  (!isInteger(iMin)  ||  iMin < 1))  {
       return crashVF("Both f_orm." + sName + ".sMsgBadLength (currently "" + fe_text.sMsgBadLength + "") and f_orm." + sName + ".iMinLength (currently "" + iMin + "") have been provided, but iMinLength must be an integer, and at least equal to one.");
     }
     //NOTE:  When MAXLENGTH is an attribute of the element,
     //fe_text.MAXLENGTH is undefined, but fe_text.maxLength
     //is not.  Things that make you go hmm.
     if(fe_text.maxLength  &&  fe_text.maxLength != -1  &&
        isInteger(fe_text.maxLength)  &&  iMin > fe_text.maxLength)  {
       return crashVF("Both f_orm." + sName + ".sMsgBadLength (currently "" + fe_text.sMsgBadLength + "") and f_orm." + sName + ".iMinLength (currently " + iMin + ") have been provided, but iMinLength must be an integer between one and f_orm." + sName + ".MAXLENGTH (currently " + fe_text.maxLength + "), inclusive.");
     }
   }  else if(iMin)  {
     return crashVF("f_orm." + sName + ".sMsgBadLength has *not* been provided, but the sub-attribute f_orm." + sName + ".iMinLength (currently " + iMin + ") has been provided.");
   }
   if(fe_text.iMaxLength)  {
     return crashVF("f_orm." + sName + ".iMaxLength (currently " + fe_text.iMaxLength + ") is only a legal sub-attribute for text elements.  To enforce maximum length in a text or password element, use the standard MAXLENGTH attribute.");
   }
 }
 //"di_" prefix stands for decimal-or-integer
 function crashIfBadIntDecCfg(di_min, di_max, bs_decimalAllowed, s_formLmntName, s_nameMin, s_nameMax)  {
   var sIntDecPostfix = "Int";
   var sAnIntADec = "an integer";
   var sIntDec = "integer";
   var sIsFuncName = "isInteger";
   if(bs_decimalAllowed == "true")  {
     sIntDecPostfix = "Dec";
     sAnIntADec = "a decimal";
     sIntDec = "decimal";
     sIsFuncName = "isDecimal";
   }
   if(di_min  &&  !isNumber(di_min, bs_decimalAllowed))  {
     return crashVF("f_orm." + s_formLmntName + ".sMsgTxt" + sIntDecPostfix + " has been provided, and the sub-variable " + s_formLmntName + "." + s_nameMin + " has also been provided.  However, " + s_nameMin + " must be " + sAnIntADec + ".  Currently "" + di_min + "".");
   }
   if(di_max  &&  !isNumber(di_max, bs_decimalAllowed))  {
     return crashVF("f_orm." + s_formLmntName + ".sMsgTxt" + sIntDecPostfix + " has been provided, and the sub-variable " + s_formLmntName + "." + s_nameMax + " has also been provided.  However, " + s_nameMax + " must be " + sAnIntADec + ".  Currently "" + di_max + "".");
   }
   if(di_min  &&  di_max  &&
     !isValidRange(di_min, di_max))  {
     return crashVF("f_orm." + s_formLmntName + ".sMsgTxt" + sIntDecPostfix + " has been provided, and both the sub-variables " + s_formLmntName + "." + s_nameMin + " and " + s_formLmntName + "." + s_nameMax + " have also been provided.  Both these variables are definitely legal " + sIntDec + "s (according to util_string." + sIsFuncName + "()), however, " + s_nameMin + " (currently "" + di_min + "") and " + s_nameMax + " (currently "" + di_max + "") are not a legal range according to util_number.isValidRange().");
   }
 }
 function crashIfBadSpaceTrimConfig(f_orm, fe_tta)  {
   fe_tta.bsTrimSpaces = getOptBooleanStringVF(fe_tta.bsTrimSpaces, "f_orm." + fe_tta.name + ".bsTrimSpaces");
   fe_tta.bsDontTrimSpaces = getOptBooleanStringVF(fe_tta.bsDontTrimSpaces, "f_orm." + fe_tta.name + ".bsDontTrimSpaces");
   if(f_orm.bsGlobalTrimSpaces == "true")  {
     if(fe_tta.bsTrimSpaces == "true")  {
       return crashVF("Both f_orm.bsGlobalTrimSpaces and f_orm." + fe_tta.name + ".bsTrimSpaces equal "true".  Only one of these variables may be "true".");
     }
   }  else  if(fe_tta.bsDontTrimSpaces == "true")  {
     return crashVF("f_orm.bsGlobalTrimSpaces has *not* been provided (or is equal to "false"), but f_orm." + fe_tta.name + ".bsDontTrimSpaces equals "true".  ");
   }
 }
 function crashIfNBSSError(s_textPwName, b_noBadSubStrings, as_globalBadSubStrs, as_badSubStrs)  {
   if(b_noBadSubStrings == "true"  &&
      (as_badSubStrs  ||  !as_globalBadSubStrs))  {
     return crashVF("f_orm." + s_textPwName + ".bsNoBadSubStrings equals "true", but either , f_orm.asGlobalBadSubStrs has *not* been provided (currently " + as_globalBadSubStrs + ") or f_orm." + s_textPwName + ".asBadSubStrs *has* been provided (currently " + as_badSubStrs + ").  When bsNoBadSubStrings equals "true", it is required that or asBadSubStrs not be provided and f_orm.asGlobalBadSubStrs should be provided.");
   }
 }
 function getRqdMissingMsg(s_requiredMsg, s_value)  {
   crashIfMissing(s_value, "s_value ("missing" means empty string)", "validate_form.getRqdMissingMsg");
   if(!s_requiredMsg)  {
     //This value is not required.
     return "";
   }
   //This value *is* required...
   if(s_value == "")  {
     //...but has not been provided.
     return s_requiredMsg;
   }
   //...and has been provided.
   return "";
 }
 /**
   Crash If the provided bad-sub-string-array is bad.
  **/
 function crashIfBadBSSA(s_variableName, as_badSubStrs)  {
   if(!as_badSubStrs)  {
     return;
   }
   var sRule = " is not required, but when it is provided, it must be of type array, at least one element in length, and each element must be of type string, at least one character in length, and all elements must be unique.  Currently, ";
   if(!isArray(as_badSubStrs))  {
     return crashVF("crashIfBadBSSA:  " + s_variableName + sRule + "it is of type "" + typeof(as_badSubStrs) + "".");
   }
   if(as_badSubStrs.length < 1)  {
     return crashVF("crashIfBadBSSA:  " + s_variableName + sRule + "it is zero elements in length.");
   }
   for(var i = 0; i < as_badSubStrs.length; i++)  {
     if(typeof(as_badSubStrs[i]) != "string")  {
       return crashVF("crashIfBadBSSA:  " + s_variableName + sRule + " s_variableName[" + i + "] is of type "" + typeof(as_badSubStrs[i]) + "".");
     }
     if(as_badSubStrs[i].length < 1)  {
       return crashVF("crashIfBadBSSA:  " + s_variableName + sRule + " s_variableName[" + i + "] is zero characters in length.");
     }
     for(var j = i + 1; j < as_badSubStrs.length; j++)  {
       if(as_badSubStrs[i] == as_badSubStrs[j])  {
         return crashVF("crashIfBadBSSA:  " + s_variableName + sRule + " Element " + i + " (currently "" + as_badSubStrs[i] + "") is equal to element " + j + ".");
       }
     }
   }
   //All elements are definitely of type string.
   for(var i = 0; i < as_badSubStrs.length; i++)  {
     for(var j = i + 1; j < as_badSubStrs.length; j++)  {
       if(as_badSubStrs[i] == as_badSubStrs[j])  {
         return crashVF("crashIfBadBSSA:  " + s_variableName + sRule + " Element " + i + " (currently "" + as_badSubStrs[i] + "") is equal to element " + j + ".");
       }
     }
   }
 }
 function  wasRCBSMalreadyFound(s_elementName)  {
   return (getRCBSMTrackerArrIdx(s_elementName) != -1);
 }
 function  getFirstArrIdx(s_elementName)  {
   var iArrIdx = getAndValidateRCBSMTArrIdx("getFirstArrIdx", s_elementName);
   var iFirstArrIdx = aiRCBSM_TRACKER_ARR_IDX[iArrIdx];
   if(iFirstArrIdx == -1)  {
     return crashVF("getFirstArrIdx:  Element named "" + s_elementName + "" *was* found in the tracker array objects, but it is of type select-multiple, which does not have multiple instances, and is therefore invalid for this function.  SANITY CHECK.  SHOULD NEVER HAPPEN.");
   }
   return iFirstArrIdx;
 }
 function  getMCSelectedCount(s_elementName)  {
   var iArrIdx = getAndValidateRCBSMTArrIdx("getMCSelectedCount", s_elementName);
   var iSelCt = aiRCBSM_TRACKER_SEL_COUNT[iArrIdx];
   if(iSelCt == -1)  {
     return crashVF("getMCSelectedCount:  Element named "" + s_elementName + "" *was* found in the tracker array objects, but it is of type radio, which is a single-choice element, and is therefore invalid for this function.  SANITY CHECK.  SHOULD NEVER HAPPEN.");
   }
   return iSelCt;
 }
 function getAndValidateRCBSMTArrIdx(s_callingFunction, s_elementName)  {
   var iArrIdx = getRCBSMTrackerArrIdx(s_elementName);
   if(iArrIdx == -1)  {
     return crashVF("getAndValidateRCBSMTArrIdx ("" + s_callingFunction + ""):  Element named "" + s_elementName + "" was not found in the tracker array objects.  SANITY CHECK.  SHOULD NEVER HAPPEN.");
   }
   return iArrIdx;
 }
 function  getRCBSMTrackerArrIdx(s_elementName)  {
   for(var i = 0; i < asRCBSM_TRACKER_NAME.length; i++)  {
     if(asRCBSM_TRACKER_NAME[i] == s_elementName)  {
       return i;
     }
   }
   return -1;
 }
 function addRCBSMtoTracker(f_orm, fe_rcbsm, i_formArrIdx)  {
   if(asRCBSM_TRACKER_NAME.length < 1)  {
     //This is the first to be tracked.  Just create a new
     //array containing this name as the only element.
     asRCBSM_TRACKER_NAME = [fe_rcbsm.name];
     aiRCBSM_TRACKER_SEL_COUNT = [getMCSelectedCountForTracker(f_orm, fe_rcbsm)];
     aiRCBSM_TRACKER_ARR_IDX = [getRCBSMFirstArrIdx(fe_rcbsm, i_formArrIdx)];
     return;
   }
   //At least one element is already being tracked.  Add this
   //element to the existing tracking arrays.
   if(wasRCBSMalreadyFound(fe_rcbsm.name))  {
     return crashVF("addRCBSMtoTracker:  Element named "" + fe_rcbsm.name + "" already exists in the TRACKER arrays.  SANITY CHECK.  SHOULD NEVER HAPPEN.");
   }
   var asTrackerNames = new Array(asRCBSM_TRACKER_NAME.length + 1);
   for(var i = 0; i < asTrackerNames.length; i++)  {
     if(i < (asTrackerNames.length - 1))  {
       asTrackerNames[i] = asRCBSM_TRACKER_NAME[i];
     }  else  {
       asTrackerNames[i] = fe_rcbsm.name;
     }
   }
   asRCBSM_TRACKER_NAME = asTrackerNames;
   var aiTrackerCounts = new Array(aiRCBSM_TRACKER_SEL_COUNT.length + 1);
   for(var i = 0; i < aiTrackerCounts.length; i++)  {
     if(i < (aiTrackerCounts.length - 1))  {
       aiTrackerCounts[i] = aiRCBSM_TRACKER_SEL_COUNT[i];
     }  else  {
       aiTrackerCounts[i] = getMCSelectedCountForTracker(f_orm, fe_rcbsm);
     }
   }
   aiRCBSM_TRACKER_SEL_COUNT = aiTrackerCounts;
   var aiTrackerArrIdx = new Array(aiRCBSM_TRACKER_ARR_IDX.length + 1);
   for(var i = 0; i < aiTrackerArrIdx.length; i++)  {
     if(i < (aiTrackerArrIdx.length - 1))  {
       aiTrackerArrIdx[i] = aiRCBSM_TRACKER_ARR_IDX[i];
     }  else  {
       aiTrackerArrIdx[i] = getRCBSMFirstArrIdx(fe_rcbsm, i_formArrIdx);
     }
   }
   aiRCBSM_TRACKER_ARR_IDX = aiTrackerArrIdx;
 }
 function getRCBSMFirstArrIdx(fe_rcbsm, i_formArrIdx)  {
   if(fe_rcbsm.type == "select-multiple")  {
     //select-multiple only has one instance in the form.  -1 indicates that.
     return -1;
   }
   return i_formArrIdx;
 }
 function getMCSelectedCountForTracker(f_orm, fe_rcbsm)  {
   if(fe_rcbsm.type != "radio"  &&
      fe_rcbsm.type != "checkbox"  &&
      fe_rcbsm.type != "select-multiple")  {
     return crashVF("getMCSelectedCount:  Element named "" + fe_rcbsm.name + "" is not of type radio, checkbox or select-multiple.  Type of this element is "" + fe_rcbsm.type + "".  SANITY CHECK.  SHOULD NEVER HAPPEN.");
   }
   if(fe_rcbsm.type == "radio")  {
     //This is not a multiple choice type.  -1 indicates that.
     return -1;
   }
   var iMCSelectedCount = 0;
   if(fe_rcbsm.type == "checkbox")  {
     for(var i = 0; i < f_orm[fe_rcbsm.name].length; i++)  {
       if(f_orm[fe_rcbsm.name][i].checked)  {
         iMCSelectedCount++;
       }
     }
     return iMCSelectedCount;
   }
   //Type is definitely select-multiple.
   for(var i = 0; i < fe_rcbsm.length; i++)  {
     if(fe_rcbsm.options[i].selected)  {
       iMCSelectedCount++;
     }
   }
   return iMCSelectedCount;
 }
 function getOptBooleanStringVF(bs_potential, s_variableName)  {
   return getOptBooleanString(bs_potential, s_variableName, "validate_form.getFormErrorMsgs");
 }
 function crashVF(s_message)  {
   return crash("validate_form.getFormErrorMsgs:  " + s_message);
 }
 function initializeLocalVars()  {
   resetCrashedFlag();
   asRCBSM_TRACKER_NAME = [];
   aiRCBSM_TRACKER_SEL_COUNT = [];
   aiRCBSM_TRACKER_ARR_IDX = [];
   iELEMENT_COUNT = 0;
   bFIRST_DEBUG_SCREEN_SEEN = false;
 }
 /**
   For backwards compatibility only.  Only use getFormErrorMsgs.  This function will eventually be eliminated.
  **/
 function validateForm(f_orm, s_userErrorPrefix, i_debugPerScreen)  {
   return getFormErrorMsgs(f_orm, s_userErrorPrefix, i_debugPerScreen);
 }

/**

 PRIVATE FUNCTIONS...end
**/

/**************************************************************************************************

 util_string.js...START
 Do not edit this file.  This file is dynamically generated by the validate_form.js
 ant build process
**************************************************************************************************/

/**

 VALIDATE_FORM.JS
 Comprehensive solution for validating HTML forms.
 Copyright (C) 2002, Jeff Epstein, jeff_epstein@yahoo.ru, http://www.jeffyjeffy.ru#download
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 This program 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 General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
**/
 //PHONE NUMBER AND ZIP CODE FORMAT/RANGES
   //For documentation, see
   //    documentation/index.html#string_zip
   //
   //Demo/testing values exist at the bottom of
   //    documentation/vf_string_phone_zip.html
   //
   //To test these formats for validity, see
   //    documentation/unit_test.html#util_string_tests
 //PHONE NUMBER FORMATS/RANGES...start
   //US 3 then 7
     var siPHONE_1_MINIMUM = "1001001000";
     var siPHONE_1_MAXIMUM = "9999999999";
   //US 7 only
     var siPHONE_2_MINIMUM = "1001000";
     var siPHONE_2_MAXIMUM = "9999999";
   var siPHONE_3_MINIMUM = "1000";
   var siPHONE_3_MAXIMUM = "9999";
   var siPHONE_4_MINIMUM = "001000";
   var siPHONE_4_MAXIMUM = "999999";
   var siPHONE_5_MINIMUM = "00000000";
   var siPHONE_5_MAXIMUM = "99999999";
   var siPHONE_6_MINIMUM = "1000000000";
   var siPHONE_6_MAXIMUM = "5555555555";
   var siPHONE_7_MINIMUM = "0";
   var siPHONE_7_MAXIMUM = "1";
   var siPHONE_8_MINIMUM = "1";
   var siPHONE_8_MAXIMUM = "9";
   var siPHONE_9_MINIMUM = "000";
   var siPHONE_9_MAXIMUM = "000";
   var siPHONE_10_MINIMUM = "010101";
   var siPHONE_10_MAXIMUM = "787374";
 //PHONE NUMBER FORMATS/RANGES...end
 //ZIP CODE FORMATS/RANGES...start
   //US 5+4
     var siZIP_1_RQD_MINIMUM = "00000";
     var siZIP_1_RQD_MAXIMUM = "99999";
     var siZIP_1_ALT_MINIMUM = "0001";
     var siZIP_1_ALT_MAXIMUM = "9999";
   //US 5 only
     var siZIP_2_RQD_MINIMUM = "00001";
     var siZIP_2_RQD_MAXIMUM = "99999";
     var siZIP_2_ALT_MINIMUM = "";
     var siZIP_2_ALT_MAXIMUM = "";
   var siZIP_3_RQD_MINIMUM = "1";
   var siZIP_3_RQD_MAXIMUM = "1";
   var siZIP_3_ALT_MINIMUM = "2";
   var siZIP_3_ALT_MAXIMUM = "2";
   var siZIP_4_RQD_MINIMUM = "01";
   var siZIP_4_RQD_MAXIMUM = "99";
   var siZIP_4_ALT_MINIMUM = "0001";
   var siZIP_4_ALT_MAXIMUM = "9999";
   var siZIP_5_RQD_MINIMUM = "00";
   var siZIP_5_RQD_MAXIMUM = "55";
   var siZIP_5_ALT_MINIMUM = "0";
   var siZIP_5_ALT_MAXIMUM = "7";
   var siZIP_6_RQD_MINIMUM = "54321";
   var siZIP_6_RQD_MAXIMUM = "55555";
   var siZIP_6_ALT_MINIMUM = "";
   var siZIP_6_ALT_MAXIMUM = "";
   var siZIP_7_RQD_MINIMUM = "00001";
   var siZIP_7_RQD_MAXIMUM = "00001";
   var siZIP_7_ALT_MINIMUM = "0001";
   var siZIP_7_ALT_MAXIMUM = "0001";
   var siZIP_8_RQD_MINIMUM = "09000";
   var siZIP_8_RQD_MAXIMUM = "91111";
   var siZIP_8_ALT_MINIMUM = "0003873874038834";
   var siZIP_8_ALT_MAXIMUM = "0020837401092837";
   var siZIP_9_RQD_MINIMUM = "0003873874038834";
   var siZIP_9_RQD_MAXIMUM = "0020837401092837";
   var siZIP_9_ALT_MINIMUM = "09000";
   var siZIP_9_ALT_MAXIMUM = "91111";
   var siZIP_10_RQD_MINIMUM = "0";
   var siZIP_10_RQD_MAXIMUM = "7";
   var siZIP_10_ALT_MINIMUM = "00";
   var siZIP_10_ALT_MAXIMUM = "55";
 //ZIP CODE FORMATS/RANGES...end


/**

 Does the provided string start or end with a space?
 EQUAL TO
   isSurroundedByChar(s_tring, " ");
**/

function isSurroundedBySpace(s_tring) {

 return isSurroundedByChar(s_tring, " ");

} /**

 Does the provided string start or end with the provided character?
 PARAMETERS
   s_tring  The string to analyze.
   c_har    The character that is determined to exist at the start or end of s_tring.
 RETURNS
   true   If the first or last character in s_tring is c_har.
   false  If s_tring is null or zero characters in length.
        If both the first and last characters in s_tring are *not* c_har.
**/

function isSurroundedByChar(s_tring, char_toTrim) {

 if(!s_tring)  {
   return false;
 }
 if(!char_toTrim  ||  char_toTrim.length != 1)  {
   return crash("isSurroundedByChar:  char_toTrim parameter must be provided, and be exactly one character in length.");
 }
 if(s_tring.length < 1)  {
   return false;
 }
 if(s_tring.substring(0, 1) == char_toTrim)  {
   return true;
 }
 return (s_tring.substring(s_tring.length - 1, s_tring.length) == char_toTrim);

}

/**

 Is the provided string a legal integer?
 RETURNS
   isNumber(s_potentialInteger, "false")
**/

function isInteger(s_potentialInteger) {

 return isNumber(s_potentialInteger, "false");

}

/**

 Is the provided string a legal decimal?
 RETURNS
   isNumber(s_potenitalDecimal, "true")
**/

function isDecimal(s_potentialDecimal) {

 return isNumber(s_potentialDecimal, "true");

} /**

 Is the provided string a legal number?
 PARAMETERS
   s_potentialNumber
     The string to analyze.  Required.
   bs_decimalAllowed
     Is the potential number allowed to be a decimal?  If "true", then yes.  If "false", no.
 RETURNS
   true
     If s_potentialNumber is a legal integer (regardless the value of bs_decimalAllowed).  A legal integer is a string that...
       ...contains one or more zeros.  Note that 0 equals 0000 equals 0000000000 equals ...
       ...starts with zero or one dashes (indicating negative), followed by one or more digits (0-9), where at least one is greater than zero.
     If bs_decimalAllowed is "true" and s_potentialNumber is a legal decimal.  A legal decimal is a string that...
       ...is an integer.
       ...starts with zero or one dashes (indicating negative) followed by zero or more digits, followed by a decimal point ("."), followed by *one* or more digits.
     (Note that s_potentialNumber is checked to be an integer first.  If it is, then true is returned, regardless the value of bs_decimalAllowed.  If the string is an integer, it is not checked, specifically, to see if it"s a decimal.  Hence, the description of a legal decimal number says "a decimal point" instead of "zero or one decimal points".)
   false
     If otherwise.
 LEGAL EXAMPLES (both integers and decimals)
     -1
     0
     1
     -50
     8750328754
     00008750328754
     08750328754
     -487584758475235
     -0000000487584758475235
     -0487584758475235
 ILLEGAL EXAMPLES (both integers and decimals)
     4875847-58475235
     487584758475235-
     [EMPTY_STRING]
     a
     0-
     -0
     Not a number!!!
     Some 123 numbers 456
     123 456
     -0.0
     -.0
     -0.000000
     -.000000
     1.
     .
 LEGAL EXAMPLES (decimals, but only after it is determined that the value is *not* an integer)
     1.1
     1.000830847018374
     058763408562473.01837486564417308746
     .1
     .0
     .01
     -1.0
**/

function isNumber(s_potentialNumber, bs_decimalAllowed) {

 crashIfMissing("util_string.jsNumber", s_potentialNumber, "s_potentialNumber");
 crashIfBadBooleanString(bs_decimalAllowed, "bs_decimalAllowed", "util_string.jsNumber");
 if(s_potentialNumber.length < 1)  {
   return false;
 }
 if(s_potentialNumber == "-")  {
   //A negative sign only makes no sense.
   return false;
 }
 if(/^-[0]+$/.test(s_potentialNumber))  {
   //Negative zero makes no sense.
   return false;
 }
 if(/^[0]+$/.test(s_potentialNumber))  {
   //Zero is a legal number:
   //0  ==  0000000000000  ==  000
   return true;
 }
 //It is definitely not zero.
 //^         The start of the line.
 //[-]{0,1}  Zero or one dashes.
 //[0-9]+    One or more of any digit.
 //$         The end of the line.
 if(/^[-]{0,1}[0-9]+$/.test(s_potentialNumber))  {
   //No matter what, this is valid.  This is a leagal integer
   //and decimal.
   return true;
 }
 //It"s not an integer...
 if(bs_decimalAllowed == "false")  {
   //...but it must be.
   return false;
 }
 //...and that"s okay.  It might be a decimal
 //Due to precision:
 //10.0000000000001 is legal (12 zeros)
 //10.00000000000001 is not  (13 zeros)
 //^         The start of the line.
 //[-]{0,1}  Zero or one dashes.
 //[0-9]*    Zero or more digits.
 //[.]      A decimal point.
 //[0-9]+    One or more digits.
 //$         The end of the line.
 if(/^[-]{0,1}[0-9]*[.][0-9]+$/.test(s_potentialNumber))  {
   //It is a "raw" decimal.  The only thing that would make
   //this illegal is if it were -0.0 or -.0, or -0.0000 or
   //-.0000 or ...
   return !(/^-0*[.]0+$/.test(s_potentialNumber));
 }
 //It is not a legal decimal number.
 return false;

}

function isEmail(s_potentialEmail) {

 if(!s_potentialEmail  ||  s_potentialEmail.length < 1)  {
   return crash("isValidNumber:  s_potentialEmail must be defined, and at least one character in length.");
 }
 if(s_potentialEmail.indexOf(" ") != -1  ||
    s_potentialEmail.indexOf("/") != -1  ||
    s_potentialEmail.indexOf("\\") != -1  ||
    s_potentialEmail.indexOf(",") != -1)  {
   //A space, slash or comma was found.
   return false;
 }
 if(/[@.][@.]/.test(s_potentialEmail))  {
   //An @ or dot is followed by an @ or dot.
   return false;
 }
 if(/^[@.]/.test(s_potentialEmail))  {
   //The first character is an @ or dot.
   return false;
 }
 if(/[@.]$/.test(s_potentialEmail))  {
   //The last character may not be an @ or dot.
   return false;
 }
 if(!/^[^@]+@[^@]+$/.test(s_potentialEmail))  {
   //Only one @ allowed
   //    (Negative of:
   //     Must have one or more non-@ starting the line,
   //     exactly one @, and then
   //     one or more non-@ ending the line.)
   return false;
 }
 //There is exactly one @.
 if(!/@.*[.]/.test(s_potentialEmail))  {
   //At least one dot must follow the (single) @.
   return false;
 }
 //At least one dot follows the @.  We already determined
 //above that it does not immediately follow it,
 //No negative conditions were met.  This is a legal email address.
 //Cool, eh?  : )
 return true;

}

function removeNonNumbers(s_tring) {

 if(!s_tring  ||  s_tring.length < 1)  {
   return crash("removeNonNumbers:  s_tring must be defined, and at least one character in length.");
 }
 var reNonNumbers = /^\D$/;
 if(/^\D$/.test(s_tring))  {
   //There are no numbers at all.
   return "";
 }
 //There is at least one number.
 var asNumberParts = s_tring.split(/\D/);
 var sNumber = asNumberParts[0];
 for(var i = 1; i < asNumberParts.length; i++)  {
   sNumber += asNumberParts[i];
 }
 return sNumber;

} /**

 Are the provided phone format strings valid?
 See the documentation above, regarding PHONE NUMBER FORMATS/RANGES.  Specifically, under the "phone" section, under "--- RULES ---".
 Call this function manually, if you wish.  It is not called by any other function in this js file...except crashIfBadPhoneFormat.
 PARAMETER
   bs_crashIfBad
     Must equal either "true" or "false".  If "true", then if the formats are invalid, this function crashes with a descriptive message.  See utility.crash().
**/

function isPhoneFormatValid(bs_crashIfBad, si_minFormat, si_maxFormat) {

 return isFormatValid("Phone", bs_crashIfBad, "si_minFormat", "si_maxFormat", si_minFormat, si_maxFormat);

}

function getValidPhone(s_potentialPhone) {

 return getValidPhone1(s_potentialPhone);

} function getValidPhone1(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_1_MINIMUM, siPHONE_1_MAXIMUM, s_potentialPhone);

} function getValidPhone2(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_2_MINIMUM, siPHONE_2_MAXIMUM, s_potentialPhone);

} function getValidPhone3(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_3_MINIMUM, siPHONE_3_MAXIMUM, s_potentialPhone);

} function getValidPhone4(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_4_MINIMUM, siPHONE_4_MAXIMUM, s_potentialPhone);

} function getValidPhone5(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_5_MINIMUM, siPHONE_5_MAXIMUM, s_potentialPhone);

} function getValidPhone6(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_6_MINIMUM, siPHONE_6_MAXIMUM, s_potentialPhone);

} function getValidPhone7(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_7_MINIMUM, siPHONE_7_MAXIMUM, s_potentialPhone);

} function getValidPhone8(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_8_MINIMUM, siPHONE_8_MAXIMUM, s_potentialPhone);

} function getValidPhone9(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_9_MINIMUM, siPHONE_9_MAXIMUM, s_potentialPhone);

} function getValidPhone10(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_10_MINIMUM, siPHONE_10_MAXIMUM, s_potentialPhone);

} /**

 Get the phone number out of the provided string.
 PARAMETERS
   si_minFormat
     The format string representing the minimum allowable bound for a legal phone number.  It is *assumed* that this string is provided and valid.  Use isPhoneFormatValid() to validate this, along with si_maxFormat.  For specific information on this variable, see the documentation above, regarding PHONE NUMBER FORMATS/RANGES, under the "phone" section.
   si_maxFormat
     The format string representing the maximum allowable bound for a legal phone number.  It is *assumed* that this string is provided and valid.  Use isPhoneFormatValid() to validate this, along with si_maxFormat.  For specific information on this variable, see the documentation above, regarding PHONE NUMBER FORMATS/RANGES, under the "phone" section.
   s_potentialPhone
     The string containing the (potentially legal) phone number, including any surrounding text.  For example:
       (215) 555-1212
       215 555 1212
       2155551212
 RETURNS
   If the phone number is invalid, according to the format, empty string ("") is returned.  Otherwise, the non-digits are stripped from s_potentialPhone, and the digits alone are returned (but as a string, preserving leading zeros).  For example, all of the above examples (under s_potentialPhone) return "2155551212".
**/

function getValidPhoneFromFormat(si_minFormat, si_maxFormat, s_potentialPhone) {

 if(!s_potentialPhone  ||  s_potentialPhone.length < 1)  {
   return crash("isValidNumber:  s_potentialPhone must be defined, and at least one character in length.");
 }
 //This also removes dashes (negative symbols) and decimal points.
 var siPhoneNumber = removeNonNumbers(s_potentialPhone);
 if(!siPhoneNumber  ||  siPhoneNumber.length < 1  ||
      siPhoneNumber.length != si_minFormat.length)  {
   //The length is illegal.
   return "";
 }
 //Must supply radix=10
 var iMin = parseInt(si_minFormat, 10);
 var iMax = parseInt(si_maxFormat, 10);
 if(isValidNumber(siPhoneNumber, iMin, iMax))  {
   //The phone number is in bounds.
   return siPhoneNumber;
 }
 //It is not a valid phone number.
 return "";

}

/**

 Are the provided zip format strings valid?
 See the documentation above, regarding PHONE NUMBER FORMATS/RANGES.  Specifically, under the "zip code" section, under "--- RULES ---".
 Call this function manually, if you wish.  It is not called by any other function in this js file.
 PARAMETER
   bs_crashIfBad
     Must equal either "true" or "false".  If "true", then if the formats are invalid, this function crashes with a descriptive message.  See utility.crash().
**/

function isZipFormatValid(bs_crashIfBad, si_rqdMinFormat, si_rqdMaxFormat, si_altMinFormat, si_altMaxFormat) {

 if(!isFormatValid("Zip", bs_crashIfBad, "si_rqdMinFormat", "si_rqdMaxFormat", si_rqdMinFormat, si_rqdMaxFormat))  {
   return false;
 }
 //The required format is valid.
 if(!si_altMinFormat ^ !si_altMaxFormat)  {
   if(bs_crashIfBad == "true")  {
     return crash("util_string.jsZipFormatValid:  si_altMinFormat ("" + si_altMinFormat + "") and si_altMaxFormat ("" + si_altMaxFormat + "") must both be either undefined or defined.");
   }
   return false;
 }
 //Both are either undefined, or defined.
 if(!si_altMinFormat)  {
   //One is undefined, therefore both are undefined.
   return true;
 }
 //Both are defined.
 return isFormatValid("Zip", bs_crashIfBad, "si_altMinFormat", "si_altMaxFormat", si_altMinFormat, si_altMaxFormat)

}

function getValidZip(s_potentialZip) {

 return getValidZip1(s_potentialZip);

} function getValidZip1(s_potentialZip) {

 return getValidZipFromFormat(siZIP_1_RQD_MINIMUM, siZIP_1_RQD_MAXIMUM, siZIP_1_ALT_MINIMUM, siZIP_1_ALT_MAXIMUM, s_potentialZip);

} function getValidZip2(s_potentialZip) {

 return getValidZipFromFormat(siZIP_2_RQD_MINIMUM, siZIP_2_RQD_MAXIMUM, siZIP_2_ALT_MINIMUM, siZIP_2_ALT_MAXIMUM, s_potentialZip);

} function getValidZip3(s_potentialZip) {

 return getValidZipFromFormat(siZIP_3_RQD_MINIMUM, siZIP_3_RQD_MAXIMUM, siZIP_3_ALT_MINIMUM, siZIP_3_ALT_MAXIMUM, s_potentialZip);

} function getValidZip4(s_potentialZip) {

 return getValidZipFromFormat(siZIP_4_RQD_MINIMUM, siZIP_4_RQD_MAXIMUM, siZIP_4_ALT_MINIMUM, siZIP_4_ALT_MAXIMUM, s_potentialZip);

} function getValidZip5(s_potentialZip) {

 return getValidZipFromFormat(siZIP_5_RQD_MINIMUM, siZIP_5_RQD_MAXIMUM, siZIP_5_ALT_MINIMUM, siZIP_5_ALT_MAXIMUM, s_potentialZip);

} function getValidZip6(s_potentialZip) {

 return getValidZipFromFormat(siZIP_6_RQD_MINIMUM, siZIP_6_RQD_MAXIMUM, siZIP_6_ALT_MINIMUM, siZIP_6_ALT_MAXIMUM, s_potentialZip);

} function getValidZip7(s_potentialZip) {

 return getValidZipFromFormat(siZIP_7_RQD_MINIMUM, siZIP_7_RQD_MAXIMUM, siZIP_7_ALT_MINIMUM, siZIP_7_ALT_MAXIMUM, s_potentialZip);

} function getValidZip8(s_potentialZip) {

 return getValidZipFromFormat(siZIP_8_RQD_MINIMUM, siZIP_8_RQD_MAXIMUM, siZIP_8_ALT_MINIMUM, siZIP_8_ALT_MAXIMUM, s_potentialZip);

} function getValidZip9(s_potentialZip) {

 return getValidZipFromFormat(siZIP_9_RQD_MINIMUM, siZIP_9_RQD_MAXIMUM, siZIP_9_ALT_MINIMUM, siZIP_9_ALT_MAXIMUM, s_potentialZip);

} function getValidZip10(s_potentialZip) {

 return getValidZipFromFormat(siZIP_10_RQD_MINIMUM, siZIP_10_RQD_MAXIMUM, siZIP_10_ALT_MINIMUM, siZIP_10_ALT_MAXIMUM, s_potentialZip);

} /**

 Get the zip code out of the provided string.
 PARAMETERS
   si_rqdMinFormat
     The format string representing the minimum allowable bound for the required portion of a legal zip code.  It is *assumed* that this string is provided and valid.  Use isZipFormatValid() to validate this, along with si_maxFormat.  For specific information on this variable, see the documentation above, regarding PHONE NUMBER FORMATS/RANGES, under the "zip code" section.
   si_rqdMaxFormat
     The format string representing the maximum allowable bound for the required portion of a legal zip code.  It is *assumed* that this string is provided and valid.  Use isZipFormatValid() to validate this, along with si_maxFormat.  For specific information on this variable, see the documentation above, regarding PHONE NUMBER FORMATS/RANGES, under the "zip code" section.
   si_altMinFormat
     The format string representing the minimum allowable bound for the alternate portion of a legal zip code.  It is *assumed* that this string is provided and valid.  Use isZipFormatValid() to validate this, along with si_maxFormat.  For specific information on this variable, see the documentation above, regarding PHONE NUMBER FORMATS/RANGES, under the "zip code" section.
   si_altMaxFormat
     The format string representing the maximum allowable bound for the alternate portion of a legal zip code.  It is *assumed* that this string is provided and valid.  Use isZipFormatValid() to validate this, along with si_maxFormat.  For specific information on this variable, see the documentation above, regarding PHONE NUMBER FORMATS/RANGES, under the "zip code" section.
   s_potentialZip
     The string containing the (potentially legal) zip code, including any surrounding text.  For example:
       08052-3848
       19130 (0408)
       00483
 RETURNS
   If the zip code is invalid, according to the format, empty string ("") is returned.  Otherwise, the non-digits are stripped from s_potentialZip, and the digits alone are returned (but as a string, preserving leading zeros).  For example, the second example above (under s_potentialZip) returns "191300408".
**/

function getValidZipFromFormat(si_rqdMinFormat, si_rqdMaxFormat, si_altMinFormat, si_altMaxFormat, s_potentialZip) {

 if(!s_potentialZip  ||  s_potentialZip.length < 1)  {
   return crash("isValidNumber:  s_potentialZip must be defined, and at least one character in length.");
 }
 var siZip = removeNonNumbers(s_potentialZip);
 var bLegalLength = false;
 if(siZip)  {
   //There is at least one digit in the zip code...it does
   //exist and...
   if(siZip.length == si_rqdMinFormat.length)  {
     //...it is the required length.
     bLegalLength = true;
   }  else if(si_altMinFormat  &&  si_altMinFormat.length > 0  &&
                  siZip.length == (si_rqdMinFormat.length + si_altMinFormat.length))  {
     //...although it is not the required length, there is
     //an alternate length format, and the zip code has
     //the same length as it PLUS the required part.
     bLegalLength = true;
   }  //ELSE:  There is no alternate format.
 }
 if(!bLegalLength)  {
   return "";
 }
 //The length is legal, according to the format.
 var sRqdPart = siZip.substring(0, si_rqdMinFormat.length);
 //Must specify 10 as the radix (base).  If you don"t, and the
 //format has leading zeros, it may get confused and assume
 //that it has a different radix.
 var iMin = parseInt(si_rqdMinFormat, 10);
 var iMax = parseInt(si_rqdMaxFormat, 10);
 if(!isValidNumber(sRqdPart, iMin, iMax))  {
   //The zip is out of bounds.
   return "";
 }
 //The required part is legal.
 if(siZip.length > sRqdPart.length)  {
   //The length of the overall zip (siZip) is longer than the
   //length of the required part.  In other words, the
   //potential zip definitely has an alternate part.
   var sAltPart = siZip.substring(si_rqdMinFormat.length, siZip.length);
   //Must specify 10 as the radix (base).
   iMin = parseInt(si_altMinFormat, 10);
   iMax = parseInt(si_altMaxFormat, 10);
   if(!isValidNumber(sAltPart, iMin, iMax))  {
     //The zip is out of bounds.
     return "";
   }
 }
 //Every part is in range.
 return siZip;

}

/**

 Is the provided string (who"s value is a non-negative integer) legal?
 PARAMETERS
   s_potentialInt
     The string to analyze.  Required, and it is *assumed* that this only contains digits (0-9.  Decimal points ["."] and negative symbols ["-"] are not legal).  If it contains anything else, this function will behave unpredictably.
   bs_trailingZeroOk
     Required.  Must equal "true" or "false".  If "true", then s_potentialInt is considered legal if it starts with one or more zeros (regardless if it actually equals zero).  If "false", then when s_potentialInt starts with a zero, this function returns false.  This parameter is primary, over bs_zeroOk (see "NOTE").
   bs_zeroOk
     Required.  Must equal "true" or "false".  If "true", then s_potentialInt is considered legal if it is equal to zero ("0", "00", "00000", "0000000000", ...).  If "false", then when s_potentialInt equals zero, this function returns false.  No matter what, a non-zero value is okay, even if there are trailing zeros (however, this does not override bs_trailingZeroOk).  This parameter is secondary to bs_trailingZerosOk (see "NOTE").
   NOTE.
     Note which combinations of bs_trailingZeroOk and bs_zeroOk are legal:
     bs_trailingZeroOk     bs_zeroOk       LEGAL?
       true                 true            yes
       true                 false           yes
       false                true            NO
       false                false           yes
 RETURNS
   true
     If s_potentialInt conforms to the rules defined by bs_zeroOk and bs_trailingZeroOk parameters.
   false
     If otherwise.
**/

function isValidPosIntStr(s_potentialInt, bs_trailingZeroOk, bs_zeroOk) {

 crashIfMissing("util_string.jsValidPosIntStr", s_potentialInt, "s_potentialInt");
 crashIfBadBooleanString(bs_trailingZeroOk, "bs_trailingZeroOk", "util_string.jsValidPosIntStr");
 crashIfBadBooleanString(bs_zeroOk, "bs_zeroOk", "util_string.jsValidPosIntStr");
 if(bs_zeroOk == "true"  &&  bs_trailingZeroOk == "false")  {
   return crash("util_string.jsValidPosIntStr:  bs_trailingZero equals "false", but bs_zeroOk equals "true".");
 }
 if(bs_zeroOk == "true")  {
   //No matter what, s_potentialInt is valid.
   return true;
 }
 //Zero, as a whole, is not okay, however, trailing zeros may
 //be okay.
 var iTrailingZeros = 0;
 for(var i = 0; i < s_potentialInt.length; i++)  {
   var cDigit = s_potentialInt.substring(i, i + 1);
   if(cDigit == "0")  {
     iTrailingZeros++;
   }  else  {
     //We"ve reached the first non-zero.
     break;
   }
 }
 if(iTrailingZeros == 0)  {
   //There are no trailing zeros.  No further analysis
   //needed.
   return true;
 }
 //There is at least one trailing zero.
 if(iTrailingZeros == s_potentialInt.length)  {
   //EVERY digit is equal to zero.
   //s_potentialInt equals zero.
   //s_potentialInt contains only zeros.
   //If bs_zeroOk equals "true":  return true.
   //If bs_zeroOk equals "false":  return false.
   return (bs_zeroOk == "true");
 }
 //There is at least one non-zero digit, following the
 //initial trailing zero(s).
 //If bs_trailingZeroOk equals "true":  return true.
 //If bs_trailingZeroOk equals "false":  return false.
 return (bs_trailingZeroOk == "true");

}

function trimSpaces(s_tring) {

 return trimChar(" ", s_tring);

}

function trimChar(c_harToTrim, s_tring) {

 if(!c_harToTrim  ||  c_harToTrim.length != 1)  {
   return crash("util_sting.trimChar:  c_harToTrim must be provided, and must be exactly one character in length.  Currently "" + c_harToTrim + "".");
 }
 crashIfMissing("util_string.trimSpaces", s_tring, "s_tring");
 var i = 0;
 var iStartingSpaces = 0;
 while(s_tring.substring(i, (i + 1)) == c_harToTrim)  {
   iStartingSpaces++
   i++;
 }
 if(iStartingSpaces == s_tring.length)  {
   return "";
 }
 i = 0;
 var iEndingSpaces = 0;
 while(s_tring.substring((s_tring.length - i), (s_tring.length - (i + 1))) == c_harToTrim)  {
   iEndingSpaces++
   i++;
 }
 if(iStartingSpaces == 0  &&  iEndingSpaces == 0)  {
   return s_tring;
 }
 return s_tring.substring(iStartingSpaces, (s_tring.length - iEndingSpaces));

}

function isFormatValid(s_type, bs_crashIfBad, s_minDesc, s_maxDesc, si_minimum, si_maximum) {

 crashIfBadBooleanString(bs_crashIfBad, "bs_crashIfBad", "util_string.js" + s_type + "FormatValid");
 crashIfMissing("util_string.js" + s_type + "FormatValid", si_minimum, s_minDesc);
 crashIfMissing("util_string.js" + s_type + "FormatValid", si_maximum, s_maxDesc);
 if(si_minimum.length != si_maximum.length)  {
   if(bs_crashIfBad == "true")  {
     return crash("util_string.js." + s_type + "FormatValid:  " + s_minDesc + " ("" + si_minimum + "") must be the same length as " + s_maxDesc + " ("" + si_maximum + "").");
   }
   return false;
 }
 if(!isInteger(si_minimum)  ||  si_minimum < 0)  {
   if(bs_crashIfBad == "true")  {
     return crash("util_string.js." + s_type + "FormatValid:  " + s_minDesc + " (currently "" + si_minimum + "") must be an integer greater than or equal to zero.");
   }
   return false;
 }
 if(!isInteger(si_maximum)  ||  si_maximum < 0)  {
   if(bs_crashIfBad == "true")  {
     return crash("util_string.js." + s_type + "FormatValid:  " + s_maxDesc + " (currently "" + si_maximum + "") must be an integer greater than or equal to zero.");
   }
   return false;
 }
 //Must supply radix=10
 var iMin = parseInt(si_minimum, 10);
 var iMax = parseInt(si_maximum, 10);
 if(iMin > iMax)  {
   if(bs_crashIfBad == "true")  {
     return crash("util_string.js." + s_type + "FormatValid:  " + s_minDesc + " (" + si_minimum + ") is numerically greater than " + s_maxDesc + " (" + si_maximum + ").");
   }
   return false;
 }
 return true;

}

function getPadded(s_tring, i_padLength) {

 crashIfMissing("util_string.js.getPadded", s_tring, "s_tring");
 crashIfMissing("util_string.js.getPadded", i_padLength, "i_padLength");
 if(!isInteger(i_padLength))  {
   return crash("util_string.js.getPadded:  i_padLength ("" + i_padLength + "") must be an *integer* greater than or equal to zero.");
 }  else if(!isValidNumberOpt(i_padLength, 0, "true", -1, "false"))  {
   return crash("util_string.js.getPadded:  i_padLength ("" + i_padLength + "") must be an *integer* greater than or equal to zero.");
 }
 if(s_tring.length >= i_padLength)  {
   return s_tring;
 }
 for(var i = s_tring.length; i < (i_padLength + 1); i++)  {
   s_tring = s_tring + " ";
 }
 return s_tring;

} /**************************************************************************************************

 util_number.js...START
 Do not edit this file.  This file is dynamically generated by the validate_form.js
 ant build process
**************************************************************************************************/

/**

 VALIDATE_FORM.JS
 Comprehensive solution for validating HTML forms.
 Copyright (C) 2002, Jeff Epstein, jeff_epstein@yahoo.ru, http://www.jeffyjeffy.ru#download
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 This program 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 General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
**/

function isValidRangeOpt(i_min, bs_enforceMin, i_max, bs_enforceMax) {

 crashIfBadBooleanString(bs_enforceMin, "bs_enforceMin", "util_number.isValidRangeOpt");
 crashIfBadBooleanString(bs_enforceMax, "bs_enforceMax", "util_number.isValidRangeOpt");
 if(bs_enforceMin == "false"  ||  bs_enforceMax == "false")  {
   //At least one of the bounds are not being enforced.
   return true;
 }
 return !(i_min > i_max);

} function isValidRange(i_min, i_max) {

 return isValidRangeOpt(i_min, "true", i_max, "true");

} function isValidNumber(i_number, i_min, i_max) {

 return isValidNumberOpt(i_number, i_min, "true", i_max, "true");

} /**

 It is assumed that the range is valid.  You will get unpredictable results if it is not.
**/

function isValidNumberOpt(i_number, i_min, bs_enforceMin, i_max, bs_enforceMax) {

 crashIfMissing("util_number.isValidNumber", i_number, "i_number");
       //alert("isValidRangeOpt(" + i_number + ", " + i_min + ", " + bs_enforceMin + ", " + i_max + ", " + bs_enforceMax + ")...\n...isValidRangeOpt(" + i_min + ", " + bs_enforceMin + ", " + i_number + ", "true")=" + isValidRangeOpt(i_min, bs_enforceMin, i_number, "true") + "\n...isValidRangeOpt(" + i_number + ", "true", " + i_max + ", " + bs_enforceMax + ")=" + isValidRangeOpt(i_number, "true", i_max, bs_enforceMax));
 return (isValidRangeOpt(i_min, bs_enforceMin, i_number, "true")  &&
         isValidRangeOpt(i_number, "true", i_max, bs_enforceMax));

}

/**************************************************************************************************

 utility.js...START
 Do not edit this file.  This file is dynamically generated by the validate_form.js
 ant build process
**************************************************************************************************/

/**

 VALIDATE_FORM.JS
 Comprehensive solution for validating HTML forms.
 Copyright (C) 2002, Jeff Epstein, jeff_epstein@yahoo.ru, http://www.jeffyjeffy.ru#download
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 This program 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 General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
**/

//GLOBAL VARIABLES...start

 //A secret public global variable.  For testing purposes, you may want to
 //avoid re-displaying the error after the alert box (within H1 tags).
 //
 //This prevents the crash function from re-presenting the
 //error, after the alert box, within H1 tags.  It makes it so you
 //don"t have to press the back button between each error, in order
 //to get back to this page.
 var bCRASH_ONLY_ALERT_BOX = false;
 //This is automatically manipulated by this js file.  It is private
 //and should never be altered.
 var bCrashed = false;

//GLOBAL VARIABLES...end /**

 Present an error message in an alert box, and also print the provided error message to screen, surrounded by H1 tags.  This function is intended for programming errors, not user errors.
 Although execution is not truly interrupted, this should be significant enough to alert the programmer to an error.
 PARAMETERS
   s_callingFuncAndError
     The function name, followed by the error message.
 RETURNS
   false
     Always.
**/

function crash(s_callingFuncAndError) {

 alert("-------ERROR-------\n\nERROR in " + s_callingFuncAndError);
 if(!bCRASH_ONLY_ALERT_BOX)  {
document.writeln("

ERROR in " + s_callingFuncAndError + "

");
 }
 bCrashed = true;
 return false;

} /**

 Was crash() called?
 RETURNS
   true
     If crash() was called.
   false
     If crash() was never called...or when it was, but you since called resetCrashedFlag().
**/

function hasCrashed() {

 return bCrashed;

} /**

 Make it appear as if crash() was never called, regardless of whether or not it actually was.  This is probably only useful for testing purposes.
**/

function resetCrashedFlag() {

 bCrashed = false;

} /**

 Conditionally print the provided message in an alert box.
 PARAMETERS
   b_condition
     If true, present s_message in an alert box.  If false, do nothing.
   s_message
     The message to present in an alert box, should b_condition be true.  If b_condition is false, this parameter is ignored.
 RETURNS
   true
     If b_condition is true.
   false
     If b_condition is false.
**/

function calert(b_condition, s_message) {

 if(b_condition)  {
   alert(s_message);
   return false;
 }
 return true;

}

/**

 Convenience function to print an error message, should a required parameter not be provided.
 PARAMETERS
   s_callingFileFunc
     Passed directly to crash, if !o_param.  If o_param is true, this parameter is ignored.
   s_paramName
     The name of o_param, only for the potential error message.  If o_param is true, this parameter is ignored.
   o_param
     The required parameter.  If "false" (!o_param) the an error message is printed.
 RETURNS
   true
     If o_param is true.
   false
     If o_param is false.
**/

function crashIfMissing(s_callingFileFunc, s_paramName, o_param) {

 if(!o_param)  {
   return crash(s_callingFileFunc + ":  Required parameter " + s_paramName + " not provided.");
 }
 return true;

} /**

 A single unit test.  If the actual result differs from the actual, an error alert box is presented.
 PARAMETERS
   s_nameOfTest
     The name of the calling JavaScript file and function name, currently being tested.  Required.
   i_testNumber
     The number of the test, for potential error messages only.  Required.
   s_expected
     The expected response from this test.
   s_actual
     The actual response from this test.
 RETURNS
   true
     If s_expected equals s_actual.
   false
     If s_expected does not equal s_actual.
**/

function test(s_nameOfTest, i_testNumber, s_expected, s_actual) {

 crashIfMissing(s_nameOfTest, "s_nameOfTest", "utility.test");
 crashIfMissing(i_testNumber, "i_testNumber", "utility.test");
 if(s_expected != s_actual)  {
   alert("---ERROR---\n\n\tTest name:\t" + s_nameOfTest + "\n\tTest number:\t" + i_testNumber + "\n\tExpected:\t"" + s_expected + ""\n\tActual:\t\t"" + s_actual + """);
   return false;
 }
 return true;

} function crashIfBadBooleanString(bs_potential, s_variableName, s_callingFunc) {

 if(!bs_potential)  {
   return crash(s_callingFunc + ":  " + s_variableName + " must be a *string*, provided, and equal to either "true" or "false".  It is currently a *boolean* equal to "false".");
 }
 if(bs_potential != "true"  &&  bs_potential != "false")  {
   var sValue = "string equal to "" + bs_potential;
   if(typeof(bs_potential) == "boolean")  {
     //It is equal to *boolean* true.  It"s not a string.
     //Note that it"s NOT false, because the first line of this
     //function eliminated this possibility.
     sValue = "*boolean* equal to "" + bs_potential;
   }
   return crash(s_callingFunc + ":  " + s_variableName + " must be a string, provided, and equal to either "true" or "false".  It is currently a " + sValue + "".");
 }

} function crashIfBadBooleanStringOpt(bs_potential, s_variableName, s_callingFunc) {

 if(!bs_potential)  {
   return;
 }
 //bs_potential has been provided.
 if(bs_potential != "true"  &&  bs_potential != "false")  {
   var sValue = "string equal to "" + bs_potential + "";
   if(typeof(bs_potential) == "boolean")  {
     //It is equal to *boolean* true.  It"s not a string.
     //Note that it"s NOT false, because the first line of this
     //function eliminated this possibility.
     sValue = "*boolean* equal to "" + bs_potential + "";
   }
   return crash(s_callingFunc + ":  " + s_variableName + " is not required, but when provided it must be a string, and equal to either "true" or "false".  It is currently a " + sValue + "".");
 }

}

function getOptBooleanString(bs_potential, s_variableName, s_callingFunc) {

 if(bs_potential)  {
   crashIfBadBooleanStringOpt(bs_potential, s_variableName, s_callingFunc);
   return bs_potential;
 }  else  {
   return "false";
 }

}


/**

 Is the provided object an array?
 This concept comes from Kas Thomas, at
 http://www.planetpdf.ru/mainpage.asp?webpageid=1144
 PARAMETERS
   o_potentialArray
     The object that is analyzed to see if it is an array.  Required.
 RETURNS
   true
     If o_potentialArray is an array.
   false
     If o_potentialArray is anything but an array.
**/

function isArray(o_potentialArray) {

 crashIfMissing(o_potentialArray, "o_potentialArray", "utility.isArray");
 if(typeof o_potentialArray != "object")  {
   return false;
 }
 //It is definitely an object.
 return (o_potentialArray.constructor.toString().match(/array/i) != null);

} </SCRIPT> <SCRIPT LANGUAGE="JavaScript">

</SCRIPT> </HEAD> <BODY><a name="top"></a>

Realistic Example: Email Login

To login, provide your email address (which is your username) and password.

<FORM onSubmit="return isFormValid(this);">

 
Email address: <INPUT TYPE="text" NAME="email_address">
Password: <INPUT TYPE="password" NAME="password">

<INPUT TYPE="submit">

<INPUT TYPE="reset">

</FORM> </BODY> </HTML>



 </source>
   
  


Log in form validation

   <source lang="html4strict">
 

<HTML> <HEAD>

  <TITLE>validate_form.js  --  Realistic Example:  Normal Login</TITLE>

<SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript"> /**

 VALIDATE_FORM.JS
 Comprehensive solution for validating HTML forms.
 Copyright (C) 2002, Jeff Epstein, jeff_epstein@yahoo.ru, http://www.jeffyjeffy.ru#download
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 This program 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 General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
**/

/**

 See validate_form_documentation.html for information.
 NOTES TO SELF
   //alert("The CODE for getRCBSMTrackerArrIdx=" + getRCBSMTrackerArrIdx);
   I would like to add a function to get the number of elements that have a (any) value.
**/

//GLOBAL VARIABLES...start (do not alter this section)

 var sDBG_INDENT = "     ";
 var asRCBSM_TRACKER_NAME = "";
 var aiRCBSM_TRACKER_SEL_COUNT = "";
 var aiRCBSM_TRACKER_ARR_IDX = "";
 var iELEMENT_COUNT = -1;
 var bFIRST_DEBUG_SCREEN_SEEN = false;
 var sCURRENT_LENGTH_FOR_TA = "~CURRLEN~";
 var bPHONE_ZIP_FORMATS_VALIDATED = false;

//GLOBAL VARIABLES...end /**

 All messages must be at least one character in length.  If they are empty string, its as if they do not exist.
**/

function getFormErrorMsgs(f_orm, s_userErrorPrefix, i_debugPerScreen) {

 //This initialization function must be the very first line.
 initializeLocalVars();
 if(!arePhoneZipFormatsValid())  {
   return;
 }
 crashIfBadConfiguration(f_orm);
 if(hasCrashed())  {
   //For whatever reason utility.crash() was called, indicating
   //an error has occured.  Get out.  Get out while you still
   //can.
   return;
 }
 outputDebugging(f_orm, i_debugPerScreen);
 return getUserErrors(f_orm, s_userErrorPrefix);

} /**

 PRIVATE FUNCTIONS...start
**/
 function arePhoneZipFormatsValid()  {
   if(bPHONE_ZIP_FORMATS_VALIDATED)  {
     //Phone and zip code formats are checked only once.
     //They"ve already been checked once and are all were
     //found to be valid.
     return true;
   }
   //The formats have not yet been checked, or they were, but
   //were found to be invalid.
   var i = -1;
   var siPMin = "";
   var siPMax = "";
   for(i = 1; i < 11; i++)  {
     siPMin = eval("siPHONE_" + i + "_MINIMUM");
     siPMax = eval("siPHONE_" + i + "_MAXIMUM");
     if(!isPhoneFormatValid("false", siPMin, siPMax))  {
       alert("---  validate_form.js ERROR  ---\n\nPhone number format invalid:\n\tsiPHONE_" + i + "_MINIMUM="" + eval("siPHONE_" + i + "_MINIMUM") + ""\n\tsiPHONE_" + i + "_MAXIMUM="" + eval("siPHONE_" + i + "_MAXIMUM") + ""\n\nThe specific error message follows...");
       isPhoneFormatValid("true", siPMin, siPMax);
       return false;
     }
   }
   var siZRMin = "";
   var siZRMax = "";
   var siZAMin = "";
   var siZAMax = "";
   for(i = 1; i < 11; i++)  {
     siZRMin = eval("siZIP_" + i + "_RQD_MINIMUM");
     siZRMax = eval("siZIP_" + i + "_RQD_MAXIMUM");
     siZAMin = eval("siZIP_" + i + "_ALT_MINIMUM");
     siZAMax = eval("siZIP_" + i + "_ALT_MAXIMUM");
     if(!isZipFormatValid("false", siZRMin, siZRMax, siZAMin, siZAMax))  {
       alert("---  validate_form.js ERROR  ---\n\nZip code format invalid:\n\tsiZIP_" + i + "_RQD_MINIMUM="" + eval("siZIP_" + i + "_RQD_MINIMUM") + ""\n\tsiZIP_" + i + "_RQD_MAXIMUM="" + eval("siZIP_" + i + "_RQD_MAXIMUM") + ""\n\tsiZIP_" + i + "_ALT_MINIMUM="" + eval("siZIP_" + i + "_ALT_MINIMUM") + ""\n\tsiZIP_" + i + "_ALT_MAXIMUM="" + eval("siZIP_" + i + "_ALT_MAXIMUM") + ""\n\nThe specific error message follows...");
       isZipFormatValid("true", siZRMin, siZRMax, siZAMin, siZAMax)
       return false;
     }
   }
   bPHONE_ZIP_FORMATS_VALIDATED = true;
   return true;
 }
  function crashIfBadConfiguration(f_orm)  {
   crashIfMissing(f_orm, "f_orm", "validate_form.getFormErrorMsgs");
   crashIfBadBSSA("f_orm.asGlobalBadSubStrs", f_orm.asGlobalBadSubStrs);
   f_orm.bsGlobalTrimSpaces = getOptBooleanStringVF(f_orm.bsGlobalTrimSpaces, "f_orm.bsGlobalTrimSpaces");
   if(hasCrashed())  {
     return;
   }
   for(var i = 0; i < f_orm.length; i++)  {
     if(f_orm[i].type == "text"  ||  f_orm[i].type == "password")  {
       crashIfBadCfg_text(f_orm, f_orm[i]);
     }  else if(f_orm[i].type == "textarea")  {
       crashIfBadCfg_textarea(f_orm, f_orm[i]);
     }  else if(f_orm[i].type == "checkbox"  ||  f_orm[i].type == "select-multiple")  {
       crashIfBadCfg_cbsm(f_orm, i);
     }  else if(f_orm[i].type == "radio"  ||  f_orm[i].type == "select-one")  {
       crashIfBadCfg_rso(f_orm, i);
     }
   }
 }
 function outputDebugging(f_orm, i_debugPerScreen)  {
   if(!i_debugPerScreen  ||  i_debugPerScreen == -1)  {
     //No debugging is requested
     return;
   }
   if(typeof(i_debugPerScreen) != "number"  ||  i_debugPerScreen < 1)  {
     return crashVF("i_debugPerScreen is not required (currently "" + i_debugPerScreen + ""), but when provided, it must be a number (currently "" + typeof(i_debugPerScreen) + "") either equal to -1, or greater than zero.");
   }
   var iDebugItemsTotal = 0;
   var iDebugItemsThisRound = 0;
   var sDebugBuffer = "";
   var sDebugThisItem = "";
   for(var i = 0; i < f_orm.length; i++)  {
     if(f_orm[i].type == "text"  ||  f_orm[i].type == "password")  {
       sDebugThisItem = getDebugging_text(f_orm, f_orm[i]);
     }  else if(f_orm[i].type == "textarea")  {
       sDebugThisItem = getDebugging_textarea(f_orm, f_orm[i]);
     }  else if(f_orm[i].type == "checkbox"  ||  f_orm[i].type == "select-multiple")  {
       sDebugThisItem = getDebugging_cbsm(f_orm, i);
     }  else if(f_orm[i].type == "radio"  ||  f_orm[i].type == "select-one")  {
       sDebugThisItem = getDebugging_rso(f_orm, i);
     }
     if(sDebugThisItem)  {
       iDebugItemsTotal++;
       iDebugItemsThisRound++;
       sDebugBuffer += sDebugThisItem + "\n";
       if(iDebugItemsThisRound >= i_debugPerScreen)  {
         sDebugBuffer = getGlobalDebugging(sDebugBuffer, f_orm);
         alert("---  validate_form.js  DEBUGGING  (" + (iDebugItemsTotal - iDebugItemsThisRound + 1) + " to " + iDebugItemsTotal + " of " + iELEMENT_COUNT + ")  ---\n\n" + sDebugBuffer);
         iDebugItemsThisRound = 0;
         sDebugBuffer = "";
       }
       sDebugThisItem = "";
     }
   }
   if(sDebugBuffer)  {
     sDebugBuffer = getGlobalDebugging(sDebugBuffer, f_orm);
     alert("---  validate_form.js  DEBUGGING  (" + (iDebugItemsTotal - iDebugItemsThisRound + 1) + " to " + iDebugItemsTotal + " of " + iELEMENT_COUNT + ")  ---\n\n" + sDebugBuffer);
   }
 }
 function getGlobalDebugging(s_debugBuffer, f_orm)  {
   if(!bFIRST_DEBUG_SCREEN_SEEN)  {
     bFIRST_DEBUG_SCREEN_SEEN = true;
     var sGlobalDebug = "";
     if(f_orm.asGlobalBadSubStrs)  {
       sGlobalDebug = sDBG_INDENT + "f_orm.asGlobalBadSubStrs=  [ " + f_orm.asGlobalBadSubStrs + " ]\n";
     }
     if(f_orm.bsGlobalTrimSpaces == "true")  {
       sGlobalDebug += sDBG_INDENT + "f_orm.bsGlobalTrimSpaces=  "true"\n";
     }
     if(sGlobalDebug)  {
       return "---  GLOBAL SETTINGS  ---\n" + sGlobalDebug + "\n\n" + s_debugBuffer;
     }
   }
   //Either the first debugging screen has already been displayed, or
   //this is the first screen, but there is no global settings
   return s_debugBuffer;
 }
 function getUserErrors(f_orm, s_prefix)  {
   var sUserErrors = "";
   for(var i = 0; i < f_orm.length; i++)  {
     if(f_orm[i].type == "text"  ||  f_orm[i].type == "password")  {
       sUserErrors += getUserErrors_text(f_orm, i, s_prefix);
     }  else if(f_orm[i].type == "textarea")  {
       sUserErrors += getUserErrors_textarea(f_orm, i, s_prefix);
     }  else if(f_orm[i].type == "checkbox"  ||  f_orm[i].type == "select-multiple")  {
       sUserErrors += getUserErrors_cbsm(f_orm, i, s_prefix);
     }  else if(f_orm[i].type == "radio"  ||  f_orm[i].type == "select-one")  {
       sUserErrors += getUserErrors_rso(f_orm, i, s_prefix);
     }
   }
   return sUserErrors;
 }
 /**
   form_element must be provided, and a form element...START
  **/
   function getDebuggingNameType(form_element)  {
     return "---  " + form_element.name + "  ---          [" + form_element.type + "]\n";
   }
   function getDebuggingMsgRequired(s_msgRequired)  {
     if(s_msgRequired)  {
       return sDBG_INDENT + "sMsgRequired:  "" + s_msgRequired + ""\n";
     }
     return "";
   }
   function getDebuggingValue(s_value)  {
     if(s_value)  {
       return sDBG_INDENT + "VALUE:  "" + s_value + ""\n";
     }
     return "";
   }
 /**
   form_element must be provided, and a form element...END
  **/
 /**
   Do not call this function without first calling crashIfBadCfg_cbsm for the form-and-form-element.
  **/
 function getUserErrors_cbsm(f_orm, i_arrIdx, s_prefix)  {
   var feCbsm = f_orm[i_arrIdx];
   var sMsgRequired = "";
   var sMsgMCRange = "";
   var iMCMin = "";
   var iMCMax = "";
   if(feCbsm.type == "checkbox")  {
     if(getFirstArrIdx(feCbsm.name) != i_arrIdx)  {
       //This checkbox has already had its user errors retrieved.
       return "";
     }
     //This checkbox has not yet had its user errors retrieved.
     sMsgRequired = f_orm[feCbsm.name + ".sMsgRequired"];
     sMsgMCRange = f_orm[feCbsm.name + ".sMsgMCRange"];
     iMCMin = f_orm[feCbsm.name + ".iMCMin"];
     iMCMax = f_orm[feCbsm.name + ".iMCMax"];
   }  else  {
     //this is a select-multiple type...which has not yet had its
     //user errors retrieved.
     sMsgRequired = feCbsm.sMsgRequired
     sMsgMCRange = feCbsm.sMsgMCRange
     iMCMin = feCbsm.iMCMin
     iMCMax = feCbsm.iMCMax
   }
   var iMCSelCount = getMCSelectedCount(feCbsm.name);
   if(sMsgRequired  &&  iMCSelCount < 1)  {
     return s_prefix + sMsgRequired + "\n";
   }
   //If its required, a value has been selected.
   if(iMCSelCount < 1)  {
     //Its not required, and no value has been selected,
     //which is okay.
     return "";
   }
   if((iMCMin  &&  iMCMin > iMCSelCount)  ||
      (iMCMax  &&  iMCMax < iMCSelCount))  {
     return s_prefix + sMsgMCRange + "\n";
   }
   return "";
 }
 /**
   Do not call this function without first calling crashIfBadCfg_cbsm for the form-and-form-element.
  **/
 function getDebugging_cbsm(f_orm, i_arrIdx)  {
   var feCbsm = f_orm[i_arrIdx];
   var sMsgRequired = "";
   var sMsgMCRange = "";
   var iMCMin = "";
   var iMCMax = "";
   if(feCbsm.type == "checkbox")  {
     if(getFirstArrIdx(feCbsm.name) != i_arrIdx)  {
       //This checkbox has already been debugged.
       return "";
     }
     //This checkbox has not yet been debugged
     sMsgRequired = f_orm[feCbsm.name + ".sMsgRequired"];
     sMsgMCRange = f_orm[feCbsm.name + ".sMsgMCRange"];
     iMCMin = f_orm[feCbsm.name + ".iMCMin"];
     iMCMax = f_orm[feCbsm.name + ".iMCMax"];
   }  else  {
     //this is a select-multiple type...which has not yet been debugged.
     sMsgRequired = feCbsm.sMsgRequired
     sMsgMCRange = feCbsm.sMsgMCRange
     iMCMin = feCbsm.iMCMin
     iMCMax = feCbsm.iMCMax
   }
   var s = getDebuggingNameType(feCbsm) + getDebuggingMsgRequired(sMsgRequired);
   if(sMsgMCRange)  {
     s += sDBG_INDENT + "sMsgMCRange:  "" + sMsgMCRange + ""\n";
     if(iMCMin)  {
       s += sDBG_INDENT + sDBG_INDENT + "iMCMin:  " + iMCMin + "\n";
     }
     if(iMCMax)  {
       s += sDBG_INDENT + sDBG_INDENT + "iMCMax:  " + iMCMax + "\n";
     }
   }
   var iMCSelCount = getMCSelectedCount(feCbsm.name);
   if(iMCSelCount > 0)  {
     s += sDBG_INDENT + "NUMBER OF CHOICES SELECTED:  " + iMCSelCount + "\n";
   }
   return s;
 }
 function crashIfBadCfg_cbsm(f_orm, i_arrIdx)  {
   conditionallyAddRCBSM(f_orm, i_arrIdx);
   var feCbsm = f_orm[i_arrIdx];
   var sMsgMCRange = "";
   var iMCMin = "";
   var iMCMax = "";
   var iTotalOptions = -1;
   var sErrVarPre = "";
   var sErrVarPost = "";
   if(feCbsm.type == "checkbox")  {
     if(getFirstArrIdx(feCbsm.name) != i_arrIdx)  {
       //This checkbox has already been validated.
       return "";
     }
     //This checkbox has not yet been validated
     sMsgMCRange = f_orm[feCbsm.name + ".sMsgMCRange"];
     iMCMin = f_orm[feCbsm.name + ".iMCMin"];
     iMCMax = f_orm[feCbsm.name + ".iMCMax"];
     iTotalOptions = f_orm[feCbsm.name].length;
     sErrVarPre = "f_orm["" + feCbsm.name;
     sErrVarPost = ""]";
   }  else  {
     //this is a select-multiple type...which has not yet been validated.
     sMsgMCRange = feCbsm.sMsgMCRange;
     iMCMin = feCbsm.iMCMin;
     iMCMax = feCbsm.iMCMax;
     iTotalOptions = feCbsm.length;
     sErrVarPre = feCbsm.name;
     sErrVarPost = "";
   }
   if(sMsgMCRange)  {
     if(!iMCMin  &&  !iMCMax)  {
       return crashVF(sErrVarPre + ".sMsgMCRange" + sErrVarPost + " has been provided (currently "" + sMsgMCRange + ""), but neither " + sErrVarPre + ".iMCMin" + sErrVarPost + " nor " + sErrVarPre + ".iMCMax" + sErrVarPost + " have been provided.  At least one of these bounds are required.");
     }
     if(iMCMin)  {
       if(!isInteger(iMCMin))  {
         return crashVF(sErrVarPre + ".iMCMin" + sErrVarPost + " has been provided, but is not of type number.  Currently of type "" + typeof(iMCMin) + "" and equal to "" + iMCMin + "".");
       }
       if(iMCMin < 1  ||  iMCMin > iTotalOptions)  {
         return crashVF(sErrVarPre + ".iMCMin" + sErrVarPost + " has been provided (currently " + iMCMin + "), but is either less than one, or greater than the total number of options (" + iTotalOptions + ").");
       }
     }
     if(iMCMax)  {
       if(!isInteger(iMCMax))  {
         return crashVF(sErrVarPre + ".iMCMax" + sErrVarPost + " has been provided, but is not of type number.  Currently of type "" + typeof(iMCMax) + "" and equal to "" + iMCMax + "".");
       }
       if(iMCMax < 1  ||  iMCMax > iTotalOptions)  {
         return crashVF(sErrVarPre + ".iMCMax" + sErrVarPost + " has been provided (currently " + iMCMax + "), but is either less than one, or greater than the total number of options (" + iTotalOptions + ").");
       }
     }
     if(iMCMin  &&  iMCMax  &&  iMCMin > iMCMax)  {
       return crashVF(sErrVarPre + ".sMsgMCRange" + sErrVarPost + " has been provided (currently "" + sMsgMCRange + ""), and both " + sErrVarPre + ".iMCMin" + sErrVarPost + " (currently " + iMCMin + ") and " + sErrVarPre + ".iMCMax" + sErrVarPost + " (currently " + iMCMax + ") have been provided.  However, iMCMin must be less than or equal to iMCMax, which it is not.");
     }
   }  else if(iMCMin  ||  iMCMax)  {
     return crashVF(sErrVarPre + ".sMsgMCRange" + sErrVarPost + " has *not* been provided, but at least one of " + sErrVarPre + ".iMCMin" + sErrVarPost + " (currently "" + iMCMin + "") or " + sErrVarPre + ".iMCMax" + sErrVarPost + " (currently "" + iMCMax + "") has been provided.");
   }
 }
 /**
   Do not call this function without first calling crashIfBadCfg_rso for the form-and-form-element.
  **/
 function getUserErrors_rso(f_orm, i_arrIdx, s_prefix)  {
   var feRso = f_orm[i_arrIdx];
   var sValue = "";
   var sMsgRequired = "";
   if(feRso.type == "radio")  {
     if(getFirstArrIdx(feRso.name) != i_arrIdx)  {
       //We already debugged this radio element.
       return "";
     }
     sMsgRequired = f_orm[feRso.name + ".sMsgRequired"];
     sValue = getRadioValue(f_orm, feRso.name);
   }  else if(feRso.selectedIndex > -1) {
     sMsgRequired = feRso.sMsgRequired;
     sValue = feRso[feRso.selectedIndex].value;
   }
   if(sMsgRequired  &&  !sValue)  {
     return s_prefix + sMsgRequired + "\n";
   }
   //If its required, a value has been provided.
   return "";
 }
 /**
   Do not call this function without first calling crashIfBadCfg_rso for the form-and-form-element.
  **/
 function getDebugging_rso(f_orm, i_arrIdx)  {
   var feRso = f_orm[i_arrIdx];
   var sValue = "";
   var sMsgRequired = "";
   if(feRso.type == "radio")  {
     if(getFirstArrIdx(feRso.name) != i_arrIdx)  {
       //We already debugged this radio element.
       return "";
     }
     sMsgRequired = f_orm[feRso.name + ".sMsgRequired"];
     sValue = getRadioValue(f_orm, feRso.name);
   }  else if(feRso.selectedIndex > -1) {
     sMsgRequired = feRso.sMsgRequired;
     sValue = feRso[feRso.selectedIndex].value;
   }
   return getDebuggingNameType(feRso) + getDebuggingMsgRequired(sMsgRequired) + getDebuggingValue(sValue);
 }
 function getRadioValue(f_orm, s_radioName)  {
   var feRadio = f_orm[s_radioName];
   for(var i = 0; i < feRadio.length; i++)  {
     if(feRadio[i].checked)  {
       return feRadio[i].value;
     }
   }
   return "";
 }
 function crashIfBadCfg_rso(f_orm, i_arrIdx)  {
   var feRso = f_orm[i_arrIdx];
   if(feRso.type == "radio")  {
     conditionallyAddRCBSM(f_orm, i_arrIdx);
   }  else  {
     iELEMENT_COUNT++;
   }
   //Nothing to validate.  The only attribute that
   //can be associated to a radio or select-one type
   //is sMsgRequired...  Which either is or isn"t...
   //doesn"t matter which.
 }
 function conditionallyAddRCBSM(f_orm, i_arrIdx)  {
   var feCbsm = f_orm[i_arrIdx];
   if(wasRCBSMalreadyFound(feCbsm.name))  {
     //We already analyzed this element.
     return;
   }
   iELEMENT_COUNT++;
   addRCBSMtoTracker(f_orm, feCbsm, i_arrIdx);
 }
 /**
   Do not call this function without first calling crashIfBadCfg_textarea for the form-and-form-element.
  **/
 function getUserErrors_textarea(f_orm, i_arrIdx, s_prefix)  {
   var feTA = f_orm[i_arrIdx];
   if(feTA.sMsgRequired  &&  !feTA.value)  {
     return s_prefix + feTA.sMsgRequired + "\n";
   }
   if(!feTA.value)  {
     return "";
   }
   if(needsToBeTrimmed(f_orm, feTA))  {
     feTA.value = trimSpaces(feTA.value);
   }
   if(feTA.sMsgBadLength  &&
      (feTA.value.length < feTA.iMinLength  ||
       feTA.value.length > feTA.iMaxLength))  {
     return s_prefix + getBadLengthMsg(feTA) + "\n";
   }
   return getBadSubStrMessage(feTA.value, f_orm, feTA.asBadSubStrs, feTA.bsNoBadSubStrings, s_prefix, feTA.sMsgBadSubStr);
 }
 function getBadLengthMsg(fe_tta)  {
   var sMsg = fe_tta.sMsgBadLength;
   var iCLArrIdx = sMsg.indexOf(sCURRENT_LENGTH_FOR_TA);
   if(iCLArrIdx != -1)  {
     sMsg = sMsg.substring(0, iCLArrIdx) + fe_tta.value.length + sMsg.substring((iCLArrIdx + sCURRENT_LENGTH_FOR_TA.length), (sMsg.length + 1));
   }
   return sMsg;
 }
 function getBadSubStrMessage(s_value, f_orm, as_badSubStrs, bs_noBadSubStrings, s_prefix, s_errorMessage)  {
   if(!s_value)  {
     //Theres no value, so it can"t have any illegal sub-string.
     return "";
   }
   if(bs_noBadSubStrings == "true")  {
     //This element is exempt.
     return "";
   }
   //"x" is important...1/2
   var asBadSubStrs = "x";
   if(f_orm.asGlobalBadSubStrs)  {
     asBadSubStrs = f_orm.asGlobalBadSubStrs;
   }
   if(as_badSubStrs)  {
     asBadSubStrs = as_badSubStrs;
   }
   //"x" is important...2/2
   if(asBadSubStrs == "x")  {
     //There are no sub-strings to consider illegal.
     return "";
   }
   //There *are* sub-strings to be considered illegal.
   for(var i = 0; i < asBadSubStrs.length; i++)  {
     if(s_value.indexOf(asBadSubStrs[i]) != -1)  {
       return s_prefix + s_errorMessage + "\n";
     }
   }
   return "";
 }
 /**
   Do not call this function without first calling crashIfBadCfg_textarea for the form-and-form-element.
  **/
 function getDebugging_textarea(f_orm, fe_textarea)  {
   var s = getDebuggingNameType(fe_textarea) + getDebuggingMsgRequired(fe_textarea.sMsgRequired);
   if(fe_textarea.bsNoBadSubStrings == "true")  {
     s += sDBG_INDENT + "bsNoBadSubStrings:  "" + fe_textarea.bsNoBadSubStrings + ""\n";
   }  else if(f_orm.asGlobalBadSubStrs  ||  fe_textarea.asBadSubStrs)  {
     if(fe_textarea.asBadSubStrs)  {
       s += sDBG_INDENT + "asBadSubStrs:  [" + fe_textarea.asBadSubStrs + "]\n";
     }  else if(f_orm.asGlobalBadSubStrs)  {
       s += sDBG_INDENT + "f_orm.asGlobalBadSubStrs:  [" + f_orm.asGlobalBadSubStrs + "]\n";
     }
     s += sDBG_INDENT + sDBG_INDENT + "sMsgBadSubStr:  "" + fe_textarea.sMsgBadSubStr + ""\n";
   }
   if(fe_textarea.sMsgBadLength)  {
     s += sDBG_INDENT + "sMsgBadLength:  "" + fe_textarea.sMsgBadLength + ""\n";
     if(fe_textarea.iMinLength)  {
       s += sDBG_INDENT + sDBG_INDENT + "iMinLength:  " + fe_textarea.iMinLength + "\n";
     }
     if(fe_textarea.iMaxLength)  {
       s += sDBG_INDENT + sDBG_INDENT + "iMaxLength:  " + fe_textarea.iMaxLength + "\n";
     }
   }
   s += getDebuggingValue(fe_textarea.value);
   return s;
 }
 function crashIfBadCfg_textarea(f_orm, fe_textarea)  {
   crashIfMissing(fe_textarea, "fe_textarea", "validate_form.crashIfBadCfg_textarea");
   if(fe_textarea.type != "textarea")  {
     return crashVF("fe_textarea must be of type "text".  Currently "" + fe_textarea.type + ""...SANITY CHECK.  SHOULD NEVER HAPPEN.");
   }
   iELEMENT_COUNT++;
   var sName = sName;
   fe_textarea.bsNoBadSubStrings = getOptBooleanStringVF(fe_textarea.bsNoBadSubStrings, "f_orm." + sName + ".bsNoBadSubStrings");
   crashIfNBSSError(sName, fe_textarea.bsNoBadSubStrings, f_orm.asGlobalBadSubStrs, fe_textarea.asBadSubStrs);
   if(fe_textarea.bsNoBadSubStrings == "false"  &&
     (f_orm.asGlobalBadSubStrs  ||  fe_textarea.asBadSubStrs)  &&
     !fe_textarea.sMsgBadSubStr)  {
     return crashVF("Either f_orm.asGlobalBadSubStrs (currently [" + f_orm.asGlobalBadSubStrs + "]) or f_orm." + sName + ".asBadSubStrs (currently [" + fe_textarea.asBadSubStrs + "]) have  been provided, AND f_orm." + sName + ".bsNoBadSubStrings equals "false" (meaning there are sub-strings that are illegal for this field).  This means that f_orm." + sName + ".sMsgBadSubStr is required.  However, f_orm." + sName + ".sMsgBadSubStr has not been provided.");
   }
   crashIfBadSpaceTrimConfig(f_orm, fe_textarea);
   var iMin = fe_textarea.iMinLength;
   var iMax = fe_textarea.iMaxLength;
   if(fe_textarea.sMsgBadLength)  {
     if(!iMin  &&  !iMax)  {
       return crashVF("f_orm." + sName + ".sMsgBadLength has been provided (currently "" + fe_textarea.sMsgBadLength + ""), but neither f_orm." + sName + ".iMinLength nor f_orm." + sName + ".iMaxLength have been provided.");
     }
     if(iMin  &&  (!isInteger(iMin)  ||  iMin < 1))  {
       return crashVF("Both f_orm." + sName + ".sMsgBadLength (currently "" + fe_textarea.sMsgBadLength + "") and f_orm." + sName + ".iMinLength (currently " + iMin + ") have been provided, but iMinLength must be an integer, and at least equal to one.  Additional information:  f_orm." + sName + ".iMaxLength currently equals " + iMax + ".");
     }
     if(iMax  &&  (!isInteger(iMax)  ||  iMax < 1))  {
       return crashVF("Both f_orm." + sName + ".sMsgBadLength (currently "" + fe_textarea.sMsgBadLength + "") and f_orm." + sName + ".iMaxLength (currently "" + iMax + "") have been provided, but iMaxLength must be an integer, and at least equal to one.  Additional information:  f_orm." + sName + ".iMinLength currently equals " + iMin + ".");
     }
     if(iMin  &&  iMax  &&  iMin > iMax)  {
       return crashVF("f_orm." + sName + ".sMsgBadLength (currently "" + fe_textarea.sMsgBadLength + ""), f_orm." + sName + ".iMinLength (currently " + iMin + ") and f_orm." + sName + ".iMaxLength (currently " + iMax + ") have all been provided, but iMinLength must be less than or equal to iMaxLength.");
     }
   }  else if(iMin  ||  iMax)  {
     return crashVF("f_orm." + sName + ".sMsgBadLength has *not* been provided, but at least one of f_orm." + sName + ".iMinLength (currently " + iMin + ") and f_orm." + sName + ".iMaxLength (currently " + iMax + ") have been provided.");
   }
 }
 /**
   Do not call this function without first calling crashIfBadCfg_textarea for the form-and-form-element.
  **/
 function getUserErrors_text(f_orm, i_arrIdx, s_prefix)  {
   var feText = f_orm[i_arrIdx];
   if(needsToBeTrimmed(f_orm, feText))  {
     feText.value = trimSpaces(feText.value);
   }
   if(feText.sMsgRequired  &&  !feText.value)  {
     return s_prefix + feText.sMsgRequired + "\n";
   }
   if(!feText.value)  {
     return "";
   }
   //It is assumed/expected that there is only one "sMsgTxt"
   //variables associated to feText.  The only reason that
   //the following ifs are not else-ifs, is because of the
   //for loop of eval statements.
   if(feText.sMsgTxtEmail)  {
     if(!isEmail(feText.value))  {
       return s_prefix + feText.sMsgTxtEmail + "\n";
     }
   }  else if(feText.sMsgTxtInt)  {
     if(!isInteger(feText.value)  ||
        (feText.iIntMin  &&  feText.iIntMin > feText.value)  ||
        (feText.iIntMax  &&  feText.iIntMax < feText.value))  {
       return s_prefix + feText.sMsgTxtInt + "\n";
     }
   }  else if(feText.sMsgTxtDec)  {
     if(!isDecimal(feText.value)  ||
        (feText.iDecMin  &&  feText.iDecMin > feText.value)  ||
        (feText.iDecMax  &&  feText.iDecMax < feText.value))  {
       return s_prefix + feText.sMsgTxtDec + "\n";
     }
   }  else if(feText.sMsgTxtPhone)  {
     var sPhoneStripped = getValidPhone1(feText.value);
     if(!sPhoneStripped)  {
       return s_prefix + feText.sMsgTxtPhone + "\n";
     }
     feText.value = sPhoneStripped;
   }  else if(feText.sMsgTxtZip)  {
     var sZipStripped = getValidZip1(feText.value);
     if(!sZipStripped)  {
       return s_prefix + feText.sMsgTxtZip + "\n";
     }
     feText.value = sZipStripped;
   }  else  {
     for(var i = 1; i < 11; i++)  {
       if(eval("feText.sMsgTxtPhone" + i))  {
         var sPhoneStripped = eval("getValidPhone" + i + "(feText.value)");
         if(!sPhoneStripped)  {
           return s_prefix + eval("feText.sMsgTxtPhone" + i) + "\n";
         }
         feText.value = sPhoneStripped;
         break;    //There is only one sMsgTxt* per element
       }
       if(eval("feText.sMsgTxtZip" + i))  {
         var sZipStripped = eval("getValidZip" + i + "(feText.value)");
         if(!sZipStripped)  {
           return s_prefix + eval("feText.sMsgTxtZip" + i) + "\n";
         }
         feText.value = sZipStripped;
         break;    //There is only one sMsgTxt* per element
       }
     }
   }
   if(feText.sMsgBadLength  &&  feText.value.length < feText.iMinLength)  {
     return s_prefix + getBadLengthMsg(feText) + "\n";
   }
   return getBadSubStrMessage(feText.value, f_orm, feText.asBadSubStrs, feText.bsNoBadSubStrings, s_prefix, feText.sMsgBadSubStr);
 }
 function needsToBeTrimmed(f_orm, fe_tta)  {
   if(!fe_tta.value)  {
     return false;
   }
   if(fe_tta.bsDontTrimSpaces == "true")  {
     return false;
   }
   if(f_orm.bsGlobalTrimSpaces == "true"  ||  fe_tta.bsTrimSpaces == "true")  {
     return isSurroundedBySpace(fe_tta.value);
   }
 }
 /**
   Do not call this function without first calling crashIfBadCfg_text for the form-and-form-element.
  **/
 function getDebugging_text(f_orm, fe_text)  {
   var sDBG_INDENT = "     ";
   var s = getDebuggingNameType(fe_text) + getDebuggingMsgRequired(fe_text.sMsgRequired);
   var bEM = fe_text.sMsgTxtEmail;
   var bInt = fe_text.sMsgTxtInt;
   var bDec = fe_text.sMsgTxtDec;
   var bZC = fe_text.sMsgTxtZip;
   var bZC1 = fe_text.sMsgTxtZip1;
   var bZC2 = fe_text.sMsgTxtZip2;
   var bZC3 = fe_text.sMsgTxtZip3;
   var bZC4 = fe_text.sMsgTxtZip4;
   var bZC5 = fe_text.sMsgTxtZip5;
   var bZC6 = fe_text.sMsgTxtZip6;
   var bZC7 = fe_text.sMsgTxtZip7;
   var bZC8 = fe_text.sMsgTxtZip8;
   var bZC9 = fe_text.sMsgTxtZip9;
   var bZC10 = fe_text.sMsgTxtZip10;
   var bPN = fe_text.sMsgTxtPhone;
   var bPN1 = fe_text.sMsgTxtPhone1;
   var bPN2 = fe_text.sMsgTxtPhone2;
   var bPN3 = fe_text.sMsgTxtPhone3;
   var bPN4 = fe_text.sMsgTxtPhone4;
   var bPN5 = fe_text.sMsgTxtPhone5;
   var bPN6 = fe_text.sMsgTxtPhone6;
   var bPN7 = fe_text.sMsgTxtPhone7;
   var bPN8 = fe_text.sMsgTxtPhone8;
   var bPN9 = fe_text.sMsgTxtPhone9;
   var bPN10 = fe_text.sMsgTxtPhone10;
   if(bEM)  {
     s += sDBG_INDENT + "sMsgTxtEmail:  "" + fe_text.sMsgTxtEmail + ""\n";
   }
   if(bZC)  {
     s += sDBG_INDENT + "sMsgTxtZip:  "" + fe_text.sMsgTxtZip + ""\n";
   }
   if(bPN)  {
     s += sDBG_INDENT + "sMsgTxtPhone:  "" + fe_text.sMsgTxtPhone + ""\n";
   }
   for(var i = 1; i < 11; i++)  {
     if(eval("bPN" + i))  {
       s += sDBG_INDENT + "sMsgTxtPhone" + i + ":  "" + eval("fe_text.sMsgTxtPhone" + i) + ""\n";
     }
     if(eval("bZC" + i))  {
       s += sDBG_INDENT + "sMsgTxtZip" + i + ":  "" + eval("fe_text.sMsgTxtZip" + i) + ""\n";
     }
   }
   if(bInt)  {
     s += sDBG_INDENT + "sMsgTxtInt:  "" + fe_text.sMsgTxtInt + ""\n";
     if(fe_text.iIntMin)  {
       s += sDBG_INDENT + sDBG_INDENT + "iIntMin:  "" + fe_text.iIntMin + ""\n";
     }
     if(fe_text.iIntMax)  {
       s += sDBG_INDENT + sDBG_INDENT + "iIntMax:  "" + fe_text.iIntMax + ""\n";
     }
   }
   if(bDec)  {
     s += sDBG_INDENT + "sMsgTxtDec:  "" + fe_text.sMsgTxtDec + ""\n";
     if(fe_text.iDecMin)  {
       s += sDBG_INDENT + sDBG_INDENT + "iDecMin:  "" + fe_text.iDecMin + ""\n";
     }
     if(fe_text.iDecMax)  {
       s += sDBG_INDENT + sDBG_INDENT + "iDecMax:  "" + fe_text.iDecMax + ""\n";
     }
   }
   if(fe_text.bsNoBadSubStrings == "true")  {
     s += sDBG_INDENT + "bsNoBadSubStrings:  "" + fe_text.bsNoBadSubStrings + ""\n";
   }  else if(!bInt  &&  !bDec  &&
                  !bZC   &&  !bZC1  &&  !bZC2  &&  !bZC3  &&  !bZC4  &&  !bZC5  &&
                  !bZC6  &&  !bZC7  &&  !bZC8  &&  !bZC9  &&  !bZC10  &&
                  !bPN   &&  !bPN1  &&  !bPN2  &&  !bPN3  &&  !bPN4  &&  !bPN5  &&
                  !bPN6  &&  !bPN7  &&  !bPN8  &&  !bPN9  &&  !bPN10  &&
              (f_orm.asGlobalBadSubStrs  ||  fe_text.asBadSubStrs))  {
     var sSecondIndent = "";
     if(fe_text.asBadSubStrs)  {
       s += sDBG_INDENT + "asBadSubStrs:  [" + fe_text.asBadSubStrs + "]\n";
       sSecondIndent = sDBG_INDENT;
     }
   }
   if(fe_text.sMsgBadLength)  {
     s += sDBG_INDENT + "sMsgBadLength:  "" + fe_text.sMsgBadLength + ""\n" + sDBG_INDENT + sDBG_INDENT + "iMinLength:  " + fe_text.iMinLength + "\n";
     if(fe_text.maxLength)  {
       s += sDBG_INDENT + sDBG_INDENT + "MAXLENGTH:  " + fe_text.MAXLENGTH + "\n";
     }
   }
   s += getDebuggingValue(fe_text.value);
   return s;
 }
 function crashIfBadCfg_text(f_orm, fe_text)  {
   crashIfMissing(fe_text, "fe_text", "validate_form.crashIfBadCfg_text");
   if(fe_text.type != "text"  &&  fe_text.type != "password")  {
     return crashVF("fe_text must be of type "text" or "password".  Currently "" + fe_text.type + ""...SANITY CHECK.  SHOULD NEVER HAPPEN.");
   }
   var sName = fe_text.name;
   iELEMENT_COUNT++;
   var bEM = fe_text.sMsgTxtEmail;
   var bInt = fe_text.sMsgTxtInt;
   var bDec = fe_text.sMsgTxtDec;
   var bZC = fe_text.sMsgTxtZip;
   var bPN = fe_text.sMsgTxtPhone;
   var iSpecialTypes = 0;
   var sSpecialTypes = "";
   if(bEM)  {
     iSpecialTypes++;
     sSpecialTypes += "sMsgTxtEmail...";
   }
   if(bInt)  {
     iSpecialTypes++;
     sSpecialTypes += "sMsgTxtInt...";
     crashIfBadIntDecCfg(fe_text.iIntMin, fe_text.iIntMax, "false", sName, "iIntMin", "iIntMax");
   }  else if(fe_text.iIntMin  ||  fe_text.iIntMax)  {
     return crashVF("f_orm." + sName + ".sMsgTxtInt has *not* been provided, but one or both of the sub-variables " + sName + ".iIntMin (currently "" + fe_text.iIntMin + "")/" + sName + ".iIntMax (currently "" + fe_text.iIntMax + "") have been provided.");
   }
   if(bDec)  {
     iSpecialTypes++;
     sSpecialTypes += "sMsgTxtDec...";
     crashIfBadIntDecCfg(fe_text.iDecMin, fe_text.iDecMax, "true", sName, "iDecMin", "iDecMax");
   }  else if(fe_text.iDecMin  ||  fe_text.iDecMax)  {
     return crashVF("f_orm." + sName + "." + sAnIntADec + " has *not* been provided, but one or both of the sub-variables " + sName + ".iDecMin (currently "" + fe_text.iDecMin + "")/" + sName + ".iDecMax (currently "" + fe_text.iDecMax + "") have been provided.");
   }
   if(bPN)  {
     iSpecialTypes++;
     sSpecialTypes += "sMsgTxtPhone...";
   }
   for(var i = 1; i < 11; i++)  {
     eval("var bPN" + i + " = fe_text.sMsgTxtPhone" + i);
     if(eval("bPN" + i))  {
       iSpecialTypes++;
       sSpecialTypes += "sMsgTxtPhone" + i + "...";
     }
   }
   if(bZC)  {
     iSpecialTypes++;
     sSpecialTypes += "sMsgTxtZip...";
   }
   for(var i = 1; i < 11; i++)  {
     eval("var bZC" + i + " = fe_text.sMsgTxtZip" + i);
     if(eval("bZC" + i))  {
       iSpecialTypes++;
       sSpecialTypes += "sMsgTxtZip" + i + "...";
     }
   }
   if(iSpecialTypes > 1)  {
     return crashVF("f_orm." + sName + " is of type "text", but has " + iSpecialTypes + " special text types associated to it.  Zero or one of the following special types may be used for a text form element:  sMsgTxtEmail, sMsgTxtInt, sMsgTxtDec, sMsgTxtZip, sMsgTxtZip1, sMsgTxtZip2, sMsgTxtZip3, sMsgTxtZip4, sMsgTxtZip5, sMsgTxtZip6, sMsgTxtZip7, sMsgTxtZip8, sMsgTxtZip9, sMsgTxtZip10, sMsgTxtPhone, sMsgTxtPhone1, sMsgTxtPhone2, sMsgTxtPhone3, sMsgTxtPhone4, sMsgTxtPhone5, sMsgTxtPhone6, sMsgTxtPhone7, sMsgTxtPhone8, sMsgTxtPhone9, sMsgTxtPhone10.\n\nActually existing special types found:  " + sSpecialTypes);
   }
   crashIfBadBSSA("f_orm." + sName + ".asBadSubStrs", fe_text.asBadSubStrs);
   fe_text.bsNoBadSubStrings = getOptBooleanStringVF(fe_text.bsNoBadSubStrings, "f_orm." + sName + ".bsNoBadSubStrings");
   crashIfNBSSError(sName, fe_text.bsNoBadSubStrings, f_orm.asGlobalBadSubStrs, fe_text.asBadSubStrs);
   if(fe_text.bsNoBadSubStrings == "false"  &&  !bInt  &&  !bDec  &&
        !bZC   &&  !bZC1  &&  !bZC2  &&  !bZC3  &&  !bZC4  &&  !bZC5  &&
        !bZC6  &&  !bZC7  &&  !bZC8  &&  !bZC9  &&  !bZC10  &&
        !bPN   &&  !bPN1  &&  !bPN2  &&  !bPN3  &&  !bPN4  &&  !bPN5  &&
        !bPN6  &&  !bPN7  &&  !bPN8  &&  !bPN9  &&  !bPN10  &&
     (f_orm.asGlobalBadSubStrs  ||  fe_text.asBadSubStrs)  &&
     !fe_text.sMsgBadSubStr)  {
     return crashVF("Either f_orm.asGlobalBadSubStrs (currently [" + f_orm.asGlobalBadSubStrs + "]) or f_orm." + sName + ".asBadSubStrs (currently [" + fe_text.asBadSubStrs + "]) have  been provided, AND f_orm." + sName + ".bsNoBadSubStrings equals "false" (meaning there are sub-strings that are illegal for this field) AND this text/password field does not have a "number" special type (sMsgTxtInt, sMsgTxtDec, sMsgTxtZip, sMsgTxtZip1, sMsgTxtZip2, sMsgTxtZip3, sMsgTxtZip4, sMsgTxtZip5, sMsgTxtZip6, sMsgTxtZip7, sMsgTxtZip8, sMsgTxtZip9, sMsgTxtZip10, sMsgTxtPhone, sMsgTxtPhone1, sMsgTxtPhone2, sMsgTxtPhone3, sMsgTxtPhone4, sMsgTxtPhone5, sMsgTxtPhone6, sMsgTxtPhone7, sMsgTxtPhone8, sMsgTxtPhone9, sMsgTxtPhone10).  This means that f_orm." + sName + ".sMsgBadSubStr is required.  However, f_orm." + sName + ".sMsgBadSubStr has not been provided.");
   }
   crashIfBadSpaceTrimConfig(f_orm, fe_text);
   var bIsSpecial = (bEM  ||  bInt  || bDec  ||
     bZC   ||  bZC1  ||  bZC2  ||  bZC3  ||  bZC4  ||  bZC5  ||
      bZC6  ||  bZC7  ||  bZC8  ||  bZC9  ||  bZC10  ||
      bPN   ||  bPN1  ||  bPN2  ||  bPN3  ||  bPN4  ||  bPN5  ||
      bPN6  ||  bPN7  ||  bPN8  ||  bPN9  ||  bPN10);
   if(bIsSpecial  &&
     (fe_text.bsTrimSpaces == "true"  ||  fe_text.bsDontTrimSpaces == "true"))  {
     return crashVF("Either f_orm." + sName + ".bsTrimSpaces (currently "" + fe_text.bsTrimSpaces + "") or f_orm." + sName + ".bsDontTrimSpaces (currently "" + fe_text.bsTrimSpaces + "") equal "true".  But this is illegal, because the element has these special types associated to it:  " + sSpecialTypes);
   }
   var iMin = fe_text.iMinLength;
   if(fe_text.sMsgBadLength)  {
     if(!iMin)  {
       return crashVF("f_orm." + sName + ".sMsgBadLength has been provided (currently "" + fe_text.sMsgBadLength + ""), but f_orm." + sName + ".iMinLength has not been provided");
     }
     if(iMin  &&  (!isInteger(iMin)  ||  iMin < 1))  {
       return crashVF("Both f_orm." + sName + ".sMsgBadLength (currently "" + fe_text.sMsgBadLength + "") and f_orm." + sName + ".iMinLength (currently "" + iMin + "") have been provided, but iMinLength must be an integer, and at least equal to one.");
     }
     //NOTE:  When MAXLENGTH is an attribute of the element,
     //fe_text.MAXLENGTH is undefined, but fe_text.maxLength
     //is not.  Things that make you go hmm.
     if(fe_text.maxLength  &&  fe_text.maxLength != -1  &&
        isInteger(fe_text.maxLength)  &&  iMin > fe_text.maxLength)  {
       return crashVF("Both f_orm." + sName + ".sMsgBadLength (currently "" + fe_text.sMsgBadLength + "") and f_orm." + sName + ".iMinLength (currently " + iMin + ") have been provided, but iMinLength must be an integer between one and f_orm." + sName + ".MAXLENGTH (currently " + fe_text.maxLength + "), inclusive.");
     }
   }  else if(iMin)  {
     return crashVF("f_orm." + sName + ".sMsgBadLength has *not* been provided, but the sub-attribute f_orm." + sName + ".iMinLength (currently " + iMin + ") has been provided.");
   }
   if(fe_text.iMaxLength)  {
     return crashVF("f_orm." + sName + ".iMaxLength (currently " + fe_text.iMaxLength + ") is only a legal sub-attribute for text elements.  To enforce maximum length in a text or password element, use the standard MAXLENGTH attribute.");
   }
 }
 //"di_" prefix stands for decimal-or-integer
 function crashIfBadIntDecCfg(di_min, di_max, bs_decimalAllowed, s_formLmntName, s_nameMin, s_nameMax)  {
   var sIntDecPostfix = "Int";
   var sAnIntADec = "an integer";
   var sIntDec = "integer";
   var sIsFuncName = "isInteger";
   if(bs_decimalAllowed == "true")  {
     sIntDecPostfix = "Dec";
     sAnIntADec = "a decimal";
     sIntDec = "decimal";
     sIsFuncName = "isDecimal";
   }
   if(di_min  &&  !isNumber(di_min, bs_decimalAllowed))  {
     return crashVF("f_orm." + s_formLmntName + ".sMsgTxt" + sIntDecPostfix + " has been provided, and the sub-variable " + s_formLmntName + "." + s_nameMin + " has also been provided.  However, " + s_nameMin + " must be " + sAnIntADec + ".  Currently "" + di_min + "".");
   }
   if(di_max  &&  !isNumber(di_max, bs_decimalAllowed))  {
     return crashVF("f_orm." + s_formLmntName + ".sMsgTxt" + sIntDecPostfix + " has been provided, and the sub-variable " + s_formLmntName + "." + s_nameMax + " has also been provided.  However, " + s_nameMax + " must be " + sAnIntADec + ".  Currently "" + di_max + "".");
   }
   if(di_min  &&  di_max  &&
     !isValidRange(di_min, di_max))  {
     return crashVF("f_orm." + s_formLmntName + ".sMsgTxt" + sIntDecPostfix + " has been provided, and both the sub-variables " + s_formLmntName + "." + s_nameMin + " and " + s_formLmntName + "." + s_nameMax + " have also been provided.  Both these variables are definitely legal " + sIntDec + "s (according to util_string." + sIsFuncName + "()), however, " + s_nameMin + " (currently "" + di_min + "") and " + s_nameMax + " (currently "" + di_max + "") are not a legal range according to util_number.isValidRange().");
   }
 }
 function crashIfBadSpaceTrimConfig(f_orm, fe_tta)  {
   fe_tta.bsTrimSpaces = getOptBooleanStringVF(fe_tta.bsTrimSpaces, "f_orm." + fe_tta.name + ".bsTrimSpaces");
   fe_tta.bsDontTrimSpaces = getOptBooleanStringVF(fe_tta.bsDontTrimSpaces, "f_orm." + fe_tta.name + ".bsDontTrimSpaces");
   if(f_orm.bsGlobalTrimSpaces == "true")  {
     if(fe_tta.bsTrimSpaces == "true")  {
       return crashVF("Both f_orm.bsGlobalTrimSpaces and f_orm." + fe_tta.name + ".bsTrimSpaces equal "true".  Only one of these variables may be "true".");
     }
   }  else  if(fe_tta.bsDontTrimSpaces == "true")  {
     return crashVF("f_orm.bsGlobalTrimSpaces has *not* been provided (or is equal to "false"), but f_orm." + fe_tta.name + ".bsDontTrimSpaces equals "true".  ");
   }
 }
 function crashIfNBSSError(s_textPwName, b_noBadSubStrings, as_globalBadSubStrs, as_badSubStrs)  {
   if(b_noBadSubStrings == "true"  &&
      (as_badSubStrs  ||  !as_globalBadSubStrs))  {
     return crashVF("f_orm." + s_textPwName + ".bsNoBadSubStrings equals "true", but either , f_orm.asGlobalBadSubStrs has *not* been provided (currently " + as_globalBadSubStrs + ") or f_orm." + s_textPwName + ".asBadSubStrs *has* been provided (currently " + as_badSubStrs + ").  When bsNoBadSubStrings equals "true", it is required that or asBadSubStrs not be provided and f_orm.asGlobalBadSubStrs should be provided.");
   }
 }
 function getRqdMissingMsg(s_requiredMsg, s_value)  {
   crashIfMissing(s_value, "s_value ("missing" means empty string)", "validate_form.getRqdMissingMsg");
   if(!s_requiredMsg)  {
     //This value is not required.
     return "";
   }
   //This value *is* required...
   if(s_value == "")  {
     //...but has not been provided.
     return s_requiredMsg;
   }
   //...and has been provided.
   return "";
 }
 /**
   Crash If the provided bad-sub-string-array is bad.
  **/
 function crashIfBadBSSA(s_variableName, as_badSubStrs)  {
   if(!as_badSubStrs)  {
     return;
   }
   var sRule = " is not required, but when it is provided, it must be of type array, at least one element in length, and each element must be of type string, at least one character in length, and all elements must be unique.  Currently, ";
   if(!isArray(as_badSubStrs))  {
     return crashVF("crashIfBadBSSA:  " + s_variableName + sRule + "it is of type "" + typeof(as_badSubStrs) + "".");
   }
   if(as_badSubStrs.length < 1)  {
     return crashVF("crashIfBadBSSA:  " + s_variableName + sRule + "it is zero elements in length.");
   }
   for(var i = 0; i < as_badSubStrs.length; i++)  {
     if(typeof(as_badSubStrs[i]) != "string")  {
       return crashVF("crashIfBadBSSA:  " + s_variableName + sRule + " s_variableName[" + i + "] is of type "" + typeof(as_badSubStrs[i]) + "".");
     }
     if(as_badSubStrs[i].length < 1)  {
       return crashVF("crashIfBadBSSA:  " + s_variableName + sRule + " s_variableName[" + i + "] is zero characters in length.");
     }
     for(var j = i + 1; j < as_badSubStrs.length; j++)  {
       if(as_badSubStrs[i] == as_badSubStrs[j])  {
         return crashVF("crashIfBadBSSA:  " + s_variableName + sRule + " Element " + i + " (currently "" + as_badSubStrs[i] + "") is equal to element " + j + ".");
       }
     }
   }
   //All elements are definitely of type string.
   for(var i = 0; i < as_badSubStrs.length; i++)  {
     for(var j = i + 1; j < as_badSubStrs.length; j++)  {
       if(as_badSubStrs[i] == as_badSubStrs[j])  {
         return crashVF("crashIfBadBSSA:  " + s_variableName + sRule + " Element " + i + " (currently "" + as_badSubStrs[i] + "") is equal to element " + j + ".");
       }
     }
   }
 }
 function  wasRCBSMalreadyFound(s_elementName)  {
   return (getRCBSMTrackerArrIdx(s_elementName) != -1);
 }
 function  getFirstArrIdx(s_elementName)  {
   var iArrIdx = getAndValidateRCBSMTArrIdx("getFirstArrIdx", s_elementName);
   var iFirstArrIdx = aiRCBSM_TRACKER_ARR_IDX[iArrIdx];
   if(iFirstArrIdx == -1)  {
     return crashVF("getFirstArrIdx:  Element named "" + s_elementName + "" *was* found in the tracker array objects, but it is of type select-multiple, which does not have multiple instances, and is therefore invalid for this function.  SANITY CHECK.  SHOULD NEVER HAPPEN.");
   }
   return iFirstArrIdx;
 }
 function  getMCSelectedCount(s_elementName)  {
   var iArrIdx = getAndValidateRCBSMTArrIdx("getMCSelectedCount", s_elementName);
   var iSelCt = aiRCBSM_TRACKER_SEL_COUNT[iArrIdx];
   if(iSelCt == -1)  {
     return crashVF("getMCSelectedCount:  Element named "" + s_elementName + "" *was* found in the tracker array objects, but it is of type radio, which is a single-choice element, and is therefore invalid for this function.  SANITY CHECK.  SHOULD NEVER HAPPEN.");
   }
   return iSelCt;
 }
 function getAndValidateRCBSMTArrIdx(s_callingFunction, s_elementName)  {
   var iArrIdx = getRCBSMTrackerArrIdx(s_elementName);
   if(iArrIdx == -1)  {
     return crashVF("getAndValidateRCBSMTArrIdx ("" + s_callingFunction + ""):  Element named "" + s_elementName + "" was not found in the tracker array objects.  SANITY CHECK.  SHOULD NEVER HAPPEN.");
   }
   return iArrIdx;
 }
 function  getRCBSMTrackerArrIdx(s_elementName)  {
   for(var i = 0; i < asRCBSM_TRACKER_NAME.length; i++)  {
     if(asRCBSM_TRACKER_NAME[i] == s_elementName)  {
       return i;
     }
   }
   return -1;
 }
 function addRCBSMtoTracker(f_orm, fe_rcbsm, i_formArrIdx)  {
   if(asRCBSM_TRACKER_NAME.length < 1)  {
     //This is the first to be tracked.  Just create a new
     //array containing this name as the only element.
     asRCBSM_TRACKER_NAME = [fe_rcbsm.name];
     aiRCBSM_TRACKER_SEL_COUNT = [getMCSelectedCountForTracker(f_orm, fe_rcbsm)];
     aiRCBSM_TRACKER_ARR_IDX = [getRCBSMFirstArrIdx(fe_rcbsm, i_formArrIdx)];
     return;
   }
   //At least one element is already being tracked.  Add this
   //element to the existing tracking arrays.
   if(wasRCBSMalreadyFound(fe_rcbsm.name))  {
     return crashVF("addRCBSMtoTracker:  Element named "" + fe_rcbsm.name + "" already exists in the TRACKER arrays.  SANITY CHECK.  SHOULD NEVER HAPPEN.");
   }
   var asTrackerNames = new Array(asRCBSM_TRACKER_NAME.length + 1);
   for(var i = 0; i < asTrackerNames.length; i++)  {
     if(i < (asTrackerNames.length - 1))  {
       asTrackerNames[i] = asRCBSM_TRACKER_NAME[i];
     }  else  {
       asTrackerNames[i] = fe_rcbsm.name;
     }
   }
   asRCBSM_TRACKER_NAME = asTrackerNames;
   var aiTrackerCounts = new Array(aiRCBSM_TRACKER_SEL_COUNT.length + 1);
   for(var i = 0; i < aiTrackerCounts.length; i++)  {
     if(i < (aiTrackerCounts.length - 1))  {
       aiTrackerCounts[i] = aiRCBSM_TRACKER_SEL_COUNT[i];
     }  else  {
       aiTrackerCounts[i] = getMCSelectedCountForTracker(f_orm, fe_rcbsm);
     }
   }
   aiRCBSM_TRACKER_SEL_COUNT = aiTrackerCounts;
   var aiTrackerArrIdx = new Array(aiRCBSM_TRACKER_ARR_IDX.length + 1);
   for(var i = 0; i < aiTrackerArrIdx.length; i++)  {
     if(i < (aiTrackerArrIdx.length - 1))  {
       aiTrackerArrIdx[i] = aiRCBSM_TRACKER_ARR_IDX[i];
     }  else  {
       aiTrackerArrIdx[i] = getRCBSMFirstArrIdx(fe_rcbsm, i_formArrIdx);
     }
   }
   aiRCBSM_TRACKER_ARR_IDX = aiTrackerArrIdx;
 }
 function getRCBSMFirstArrIdx(fe_rcbsm, i_formArrIdx)  {
   if(fe_rcbsm.type == "select-multiple")  {
     //select-multiple only has one instance in the form.  -1 indicates that.
     return -1;
   }
   return i_formArrIdx;
 }
 function getMCSelectedCountForTracker(f_orm, fe_rcbsm)  {
   if(fe_rcbsm.type != "radio"  &&
      fe_rcbsm.type != "checkbox"  &&
      fe_rcbsm.type != "select-multiple")  {
     return crashVF("getMCSelectedCount:  Element named "" + fe_rcbsm.name + "" is not of type radio, checkbox or select-multiple.  Type of this element is "" + fe_rcbsm.type + "".  SANITY CHECK.  SHOULD NEVER HAPPEN.");
   }
   if(fe_rcbsm.type == "radio")  {
     //This is not a multiple choice type.  -1 indicates that.
     return -1;
   }
   var iMCSelectedCount = 0;
   if(fe_rcbsm.type == "checkbox")  {
     for(var i = 0; i < f_orm[fe_rcbsm.name].length; i++)  {
       if(f_orm[fe_rcbsm.name][i].checked)  {
         iMCSelectedCount++;
       }
     }
     return iMCSelectedCount;
   }
   //Type is definitely select-multiple.
   for(var i = 0; i < fe_rcbsm.length; i++)  {
     if(fe_rcbsm.options[i].selected)  {
       iMCSelectedCount++;
     }
   }
   return iMCSelectedCount;
 }
 function getOptBooleanStringVF(bs_potential, s_variableName)  {
   return getOptBooleanString(bs_potential, s_variableName, "validate_form.getFormErrorMsgs");
 }
 function crashVF(s_message)  {
   return crash("validate_form.getFormErrorMsgs:  " + s_message);
 }
 function initializeLocalVars()  {
   resetCrashedFlag();
   asRCBSM_TRACKER_NAME = [];
   aiRCBSM_TRACKER_SEL_COUNT = [];
   aiRCBSM_TRACKER_ARR_IDX = [];
   iELEMENT_COUNT = 0;
   bFIRST_DEBUG_SCREEN_SEEN = false;
 }
 /**
   For backwards compatibility only.  Only use getFormErrorMsgs.  This function will eventually be eliminated.
  **/
 function validateForm(f_orm, s_userErrorPrefix, i_debugPerScreen)  {
   return getFormErrorMsgs(f_orm, s_userErrorPrefix, i_debugPerScreen);
 }

/**

 PRIVATE FUNCTIONS...end
**/

/**************************************************************************************************

 util_string.js...START
 Do not edit this file.  This file is dynamically generated by the validate_form.js
 ant build process
**************************************************************************************************/

/**

 VALIDATE_FORM.JS
 Comprehensive solution for validating HTML forms.
 Copyright (C) 2002, Jeff Epstein, jeff_epstein@yahoo.ru, http://www.jeffyjeffy.ru#download
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 This program 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 General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
**/
 //PHONE NUMBER AND ZIP CODE FORMAT/RANGES
   //For documentation, see
   //    documentation/index.html#string_zip
   //
   //Demo/testing values exist at the bottom of
   //    documentation/vf_string_phone_zip.html
   //
   //To test these formats for validity, see
   //    documentation/unit_test.html#util_string_tests
 //PHONE NUMBER FORMATS/RANGES...start
   //US 3 then 7
     var siPHONE_1_MINIMUM = "1001001000";
     var siPHONE_1_MAXIMUM = "9999999999";
   //US 7 only
     var siPHONE_2_MINIMUM = "1001000";
     var siPHONE_2_MAXIMUM = "9999999";
   var siPHONE_3_MINIMUM = "1000";
   var siPHONE_3_MAXIMUM = "9999";
   var siPHONE_4_MINIMUM = "001000";
   var siPHONE_4_MAXIMUM = "999999";
   var siPHONE_5_MINIMUM = "00000000";
   var siPHONE_5_MAXIMUM = "99999999";
   var siPHONE_6_MINIMUM = "1000000000";
   var siPHONE_6_MAXIMUM = "5555555555";
   var siPHONE_7_MINIMUM = "0";
   var siPHONE_7_MAXIMUM = "1";
   var siPHONE_8_MINIMUM = "1";
   var siPHONE_8_MAXIMUM = "9";
   var siPHONE_9_MINIMUM = "000";
   var siPHONE_9_MAXIMUM = "000";
   var siPHONE_10_MINIMUM = "010101";
   var siPHONE_10_MAXIMUM = "787374";
 //PHONE NUMBER FORMATS/RANGES...end
 //ZIP CODE FORMATS/RANGES...start
   //US 5+4
     var siZIP_1_RQD_MINIMUM = "00000";
     var siZIP_1_RQD_MAXIMUM = "99999";
     var siZIP_1_ALT_MINIMUM = "0001";
     var siZIP_1_ALT_MAXIMUM = "9999";
   //US 5 only
     var siZIP_2_RQD_MINIMUM = "00001";
     var siZIP_2_RQD_MAXIMUM = "99999";
     var siZIP_2_ALT_MINIMUM = "";
     var siZIP_2_ALT_MAXIMUM = "";
   var siZIP_3_RQD_MINIMUM = "1";
   var siZIP_3_RQD_MAXIMUM = "1";
   var siZIP_3_ALT_MINIMUM = "2";
   var siZIP_3_ALT_MAXIMUM = "2";
   var siZIP_4_RQD_MINIMUM = "01";
   var siZIP_4_RQD_MAXIMUM = "99";
   var siZIP_4_ALT_MINIMUM = "0001";
   var siZIP_4_ALT_MAXIMUM = "9999";
   var siZIP_5_RQD_MINIMUM = "00";
   var siZIP_5_RQD_MAXIMUM = "55";
   var siZIP_5_ALT_MINIMUM = "0";
   var siZIP_5_ALT_MAXIMUM = "7";
   var siZIP_6_RQD_MINIMUM = "54321";
   var siZIP_6_RQD_MAXIMUM = "55555";
   var siZIP_6_ALT_MINIMUM = "";
   var siZIP_6_ALT_MAXIMUM = "";
   var siZIP_7_RQD_MINIMUM = "00001";
   var siZIP_7_RQD_MAXIMUM = "00001";
   var siZIP_7_ALT_MINIMUM = "0001";
   var siZIP_7_ALT_MAXIMUM = "0001";
   var siZIP_8_RQD_MINIMUM = "09000";
   var siZIP_8_RQD_MAXIMUM = "91111";
   var siZIP_8_ALT_MINIMUM = "0003873874038834";
   var siZIP_8_ALT_MAXIMUM = "0020837401092837";
   var siZIP_9_RQD_MINIMUM = "0003873874038834";
   var siZIP_9_RQD_MAXIMUM = "0020837401092837";
   var siZIP_9_ALT_MINIMUM = "09000";
   var siZIP_9_ALT_MAXIMUM = "91111";
   var siZIP_10_RQD_MINIMUM = "0";
   var siZIP_10_RQD_MAXIMUM = "7";
   var siZIP_10_ALT_MINIMUM = "00";
   var siZIP_10_ALT_MAXIMUM = "55";
 //ZIP CODE FORMATS/RANGES...end


/**

 Does the provided string start or end with a space?
 EQUAL TO
   isSurroundedByChar(s_tring, " ");
**/

function isSurroundedBySpace(s_tring) {

 return isSurroundedByChar(s_tring, " ");

} /**

 Does the provided string start or end with the provided character?
 PARAMETERS
   s_tring  The string to analyze.
   c_har    The character that is determined to exist at the start or end of s_tring.
 RETURNS
   true   If the first or last character in s_tring is c_har.
   false  If s_tring is null or zero characters in length.
        If both the first and last characters in s_tring are *not* c_har.
**/

function isSurroundedByChar(s_tring, char_toTrim) {

 if(!s_tring)  {
   return false;
 }
 if(!char_toTrim  ||  char_toTrim.length != 1)  {
   return crash("isSurroundedByChar:  char_toTrim parameter must be provided, and be exactly one character in length.");
 }
 if(s_tring.length < 1)  {
   return false;
 }
 if(s_tring.substring(0, 1) == char_toTrim)  {
   return true;
 }
 return (s_tring.substring(s_tring.length - 1, s_tring.length) == char_toTrim);

}

/**

 Is the provided string a legal integer?
 RETURNS
   isNumber(s_potentialInteger, "false")
**/

function isInteger(s_potentialInteger) {

 return isNumber(s_potentialInteger, "false");

}

/**

 Is the provided string a legal decimal?
 RETURNS
   isNumber(s_potenitalDecimal, "true")
**/

function isDecimal(s_potentialDecimal) {

 return isNumber(s_potentialDecimal, "true");

} /**

 Is the provided string a legal number?
 PARAMETERS
   s_potentialNumber
     The string to analyze.  Required.
   bs_decimalAllowed
     Is the potential number allowed to be a decimal?  If "true", then yes.  If "false", no.
 RETURNS
   true
     If s_potentialNumber is a legal integer (regardless the value of bs_decimalAllowed).  A legal integer is a string that...
       ...contains one or more zeros.  Note that 0 equals 0000 equals 0000000000 equals ...
       ...starts with zero or one dashes (indicating negative), followed by one or more digits (0-9), where at least one is greater than zero.
     If bs_decimalAllowed is "true" and s_potentialNumber is a legal decimal.  A legal decimal is a string that...
       ...is an integer.
       ...starts with zero or one dashes (indicating negative) followed by zero or more digits, followed by a decimal point ("."), followed by *one* or more digits.
     (Note that s_potentialNumber is checked to be an integer first.  If it is, then true is returned, regardless the value of bs_decimalAllowed.  If the string is an integer, it is not checked, specifically, to see if it"s a decimal.  Hence, the description of a legal decimal number says "a decimal point" instead of "zero or one decimal points".)
   false
     If otherwise.
 LEGAL EXAMPLES (both integers and decimals)
     -1
     0
     1
     -50
     8750328754
     00008750328754
     08750328754
     -487584758475235
     -0000000487584758475235
     -0487584758475235
 ILLEGAL EXAMPLES (both integers and decimals)
     4875847-58475235
     487584758475235-
     [EMPTY_STRING]
     a
     0-
     -0
     Not a number!!!
     Some 123 numbers 456
     123 456
     -0.0
     -.0
     -0.000000
     -.000000
     1.
     .
 LEGAL EXAMPLES (decimals, but only after it is determined that the value is *not* an integer)
     1.1
     1.000830847018374
     058763408562473.01837486564417308746
     .1
     .0
     .01
     -1.0
**/

function isNumber(s_potentialNumber, bs_decimalAllowed) {

 crashIfMissing("util_string.jsNumber", s_potentialNumber, "s_potentialNumber");
 crashIfBadBooleanString(bs_decimalAllowed, "bs_decimalAllowed", "util_string.jsNumber");
 if(s_potentialNumber.length < 1)  {
   return false;
 }
 if(s_potentialNumber == "-")  {
   //A negative sign only makes no sense.
   return false;
 }
 if(/^-[0]+$/.test(s_potentialNumber))  {
   //Negative zero makes no sense.
   return false;
 }
 if(/^[0]+$/.test(s_potentialNumber))  {
   //Zero is a legal number:
   //0  ==  0000000000000  ==  000
   return true;
 }
 //It is definitely not zero.
 //^         The start of the line.
 //[-]{0,1}  Zero or one dashes.
 //[0-9]+    One or more of any digit.
 //$         The end of the line.
 if(/^[-]{0,1}[0-9]+$/.test(s_potentialNumber))  {
   //No matter what, this is valid.  This is a leagal integer
   //and decimal.
   return true;
 }
 //It"s not an integer...
 if(bs_decimalAllowed == "false")  {
   //...but it must be.
   return false;
 }
 //...and that"s okay.  It might be a decimal
 //Due to precision:
 //10.0000000000001 is legal (12 zeros)
 //10.00000000000001 is not  (13 zeros)
 //^         The start of the line.
 //[-]{0,1}  Zero or one dashes.
 //[0-9]*    Zero or more digits.
 //[.]      A decimal point.
 //[0-9]+    One or more digits.
 //$         The end of the line.
 if(/^[-]{0,1}[0-9]*[.][0-9]+$/.test(s_potentialNumber))  {
   //It is a "raw" decimal.  The only thing that would make
   //this illegal is if it were -0.0 or -.0, or -0.0000 or
   //-.0000 or ...
   return !(/^-0*[.]0+$/.test(s_potentialNumber));
 }
 //It is not a legal decimal number.
 return false;

}

function isEmail(s_potentialEmail) {

 if(!s_potentialEmail  ||  s_potentialEmail.length < 1)  {
   return crash("isValidNumber:  s_potentialEmail must be defined, and at least one character in length.");
 }
 if(s_potentialEmail.indexOf(" ") != -1  ||
    s_potentialEmail.indexOf("/") != -1  ||
    s_potentialEmail.indexOf("\\") != -1  ||
    s_potentialEmail.indexOf(",") != -1)  {
   //A space, slash or comma was found.
   return false;
 }
 if(/[@.][@.]/.test(s_potentialEmail))  {
   //An @ or dot is followed by an @ or dot.
   return false;
 }
 if(/^[@.]/.test(s_potentialEmail))  {
   //The first character is an @ or dot.
   return false;
 }
 if(/[@.]$/.test(s_potentialEmail))  {
   //The last character may not be an @ or dot.
   return false;
 }
 if(!/^[^@]+@[^@]+$/.test(s_potentialEmail))  {
   //Only one @ allowed
   //    (Negative of:
   //     Must have one or more non-@ starting the line,
   //     exactly one @, and then
   //     one or more non-@ ending the line.)
   return false;
 }
 //There is exactly one @.
 if(!/@.*[.]/.test(s_potentialEmail))  {
   //At least one dot must follow the (single) @.
   return false;
 }
 //At least one dot follows the @.  We already determined
 //above that it does not immediately follow it,
 //No negative conditions were met.  This is a legal email address.
 //Cool, eh?  : )
 return true;

}

function removeNonNumbers(s_tring) {

 if(!s_tring  ||  s_tring.length < 1)  {
   return crash("removeNonNumbers:  s_tring must be defined, and at least one character in length.");
 }
 var reNonNumbers = /^\D$/;
 if(/^\D$/.test(s_tring))  {
   //There are no numbers at all.
   return "";
 }
 //There is at least one number.
 var asNumberParts = s_tring.split(/\D/);
 var sNumber = asNumberParts[0];
 for(var i = 1; i < asNumberParts.length; i++)  {
   sNumber += asNumberParts[i];
 }
 return sNumber;

} /**

 Are the provided phone format strings valid?
 See the documentation above, regarding PHONE NUMBER FORMATS/RANGES.  Specifically, under the "phone" section, under "--- RULES ---".
 Call this function manually, if you wish.  It is not called by any other function in this js file...except crashIfBadPhoneFormat.
 PARAMETER
   bs_crashIfBad
     Must equal either "true" or "false".  If "true", then if the formats are invalid, this function crashes with a descriptive message.  See utility.crash().
**/

function isPhoneFormatValid(bs_crashIfBad, si_minFormat, si_maxFormat) {

 return isFormatValid("Phone", bs_crashIfBad, "si_minFormat", "si_maxFormat", si_minFormat, si_maxFormat);

}

function getValidPhone(s_potentialPhone) {

 return getValidPhone1(s_potentialPhone);

} function getValidPhone1(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_1_MINIMUM, siPHONE_1_MAXIMUM, s_potentialPhone);

} function getValidPhone2(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_2_MINIMUM, siPHONE_2_MAXIMUM, s_potentialPhone);

} function getValidPhone3(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_3_MINIMUM, siPHONE_3_MAXIMUM, s_potentialPhone);

} function getValidPhone4(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_4_MINIMUM, siPHONE_4_MAXIMUM, s_potentialPhone);

} function getValidPhone5(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_5_MINIMUM, siPHONE_5_MAXIMUM, s_potentialPhone);

} function getValidPhone6(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_6_MINIMUM, siPHONE_6_MAXIMUM, s_potentialPhone);

} function getValidPhone7(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_7_MINIMUM, siPHONE_7_MAXIMUM, s_potentialPhone);

} function getValidPhone8(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_8_MINIMUM, siPHONE_8_MAXIMUM, s_potentialPhone);

} function getValidPhone9(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_9_MINIMUM, siPHONE_9_MAXIMUM, s_potentialPhone);

} function getValidPhone10(s_potentialPhone) {

 return getValidPhoneFromFormat(siPHONE_10_MINIMUM, siPHONE_10_MAXIMUM, s_potentialPhone);

} /**

 Get the phone number out of the provided string.
 PARAMETERS
   si_minFormat
     The format string representing the minimum allowable bound for a legal phone number.  It is *assumed* that this string is provided and valid.  Use isPhoneFormatValid() to validate this, along with si_maxFormat.  For specific information on this variable, see the documentation above, regarding PHONE NUMBER FORMATS/RANGES, under the "phone" section.
   si_maxFormat
     The format string representing the maximum allowable bound for a legal phone number.  It is *assumed* that this string is provided and valid.  Use isPhoneFormatValid() to validate this, along with si_maxFormat.  For specific information on this variable, see the documentation above, regarding PHONE NUMBER FORMATS/RANGES, under the "phone" section.
   s_potentialPhone
     The string containing the (potentially legal) phone number, including any surrounding text.  For example:
       (215) 555-1212
       215 555 1212
       2155551212
 RETURNS
   If the phone number is invalid, according to the format, empty string ("") is returned.  Otherwise, the non-digits are stripped from s_potentialPhone, and the digits alone are returned (but as a string, preserving leading zeros).  For example, all of the above examples (under s_potentialPhone) return "2155551212".
**/

function getValidPhoneFromFormat(si_minFormat, si_maxFormat, s_potentialPhone) {

 if(!s_potentialPhone  ||  s_potentialPhone.length < 1)  {
   return crash("isValidNumber:  s_potentialPhone must be defined, and at least one character in length.");
 }
 //This also removes dashes (negative symbols) and decimal points.
 var siPhoneNumber = removeNonNumbers(s_potentialPhone);
 if(!siPhoneNumber  ||  siPhoneNumber.length < 1  ||
      siPhoneNumber.length != si_minFormat.length)  {
   //The length is illegal.
   return "";
 }
 //Must supply radix=10
 var iMin = parseInt(si_minFormat, 10);
 var iMax = parseInt(si_maxFormat, 10);
 if(isValidNumber(siPhoneNumber, iMin, iMax))  {
   //The phone number is in bounds.
   return siPhoneNumber;
 }
 //It is not a valid phone number.
 return "";

}

/**

 Are the provided zip format strings valid?
 See the documentation above, regarding PHONE NUMBER FORMATS/RANGES.  Specifically, under the "zip code" section, under "--- RULES ---".
 Call this function manually, if you wish.  It is not called by any other function in this js file.
 PARAMETER
   bs_crashIfBad
     Must equal either "true" or "false".  If "true", then if the formats are invalid, this function crashes with a descriptive message.  See utility.crash().
**/

function isZipFormatValid(bs_crashIfBad, si_rqdMinFormat, si_rqdMaxFormat, si_altMinFormat, si_altMaxFormat) {

 if(!isFormatValid("Zip", bs_crashIfBad, "si_rqdMinFormat", "si_rqdMaxFormat", si_rqdMinFormat, si_rqdMaxFormat))  {
   return false;
 }
 //The required format is valid.
 if(!si_altMinFormat ^ !si_altMaxFormat)  {
   if(bs_crashIfBad == "true")  {
     return crash("util_string.jsZipFormatValid:  si_altMinFormat ("" + si_altMinFormat + "") and si_altMaxFormat ("" + si_altMaxFormat + "") must both be either undefined or defined.");
   }
   return false;
 }
 //Both are either undefined, or defined.
 if(!si_altMinFormat)  {
   //One is undefined, therefore both are undefined.
   return true;
 }
 //Both are defined.
 return isFormatValid("Zip", bs_crashIfBad, "si_altMinFormat", "si_altMaxFormat", si_altMinFormat, si_altMaxFormat)

}

function getValidZip(s_potentialZip) {

 return getValidZip1(s_potentialZip);

} function getValidZip1(s_potentialZip) {

 return getValidZipFromFormat(siZIP_1_RQD_MINIMUM, siZIP_1_RQD_MAXIMUM, siZIP_1_ALT_MINIMUM, siZIP_1_ALT_MAXIMUM, s_potentialZip);

} function getValidZip2(s_potentialZip) {

 return getValidZipFromFormat(siZIP_2_RQD_MINIMUM, siZIP_2_RQD_MAXIMUM, siZIP_2_ALT_MINIMUM, siZIP_2_ALT_MAXIMUM, s_potentialZip);

} function getValidZip3(s_potentialZip) {

 return getValidZipFromFormat(siZIP_3_RQD_MINIMUM, siZIP_3_RQD_MAXIMUM, siZIP_3_ALT_MINIMUM, siZIP_3_ALT_MAXIMUM, s_potentialZip);

} function getValidZip4(s_potentialZip) {

 return getValidZipFromFormat(siZIP_4_RQD_MINIMUM, siZIP_4_RQD_MAXIMUM, siZIP_4_ALT_MINIMUM, siZIP_4_ALT_MAXIMUM, s_potentialZip);

} function getValidZip5(s_potentialZip) {

 return getValidZipFromFormat(siZIP_5_RQD_MINIMUM, siZIP_5_RQD_MAXIMUM, siZIP_5_ALT_MINIMUM, siZIP_5_ALT_MAXIMUM, s_potentialZip);

} function getValidZip6(s_potentialZip) {

 return getValidZipFromFormat(siZIP_6_RQD_MINIMUM, siZIP_6_RQD_MAXIMUM, siZIP_6_ALT_MINIMUM, siZIP_6_ALT_MAXIMUM, s_potentialZip);

} function getValidZip7(s_potentialZip) {

 return getValidZipFromFormat(siZIP_7_RQD_MINIMUM, siZIP_7_RQD_MAXIMUM, siZIP_7_ALT_MINIMUM, siZIP_7_ALT_MAXIMUM, s_potentialZip);

} function getValidZip8(s_potentialZip) {

 return getValidZipFromFormat(siZIP_8_RQD_MINIMUM, siZIP_8_RQD_MAXIMUM, siZIP_8_ALT_MINIMUM, siZIP_8_ALT_MAXIMUM, s_potentialZip);

} function getValidZip9(s_potentialZip) {

 return getValidZipFromFormat(siZIP_9_RQD_MINIMUM, siZIP_9_RQD_MAXIMUM, siZIP_9_ALT_MINIMUM, siZIP_9_ALT_MAXIMUM, s_potentialZip);

} function getValidZip10(s_potentialZip) {

 return getValidZipFromFormat(siZIP_10_RQD_MINIMUM, siZIP_10_RQD_MAXIMUM, siZIP_10_ALT_MINIMUM, siZIP_10_ALT_MAXIMUM, s_potentialZip);

} /**

 Get the zip code out of the provided string.
 PARAMETERS
   si_rqdMinFormat
     The format string representing the minimum allowable bound for the required portion of a legal zip code.  It is *assumed* that this string is provided and valid.  Use isZipFormatValid() to validate this, along with si_maxFormat.  For specific information on this variable, see the documentation above, regarding PHONE NUMBER FORMATS/RANGES, under the "zip code" section.
   si_rqdMaxFormat
     The format string representing the maximum allowable bound for the required portion of a legal zip code.  It is *assumed* that this string is provided and valid.  Use isZipFormatValid() to validate this, along with si_maxFormat.  For specific information on this variable, see the documentation above, regarding PHONE NUMBER FORMATS/RANGES, under the "zip code" section.
   si_altMinFormat
     The format string representing the minimum allowable bound for the alternate portion of a legal zip code.  It is *assumed* that this string is provided and valid.  Use isZipFormatValid() to validate this, along with si_maxFormat.  For specific information on this variable, see the documentation above, regarding PHONE NUMBER FORMATS/RANGES, under the "zip code" section.
   si_altMaxFormat
     The format string representing the maximum allowable bound for the alternate portion of a legal zip code.  It is *assumed* that this string is provided and valid.  Use isZipFormatValid() to validate this, along with si_maxFormat.  For specific information on this variable, see the documentation above, regarding PHONE NUMBER FORMATS/RANGES, under the "zip code" section.
   s_potentialZip
     The string containing the (potentially legal) zip code, including any surrounding text.  For example:
       08052-3848
       19130 (0408)
       00483
 RETURNS
   If the zip code is invalid, according to the format, empty string ("") is returned.  Otherwise, the non-digits are stripped from s_potentialZip, and the digits alone are returned (but as a string, preserving leading zeros).  For example, the second example above (under s_potentialZip) returns "191300408".
**/

function getValidZipFromFormat(si_rqdMinFormat, si_rqdMaxFormat, si_altMinFormat, si_altMaxFormat, s_potentialZip) {

 if(!s_potentialZip  ||  s_potentialZip.length < 1)  {
   return crash("isValidNumber:  s_potentialZip must be defined, and at least one character in length.");
 }
 var siZip = removeNonNumbers(s_potentialZip);
 var bLegalLength = false;
 if(siZip)  {
   //There is at least one digit in the zip code...it does
   //exist and...
   if(siZip.length == si_rqdMinFormat.length)  {
     //...it is the required length.
     bLegalLength = true;
   }  else if(si_altMinFormat  &&  si_altMinFormat.length > 0  &&
                  siZip.length == (si_rqdMinFormat.length + si_altMinFormat.length))  {
     //...although it is not the required length, there is
     //an alternate length format, and the zip code has
     //the same length as it PLUS the required part.
     bLegalLength = true;
   }  //ELSE:  There is no alternate format.
 }
 if(!bLegalLength)  {
   return "";
 }
 //The length is legal, according to the format.
 var sRqdPart = siZip.substring(0, si_rqdMinFormat.length);
 //Must specify 10 as the radix (base).  If you don"t, and the
 //format has leading zeros, it may get confused and assume
 //that it has a different radix.
 var iMin = parseInt(si_rqdMinFormat, 10);
 var iMax = parseInt(si_rqdMaxFormat, 10);
 if(!isValidNumber(sRqdPart, iMin, iMax))  {
   //The zip is out of bounds.
   return "";
 }
 //The required part is legal.
 if(siZip.length > sRqdPart.length)  {
   //The length of the overall zip (siZip) is longer than the
   //length of the required part.  In other words, the
   //potential zip definitely has an alternate part.
   var sAltPart = siZip.substring(si_rqdMinFormat.length, siZip.length);
   //Must specify 10 as the radix (base).
   iMin = parseInt(si_altMinFormat, 10);
   iMax = parseInt(si_altMaxFormat, 10);
   if(!isValidNumber(sAltPart, iMin, iMax))  {
     //The zip is out of bounds.
     return "";
   }
 }
 //Every part is in range.
 return siZip;

}

/**

 Is the provided string (who"s value is a non-negative integer) legal?
 PARAMETERS
   s_potentialInt
     The string to analyze.  Required, and it is *assumed* that this only contains digits (0-9.  Decimal points ["."] and negative symbols ["-"] are not legal).  If it contains anything else, this function will behave unpredictably.
   bs_trailingZeroOk
     Required.  Must equal "true" or "false".  If "true", then s_potentialInt is considered legal if it starts with one or more zeros (regardless if it actually equals zero).  If "false", then when s_potentialInt starts with a zero, this function returns false.  This parameter is primary, over bs_zeroOk (see "NOTE").
   bs_zeroOk
     Required.  Must equal "true" or "false".  If "true", then s_potentialInt is considered legal if it is equal to zero ("0", "00", "00000", "0000000000", ...).  If "false", then when s_potentialInt equals zero, this function returns false.  No matter what, a non-zero value is okay, even if there are trailing zeros (however, this does not override bs_trailingZeroOk).  This parameter is secondary to bs_trailingZerosOk (see "NOTE").
   NOTE.
     Note which combinations of bs_trailingZeroOk and bs_zeroOk are legal:
     bs_trailingZeroOk     bs_zeroOk       LEGAL?
       true                 true            yes
       true                 false           yes
       false                true            NO
       false                false           yes
 RETURNS
   true
     If s_potentialInt conforms to the rules defined by bs_zeroOk and bs_trailingZeroOk parameters.
   false
     If otherwise.
**/

function isValidPosIntStr(s_potentialInt, bs_trailingZeroOk, bs_zeroOk) {

 crashIfMissing("util_string.jsValidPosIntStr", s_potentialInt, "s_potentialInt");
 crashIfBadBooleanString(bs_trailingZeroOk, "bs_trailingZeroOk", "util_string.jsValidPosIntStr");
 crashIfBadBooleanString(bs_zeroOk, "bs_zeroOk", "util_string.jsValidPosIntStr");
 if(bs_zeroOk == "true"  &&  bs_trailingZeroOk == "false")  {
   return crash("util_string.jsValidPosIntStr:  bs_trailingZero equals "false", but bs_zeroOk equals "true".");
 }
 if(bs_zeroOk == "true")  {
   //No matter what, s_potentialInt is valid.
   return true;
 }
 //Zero, as a whole, is not okay, however, trailing zeros may
 //be okay.
 var iTrailingZeros = 0;
 for(var i = 0; i < s_potentialInt.length; i++)  {
   var cDigit = s_potentialInt.substring(i, i + 1);
   if(cDigit == "0")  {
     iTrailingZeros++;
   }  else  {
     //We"ve reached the first non-zero.
     break;
   }
 }
 if(iTrailingZeros == 0)  {
   //There are no trailing zeros.  No further analysis
   //needed.
   return true;
 }
 //There is at least one trailing zero.
 if(iTrailingZeros == s_potentialInt.length)  {
   //EVERY digit is equal to zero.
   //s_potentialInt equals zero.
   //s_potentialInt contains only zeros.
   //If bs_zeroOk equals "true":  return true.
   //If bs_zeroOk equals "false":  return false.
   return (bs_zeroOk == "true");
 }
 //There is at least one non-zero digit, following the
 //initial trailing zero(s).
 //If bs_trailingZeroOk equals "true":  return true.
 //If bs_trailingZeroOk equals "false":  return false.
 return (bs_trailingZeroOk == "true");

}

function trimSpaces(s_tring) {

 return trimChar(" ", s_tring);

}

function trimChar(c_harToTrim, s_tring) {

 if(!c_harToTrim  ||  c_harToTrim.length != 1)  {
   return crash("util_sting.trimChar:  c_harToTrim must be provided, and must be exactly one character in length.  Currently "" + c_harToTrim + "".");
 }
 crashIfMissing("util_string.trimSpaces", s_tring, "s_tring");
 var i = 0;
 var iStartingSpaces = 0;
 while(s_tring.substring(i, (i + 1)) == c_harToTrim)  {
   iStartingSpaces++
   i++;
 }
 if(iStartingSpaces == s_tring.length)  {
   return "";
 }
 i = 0;
 var iEndingSpaces = 0;
 while(s_tring.substring((s_tring.length - i), (s_tring.length - (i + 1))) == c_harToTrim)  {
   iEndingSpaces++
   i++;
 }
 if(iStartingSpaces == 0  &&  iEndingSpaces == 0)  {
   return s_tring;
 }
 return s_tring.substring(iStartingSpaces, (s_tring.length - iEndingSpaces));

}

function isFormatValid(s_type, bs_crashIfBad, s_minDesc, s_maxDesc, si_minimum, si_maximum) {

 crashIfBadBooleanString(bs_crashIfBad, "bs_crashIfBad", "util_string.js" + s_type + "FormatValid");
 crashIfMissing("util_string.js" + s_type + "FormatValid", si_minimum, s_minDesc);
 crashIfMissing("util_string.js" + s_type + "FormatValid", si_maximum, s_maxDesc);
 if(si_minimum.length != si_maximum.length)  {
   if(bs_crashIfBad == "true")  {
     return crash("util_string.js." + s_type + "FormatValid:  " + s_minDesc + " ("" + si_minimum + "") must be the same length as " + s_maxDesc + " ("" + si_maximum + "").");
   }
   return false;
 }
 if(!isInteger(si_minimum)  ||  si_minimum < 0)  {
   if(bs_crashIfBad == "true")  {
     return crash("util_string.js." + s_type + "FormatValid:  " + s_minDesc + " (currently "" + si_minimum + "") must be an integer greater than or equal to zero.");
   }
   return false;
 }
 if(!isInteger(si_maximum)  ||  si_maximum < 0)  {
   if(bs_crashIfBad == "true")  {
     return crash("util_string.js." + s_type + "FormatValid:  " + s_maxDesc + " (currently "" + si_maximum + "") must be an integer greater than or equal to zero.");
   }
   return false;
 }
 //Must supply radix=10
 var iMin = parseInt(si_minimum, 10);
 var iMax = parseInt(si_maximum, 10);
 if(iMin > iMax)  {
   if(bs_crashIfBad == "true")  {
     return crash("util_string.js." + s_type + "FormatValid:  " + s_minDesc + " (" + si_minimum + ") is numerically greater than " + s_maxDesc + " (" + si_maximum + ").");
   }
   return false;
 }
 return true;

}

function getPadded(s_tring, i_padLength) {

 crashIfMissing("util_string.js.getPadded", s_tring, "s_tring");
 crashIfMissing("util_string.js.getPadded", i_padLength, "i_padLength");
 if(!isInteger(i_padLength))  {
   return crash("util_string.js.getPadded:  i_padLength ("" + i_padLength + "") must be an *integer* greater than or equal to zero.");
 }  else if(!isValidNumberOpt(i_padLength, 0, "true", -1, "false"))  {
   return crash("util_string.js.getPadded:  i_padLength ("" + i_padLength + "") must be an *integer* greater than or equal to zero.");
 }
 if(s_tring.length >= i_padLength)  {
   return s_tring;
 }
 for(var i = s_tring.length; i < (i_padLength + 1); i++)  {
   s_tring = s_tring + " ";
 }
 return s_tring;

} /**************************************************************************************************

 util_number.js...START
 Do not edit this file.  This file is dynamically generated by the validate_form.js
 ant build process
**************************************************************************************************/

/**

 VALIDATE_FORM.JS
 Comprehensive solution for validating HTML forms.
 Copyright (C) 2002, Jeff Epstein, jeff_epstein@yahoo.ru, http://www.jeffyjeffy.ru#download
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 This program 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 General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
**/

function isValidRangeOpt(i_min, bs_enforceMin, i_max, bs_enforceMax) {

 crashIfBadBooleanString(bs_enforceMin, "bs_enforceMin", "util_number.isValidRangeOpt");
 crashIfBadBooleanString(bs_enforceMax, "bs_enforceMax", "util_number.isValidRangeOpt");
 if(bs_enforceMin == "false"  ||  bs_enforceMax == "false")  {
   //At least one of the bounds are not being enforced.
   return true;
 }
 return !(i_min > i_max);

} function isValidRange(i_min, i_max) {

 return isValidRangeOpt(i_min, "true", i_max, "true");

} function isValidNumber(i_number, i_min, i_max) {

 return isValidNumberOpt(i_number, i_min, "true", i_max, "true");

} /**

 It is assumed that the range is valid.  You will get unpredictable results if it is not.
**/

function isValidNumberOpt(i_number, i_min, bs_enforceMin, i_max, bs_enforceMax) {

 crashIfMissing("util_number.isValidNumber", i_number, "i_number");
       //alert("isValidRangeOpt(" + i_number + ", " + i_min + ", " + bs_enforceMin + ", " + i_max + ", " + bs_enforceMax + ")...\n...isValidRangeOpt(" + i_min + ", " + bs_enforceMin + ", " + i_number + ", "true")=" + isValidRangeOpt(i_min, bs_enforceMin, i_number, "true") + "\n...isValidRangeOpt(" + i_number + ", "true", " + i_max + ", " + bs_enforceMax + ")=" + isValidRangeOpt(i_number, "true", i_max, bs_enforceMax));
 return (isValidRangeOpt(i_min, bs_enforceMin, i_number, "true")  &&
         isValidRangeOpt(i_number, "true", i_max, bs_enforceMax));

}

/**************************************************************************************************

 utility.js...START
 Do not edit this file.  This file is dynamically generated by the validate_form.js
 ant build process
**************************************************************************************************/

/**

 VALIDATE_FORM.JS
 Comprehensive solution for validating HTML forms.
 Copyright (C) 2002, Jeff Epstein, jeff_epstein@yahoo.ru, http://www.jeffyjeffy.ru#download
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 This program 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 General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
**/

//GLOBAL VARIABLES...start

 //A secret public global variable.  For testing purposes, you may want to
 //avoid re-displaying the error after the alert box (within H1 tags).
 //
 //This prevents the crash function from re-presenting the
 //error, after the alert box, within H1 tags.  It makes it so you
 //don"t have to press the back button between each error, in order
 //to get back to this page.
 var bCRASH_ONLY_ALERT_BOX = false;
 //This is automatically manipulated by this js file.  It is private
 //and should never be altered.
 var bCrashed = false;

//GLOBAL VARIABLES...end /**

 Present an error message in an alert box, and also print the provided error message to screen, surrounded by H1 tags.  This function is intended for programming errors, not user errors.
 Although execution is not truly interrupted, this should be significant enough to alert the programmer to an error.
 PARAMETERS
   s_callingFuncAndError
     The function name, followed by the error message.
 RETURNS
   false
     Always.
**/

function crash(s_callingFuncAndError) {

 alert("-------ERROR-------\n\nERROR in " + s_callingFuncAndError);
 if(!bCRASH_ONLY_ALERT_BOX)  {
document.writeln("

ERROR in " + s_callingFuncAndError + "

");
 }
 bCrashed = true;
 return false;

} /**

 Was crash() called?
 RETURNS
   true
     If crash() was called.
   false
     If crash() was never called...or when it was, but you since called resetCrashedFlag().
**/

function hasCrashed() {

 return bCrashed;

} /**

 Make it appear as if crash() was never called, regardless of whether or not it actually was.  This is probably only useful for testing purposes.
**/

function resetCrashedFlag() {

 bCrashed = false;

} /**

 Conditionally print the provided message in an alert box.
 PARAMETERS
   b_condition
     If true, present s_message in an alert box.  If false, do nothing.
   s_message
     The message to present in an alert box, should b_condition be true.  If b_condition is false, this parameter is ignored.
 RETURNS
   true
     If b_condition is true.
   false
     If b_condition is false.
**/

function calert(b_condition, s_message) {

 if(b_condition)  {
   alert(s_message);
   return false;
 }
 return true;

}

/**

 Convenience function to print an error message, should a required parameter not be provided.
 PARAMETERS
   s_callingFileFunc
     Passed directly to crash, if !o_param.  If o_param is true, this parameter is ignored.
   s_paramName
     The name of o_param, only for the potential error message.  If o_param is true, this parameter is ignored.
   o_param
     The required parameter.  If "false" (!o_param) the an error message is printed.
 RETURNS
   true
     If o_param is true.
   false
     If o_param is false.
**/

function crashIfMissing(s_callingFileFunc, s_paramName, o_param) {

 if(!o_param)  {
   return crash(s_callingFileFunc + ":  Required parameter " + s_paramName + " not provided.");
 }
 return true;

} /**

 A single unit test.  If the actual result differs from the actual, an error alert box is presented.
 PARAMETERS
   s_nameOfTest
     The name of the calling JavaScript file and function name, currently being tested.  Required.
   i_testNumber
     The number of the test, for potential error messages only.  Required.
   s_expected
     The expected response from this test.
   s_actual
     The actual response from this test.
 RETURNS
   true
     If s_expected equals s_actual.
   false
     If s_expected does not equal s_actual.
**/

function test(s_nameOfTest, i_testNumber, s_expected, s_actual) {

 crashIfMissing(s_nameOfTest, "s_nameOfTest", "utility.test");
 crashIfMissing(i_testNumber, "i_testNumber", "utility.test");
 if(s_expected != s_actual)  {
   alert("---ERROR---\n\n\tTest name:\t" + s_nameOfTest + "\n\tTest number:\t" + i_testNumber + "\n\tExpected:\t"" + s_expected + ""\n\tActual:\t\t"" + s_actual + """);
   return false;
 }
 return true;

} function crashIfBadBooleanString(bs_potential, s_variableName, s_callingFunc) {

 if(!bs_potential)  {
   return crash(s_callingFunc + ":  " + s_variableName + " must be a *string*, provided, and equal to either "true" or "false".  It is currently a *boolean* equal to "false".");
 }
 if(bs_potential != "true"  &&  bs_potential != "false")  {
   var sValue = "string equal to "" + bs_potential;
   if(typeof(bs_potential) == "boolean")  {
     //It is equal to *boolean* true.  It"s not a string.
     //Note that it"s NOT false, because the first line of this
     //function eliminated this possibility.
     sValue = "*boolean* equal to "" + bs_potential;
   }
   return crash(s_callingFunc + ":  " + s_variableName + " must be a string, provided, and equal to either "true" or "false".  It is currently a " + sValue + "".");
 }

} function crashIfBadBooleanStringOpt(bs_potential, s_variableName, s_callingFunc) {

 if(!bs_potential)  {
   return;
 }
 //bs_potential has been provided.
 if(bs_potential != "true"  &&  bs_potential != "false")  {
   var sValue = "string equal to "" + bs_potential + "";
   if(typeof(bs_potential) == "boolean")  {
     //It is equal to *boolean* true.  It"s not a string.
     //Note that it"s NOT false, because the first line of this
     //function eliminated this possibility.
     sValue = "*boolean* equal to "" + bs_potential + "";
   }
   return crash(s_callingFunc + ":  " + s_variableName + " is not required, but when provided it must be a string, and equal to either "true" or "false".  It is currently a " + sValue + "".");
 }

}

function getOptBooleanString(bs_potential, s_variableName, s_callingFunc) {

 if(bs_potential)  {
   crashIfBadBooleanStringOpt(bs_potential, s_variableName, s_callingFunc);
   return bs_potential;
 }  else  {
   return "false";
 }

}


/**

 Is the provided object an array?
 This concept comes from Kas Thomas, at
 http://www.planetpdf.ru/mainpage.asp?webpageid=1144
 PARAMETERS
   o_potentialArray
     The object that is analyzed to see if it is an array.  Required.
 RETURNS
   true
     If o_potentialArray is an array.
   false
     If o_potentialArray is anything but an array.
**/

function isArray(o_potentialArray) {

 crashIfMissing(o_potentialArray, "o_potentialArray", "utility.isArray");
 if(typeof o_potentialArray != "object")  {
   return false;
 }
 //It is definitely an object.
 return (o_potentialArray.constructor.toString().match(/array/i) != null);

} </SCRIPT> <SCRIPT LANGUAGE="JavaScript">

</SCRIPT> </HEAD> <BODY><a name="top"></a>

Realistic Example: Normal Login

To login, provide your username and password.

<FORM onSubmit="return isFormValid(this);">

 
Username: <INPUT TYPE="text" NAME="username">
Password: <INPUT TYPE="password" NAME="password">

<INPUT TYPE="submit">

<INPUT TYPE="reset">

</FORM> </BODY> </HTML>



 </source>
   
  


Time Validate

   <source lang="html4strict">
 

<HTML> <HEAD> <SCRIPT language="JavaScript">

</SCRIPT> </HEAD> <BODY> <FORM name="myForm" action="#" onSubmit="return check_it();"> What time is it?
<INPUT type="text" name="the_time">
<INPUT type="submit" value="Submit"> </BODY> </HTML>


 </source>
   
  


URL Validate

   <source lang="html4strict">
 

<HTML> <HEAD> <SCRIPT language="JavaScript">

</SCRIPT> </HEAD> <BODY> <FORM name="myForm" action="#" onSubmit="return check_it();"> Enter URL:
<INPUT type="text" name="t1">
<INPUT type="submit" value="Submit"> </BODY> </HTML>


 </source>
   
  


Use JavaScript to check the password input

   <source lang="html4strict">
 

<html> <head> <title>A Simple Page</title> <script language="JavaScript"> function sendMe() {

   return confirm("Continue?");

} function chkForm() {

   if (form1.pass1.value != form1.pass2.value)
   {
       alert("Password does not match");
       form1.pass1.value = "";
       form1.pass2.value = "";
       form1.pass1.focus();
       return false;
   }

} </script> </head> <body> <form name="form1" method="POST" action="someCGI.cgi" onSubmit="return sendMe()">

Enter you password: <input type="password" name="pass1">
Re-enter you password: <input type="password" name="pass2">
<input type="submit" value="Submit" onClick="return chkForm()"> <input type="reset" value="Reset">

</form> </body> </html>


 </source>