home *** CD-ROM | disk | FTP | other *** search
/ business-86-101-185-173.business.broadband.hu / business-86-101-185-173.business.broadband.hu.zip / business-86-101-185-173.business.broadband.hu / scs.zip / ApplicationWebUIValidation.js < prev    next >
Text File  |  2008-06-18  |  46KB  |  1,502 lines

  1. //<script>
  2.  
  3. //Same as the Microsoft version, except with 1 line added to the end
  4. function ValidatorOnLoad() {
  5.     if (typeof(Page_Validators) == "undefined")
  6.         return;
  7.  
  8.     var i, val;
  9.     for (i = 0; i < Page_Validators.length; i++) {
  10.         val = Page_Validators[i];
  11.         if (typeof(val.evaluationfunction) == "string") {
  12.             eval("val.evaluationfunction = " + val.evaluationfunction + ";");
  13.         }
  14.         if (typeof(val.isvalid) == "string") {
  15.             if (val.isvalid == "False") {
  16.                 val.isvalid = false;                                
  17.                 Page_IsValid = false;
  18.             } 
  19.             else {
  20.                 val.isvalid = true;
  21.             }
  22.         } else {
  23.             val.isvalid = true;
  24.         }
  25.         if (typeof(val.enabled) == "string") {
  26.             val.enabled = (val.enabled != "False");
  27.         }
  28.         ValidatorHookupControlID(val.controltovalidate, val);
  29.         ValidatorHookupControlID(val.controlhookup, val);
  30.     }
  31.     Page_ValidationActive = true;
  32.     
  33.     if (!Page_IsValid) { ValidationSummaryOnSubmit(); }
  34. }
  35.  
  36. //Same as the Microsoft version, except:
  37. //A) This function will not display duplicate validator error messages
  38. //   in either the summary or the message box.
  39. function ValidationSummaryOnSubmit() {
  40.     if (typeof(Page_ValidationSummaries) == "undefined") 
  41.         return;
  42.     var summary, sums, s;
  43.     for (sums = 0; sums < Page_ValidationSummaries.length; sums++) {
  44.         summary = Page_ValidationSummaries[sums];
  45.         summary.style.display = "none";
  46.         if (!Page_IsValid) {
  47.             if (summary.showsummary != "False") {
  48.                 summary.style.display = "";
  49.                 if (typeof(summary.displaymode) != "string") {
  50.                     summary.displaymode = "BulletList";
  51.                 }
  52.                 switch (summary.displaymode) {
  53.                     case "List":
  54.                         headerSep = "<br>";
  55.                         first = "";
  56.                         pre = "";
  57.                         post = "<br>";
  58.                         endString = "";
  59.                         break;
  60.                         
  61.                     case "BulletList":
  62.                     default: 
  63.                         headerSep = "";
  64.                         first = "<ul>";
  65.                         pre = "<li>";
  66.                         post = "</li>";
  67.                         endString = "</ul>";
  68.                         break;
  69.                         
  70.                     case "SingleParagraph":
  71.                         headerSep = " ";
  72.                         first = "";
  73.                         pre = "";
  74.                         post = " ";
  75.                         endString = "<br>";
  76.                         break;
  77.                 }
  78.                 s = "";
  79.                 if (typeof(summary.headertext) == "string") {
  80.                     s += summary.headertext + headerSep;
  81.                 }
  82.                 s += first;
  83.  
  84.                 //start changed code
  85.                 var errorMessages = Fev_GetInvalidValidatorErrorMessages();
  86.                 for (i = 0; i < errorMessages.length; i++)
  87.                 {
  88.                     s += pre + errorMessages[i] + post;
  89.                 }   
  90.                 //end changed code
  91.  
  92.                 s += endString;
  93.                 summary.innerHTML = s; 
  94.                 window.scrollTo(0,0);
  95.             }
  96.             if (summary.showmessagebox == "True") {
  97.                 s = "";
  98.                 if (typeof(summary.headertext) == "string") {
  99.                     s += summary.headertext + "<BR>";
  100.                 }
  101.                 
  102.                 //start changed code
  103.                 var errorMessages = Fev_GetInvalidValidatorErrorMessages();
  104.                 var pre, post;
  105.                 switch (summary.displaymode)
  106.                 {
  107.                 case "List":
  108.                     pre = '';
  109.                     post = '<BR>';
  110.                     break;
  111.                 case "BulletList":
  112.                 default: 
  113.                     pre = '  - ';
  114.                     post = '<BR>';
  115.                     break;
  116.                 case "SingleParagraph":
  117.                     pre = '';
  118.                     post = ' ';
  119.                     break;
  120.                 }
  121.                 for (i = 0; i < errorMessages.length; i++)
  122.                 {
  123.                     s += pre + errorMessages[i] + post;
  124.                 }
  125.                 //end changed code
  126.  
  127.                 span = document.createElement("SPAN");
  128.                 span.innerHTML = s;
  129.                 s = span.innerText;
  130.                 alert(s);
  131.             }
  132.         }
  133.     }
  134. }
  135.  
  136.  
  137. //
  138. // Validation constants
  139. //
  140. var FEV_CREDIT_CARD_TYPE_VISA = 'Visa';
  141. var FEV_CREDIT_CARD_TYPE_DISCOVER = 'Discover';
  142. var FEV_CREDIT_CARD_TYPE_MASTER_CARD = 'Master Card';
  143. var FEV_CREDIT_CARD_TYPE_AMERICAN_EXPRESS = 'American Express';
  144. var FEV_CREDIT_CARD_TYPE_ENROUTE = 'EnRoute';
  145. var FEV_CREDIT_CARD_TYPE_CARTE_BLANCHE = 'Carte Blanche';
  146. var FEV_CREDIT_CARD_TYPE_DINERS_CLUB = 'Diners Club';
  147. var FEV_CREDIT_CARD_TYPE_JCB = 'JCB';
  148. var FEV_CREDIT_CARD_TYPE_UNKNOWN = 'Unknown';
  149. var FEV_CREDIT_CARD_TYPE_INVALID = 'Invalid';
  150.  
  151. //
  152. // .NET Validator Control functions
  153. //
  154.  
  155. function Fev_ValidatorEvaluateIsValid(val)
  156. {
  157.     var control;
  158.     if (document && val && val.controltovalidate) {
  159.         control = document.getElementById(val.controltovalidate);
  160.         if (control) {
  161.             return CustomValidatorEvaluateIsValid(val);
  162.         }
  163.     }
  164.     return(true);
  165. }
  166.  
  167. function Fev_FieldValueValidatorEvaluateIsValid(objSource, objArguments) {
  168.     var innerValidatorId = objSource.id + '_InnerValidator';
  169.     var innerValidator = document.all[innerValidatorId];
  170.     if (innerValidator)
  171.     {
  172.         ValidatorValidate(innerValidator);
  173.         objArguments.IsValid = innerValidator.isvalid;
  174.     }
  175.     else
  176.     {
  177.         objArguments.IsValid = true;
  178.     }
  179. }
  180.  
  181. function Fev_BooleanValidatorEvaluateIsValid(objSource, objArguments) {
  182.     var value = objArguments.Value;
  183.     if (value == '') objArguments.IsValid = true;
  184.     else objArguments.IsValid = Fev_isValidBoolean(value);
  185. }
  186.  
  187. function Fev_PasswordValidatorEvaluateIsValid(objSource, objArguments) {
  188.     var value = objArguments.Value;
  189.     if (value == '') objArguments.IsValid = true;
  190.     else objArguments.IsValid = Fev_isValidPassword(value, objSource.MinLength, objSource.MaxLength);
  191. }
  192.  
  193. function Fev_UsaPhoneNumberValidatorEvaluateIsValid(objSource, objArguments) {
  194.     var value = objArguments.Value;
  195.     if (value == '') objArguments.IsValid = true;
  196.     else objArguments.IsValid = Fev_isValidUsaPhoneNumber(value);
  197. }
  198.  
  199. function Fev_CreditCardNumberValidatorEvaluateIsValid(objSource, objArguments)
  200. {
  201.     var value = objArguments.Value;
  202.     if (value == '') objArguments.IsValid = true;
  203.     else objArguments.IsValid = Fev_isValidCreditCardNumber(value, true);
  204. }
  205.  
  206. function Fev_CreditCardDateValidatorEvaluateIsValid(objSource, objArguments) {
  207.     var value = objArguments.Value;
  208.     if (value == '') objArguments.IsValid = true;
  209.     else objArguments.IsValid = Fev_isValidCreditCardDate(value);
  210. }
  211.  
  212. function Fev_NumberValidatorEvaluateIsValid(objSource, objArguments)
  213. {
  214.     var value = objArguments.Value;
  215.     if (value == '') objArguments.IsValid = true;
  216.     else objArguments.IsValid = Fev_isValidFloatUpToNDecimals(value, objSource.MaxDecimalPlaces, objSource.MinValue, objSource.MaxValue);
  217. }
  218.  
  219. function Fev_CountryValidatorEvaluateIsValid(objSource, objArguments) {
  220.     var value = objArguments.Value;
  221.     if (value == '') objArguments.IsValid = true;
  222.     else objArguments.IsValid = Fev_isValidCountry(value);
  223. }
  224.  
  225. function Fev_UsaStateValidatorEvaluateIsValid(objSource, objArguments) {
  226.     var value = objArguments.Value;
  227.     if (value == '') objArguments.IsValid = true;
  228.     else objArguments.IsValid = Fev_isValidUsaState(value);
  229. }
  230.  
  231. function Fev_UsaZipCodeValidatorEvaluateIsValid(objSource, objArguments) {
  232.     var value = objArguments.Value;
  233.     if (value == '') objArguments.IsValid = true;
  234.     else objArguments.IsValid = Fev_isValidUsaZipCode(value);
  235. }
  236.  
  237. function Fev_EmailValidatorEvaluateIsValid(objSource, objArguments) {
  238.     var value = objArguments.Value;
  239.     if (value == '') objArguments.IsValid = true;
  240.     else objArguments.IsValid = Fev_isValidEmailAddress(value);
  241. }
  242.  
  243. function Fev_UrlValidatorEvaluateIsValid(objSource, objArguments) {
  244.     var value = objArguments.Value;
  245.     if (value == '') objArguments.IsValid = true;
  246.     else objArguments.IsValid = Fev_isValidUrl(value);
  247. }
  248.  
  249. function Fev_PercentageValidatorEvaluateIsValid(objSource, objArguments)
  250. {
  251.     var value = objArguments.Value;
  252.     if (value == '') objArguments.IsValid = true;
  253.     else objArguments.IsValid = Fev_isValidPercentage(value, objSource.MaxDecimalPlaces, objSource.MinValue, objSource.MaxValue);
  254. }
  255.  
  256. function Fev_CurrencyValidatorEvaluateIsValid(objSource, objArguments)
  257. {
  258.     var value = objArguments.Value;
  259.     if (value == '') objArguments.IsValid = true;
  260.     else objArguments.IsValid = Fev_isValidCurrency(value, objSource.MaxDecimalPlaces, objSource.MinValue, objSource.MaxValue);
  261. }
  262.  
  263. function Fev_ImageValidatorEvaluateIsValid(objSource, objArguments) {
  264.     var value = objArguments.Value;
  265.     if (value == '') objArguments.IsValid = true;
  266.     else objArguments.IsValid = Fev_isValidImagePath(value);
  267. }
  268.  
  269. function Fev_FileValidatorEvaluateIsValid(objSource, objArguments) {
  270.     var value = objArguments.Value;
  271.     if (value == '') objArguments.IsValid = true;
  272.     else objArguments.IsValid = Fev_isValidWindowsFileName(value);
  273. }
  274.  
  275. function Fev_DateTimeValidatorEvaluateIsValid(objSource, objArguments) {
  276.     var value = objArguments.Value;
  277.     if (value == '') objArguments.IsValid = true;
  278.     else objArguments.IsValid = Fev_isValidUsaDate_digits(value, objSource.AllowTime);
  279. }
  280.  
  281. function Fev_ShortDateValidatorEvaluateIsValid(objSource, objArguments) {
  282.     var value = objArguments.Value;
  283.     if (value == '') objArguments.IsValid = true;
  284.     else objArguments.IsValid = Fev_isValidUsaDate_digits(value, false);
  285. }
  286.  
  287. function Fev_TextBoxMaxLengthValidatorEvaluateIsValid(objSource, objArguments) {
  288.     var ctv = Fev_GetControlToValidate(objSource);
  289.     var value = objArguments.Value;
  290.     if (value == '') objArguments.IsValid = true;
  291.     else if (ctv && ctv.MaxLength)
  292.         objArguments.IsValid = !((ctv.MaxLength > 0) && (ctv.MaxLength < value.length));
  293.     else objArguments.IsValid = true;
  294. }
  295.  
  296.  
  297. //
  298. // Utility functions
  299. //
  300.  
  301.  
  302. function Fev_GetControlToValidate(validator) {
  303.     if (validator && validator.controltovalidate)
  304.         return Fev_GetControlToValidateById(validator.controltovalidate); 
  305.     return null;
  306. }
  307.  
  308. function Fev_GetControlToValidateById(id) {
  309.     var control;
  310.     control = document.all[id];
  311.     if (typeof(control.value) == "string") {
  312.         return control;
  313.     }
  314.     if (typeof(control.tagName) == "undefined" && typeof(control.length) == "number") {
  315.         var j;
  316.         for (j=0; j < control.length; j++) {
  317.             var inner = control[j];
  318.             if (typeof(inner.value) == "string" && (inner.type != "radio" || inner.status == true)) {
  319.                 return inner;
  320.             }
  321.         }
  322.     }
  323.     else {
  324.         return Fev_GetControlToValidateRecursive(control);
  325.     }
  326.     return "";
  327. }
  328.  
  329. function Fev_GetControlToValidateRecursive(control)
  330. {
  331.     if (typeof(control.value) == "string" && (control.type != "radio" || control.status == true)) {
  332.         return control;
  333.     }
  334.     var i;
  335.     for (i = 0; i < control.children.length; i++) {
  336.         var child = Fev_GetControlToValidateRecursive(control.children[i]);
  337.         if (child != null) return child;
  338.     }
  339.     return null;
  340. }
  341.  
  342.  
  343. //TODO: Test
  344. //function removes non-digit characters, and returns the string
  345. function Fev_RemoveNonDigits(str)
  346. {
  347.     if (str == null || str.length < 1)
  348.         return '';
  349.  
  350.     var i;
  351.     var currentChar;
  352.     for (i = 0; i < str.length; i++) {
  353.         currentChar = str.charAt(i);
  354.  
  355.         currentChar = parseInt(currentChar, 10);
  356.         if (isNaN(currentChar)) {
  357.             if (i == 0) {                    //1st char
  358.                 if (str.length > 1) {
  359.                     str = str.substring(1);
  360.                 } else {
  361.                     str = '';
  362.                 }
  363.             } else if (i == str.length-1) {    //last char
  364.                 str = str.substring(0, str.length-1);
  365.             } else {                        //somewhere in the middle
  366.                 str = str.substring(0, i) + str.substring(i+1, str.length);
  367.             }
  368.             i--;
  369.         }
  370.     }
  371.     return str;
  372. }
  373.  
  374.  
  375. //==================================================================
  376. //Fev_StrReplace(original string, find string to replace, string that replaces, isCaseSensitive, numTimes) : Returns a copy of a string after replacement.
  377. //    loops (replaces) numTimes times, or as long as the string is found (when numTimes = -1)
  378. //  isCaseSensitive: true (case matters), false (case doesn't matter)
  379. //==================================================================
  380. function Fev_StrReplace(originalStr, findStr, replaceWith, isCaseSensitive, numTimes)
  381. {
  382.     if (originalStr == null || originalStr == "" || findStr == null || findStr == "")
  383.         return originalStr;
  384.     if (findStr == replaceWith)
  385.         return originalStr;
  386.  
  387.     numTimes = parseInt(numTimes, 10);
  388.     if (isNaN(numTimes) || numTimes == 0)
  389.         return originalStr;
  390.     var isInfinite = (numTimes < 0);
  391.  
  392.     var findStrLen = findStr.length;
  393.     var tempStr = originalStr;
  394.     var myCounter = 0;
  395.  
  396.     var TEMP_PLACEHOLDER = 'á';
  397.  
  398.     if (findStr.indexOf(TEMP_PLACEHOLDER) >= 0)
  399.         return originalStr;
  400.  
  401.     var index;
  402.     if (isCaseSensitive) {
  403.         index = tempStr.indexOf(findStr);
  404.     } else {
  405.         index = tempStr.toUpperCase().indexOf(findStr.toUpperCase());
  406.     }
  407.  
  408.     while (index >= 0 && (isInfinite || myCounter < numTimes)) {
  409.         if (index == tempStr.length - findStrLen) {
  410.             tempStr = tempStr.substring(0, tempStr.length - findStrLen) + TEMP_PLACEHOLDER;
  411.         } else if (index == 0) {
  412.             tempStr = TEMP_PLACEHOLDER + tempStr.substring(findStrLen);
  413.         } else {
  414.             tempStr = tempStr.substring(0, index) + TEMP_PLACEHOLDER + tempStr.substring(index + findStrLen);
  415.         }
  416.  
  417.         if (isCaseSensitive) {
  418.             index = tempStr.indexOf(findStr);
  419.         } else {
  420.             index = tempStr.toUpperCase().indexOf(findStr.toUpperCase());
  421.         }
  422.         myCounter++;
  423.     }
  424.  
  425.     index = tempStr.indexOf(TEMP_PLACEHOLDER);
  426.     findStrLen = TEMP_PLACEHOLDER.length;
  427.  
  428.     while (index >= 0 && (isInfinite || myCounter > 0)) {
  429.         if (index == tempStr.length - findStrLen) {
  430.             tempStr = tempStr.substring(0, tempStr.length - findStrLen) + replaceWith;
  431.         } else if (index == 0) {
  432.             tempStr = replaceWith + tempStr.substring(findStrLen);
  433.         } else {
  434.             tempStr = tempStr.substring(0, index) + replaceWith + tempStr.substring(index + findStrLen);
  435.         }
  436.  
  437.         index = tempStr.indexOf(TEMP_PLACEHOLDER);
  438.         myCounter--;
  439.     }
  440.     return tempStr;
  441. }
  442.  
  443. function Fev_Trim(str)
  444. {
  445.     if (str == null) return null;
  446.     var m = str.match(/^\s*(\S+(\s+\S+)*)\s*$/);
  447.     return (m == null) ? "" : m[1];
  448. }
  449.  
  450. //
  451. // Validation functions
  452. // Note: All Fev_isValid* functions always return true or false (they never throw errors).
  453. //
  454.  
  455. function Fev_isValidCreditCardNumber(strCreditCardNumber, bIgnoreNonDigits)
  456. {
  457.     if ((strCreditCardNumber == null) || (strCreditCardNumber == ''))
  458.         return false;
  459.  
  460.     var strDigits = Fev_RemoveNonDigits(strCreditCardNumber);
  461.  
  462.     if ((!bIgnoreNonDigits) && (strDigits != strCreditCardNumber))
  463.         return false;
  464.     if ((strDigits == null) || (strDigits == ''))
  465.         return false;
  466.     if ((strDigits.length < 4) || (strDigits.length > 19))
  467.         return false;
  468.  
  469.     var strCardType = Fev_ParseCreditCardNumberPrefix(strDigits, true);
  470.  
  471.     //Validate the card number's length and type
  472.     switch (strCardType)
  473.     {
  474.     case FEV_CREDIT_CARD_TYPE_VISA:
  475.         if ((strDigits.length != 16) && (strDigits.length != 13)) return false;
  476.         break;
  477.     case FEV_CREDIT_CARD_TYPE_DISCOVER:
  478.     case FEV_CREDIT_CARD_TYPE_MASTER_CARD:
  479.         if (strDigits.length != 16) return false;
  480.         break;
  481.     case FEV_CREDIT_CARD_TYPE_AMERICAN_EXPRESS:
  482.     case FEV_CREDIT_CARD_TYPE_ENROUTE:
  483.         if (strDigits.length != 15) return false;
  484.         break;
  485.     case FEV_CREDIT_CARD_TYPE_CARTE_BLANCHE:
  486.     case FEV_CREDIT_CARD_TYPE_DINERS_CLUB:
  487.         if (strDigits.length != 14) return false;
  488.         break;
  489.     case FEV_CREDIT_CARD_TYPE_JCB:
  490.         if ((strDigits.charAt(0) == 3) && (strDigits.length != 16)) return false;
  491.         else if ((strDigits.charAt(0) != 3) && (strDigits.length != 15)) return false;
  492.         break;
  493.     case FEV_CREDIT_CARD_TYPE_UNKNOWN:
  494.     case FEV_CREDIT_CARD_TYPE_INVALID:
  495.     default:
  496.         return false;
  497.     }
  498.  
  499.     //Validate the card number's Luhn checksum
  500.     switch (strCardType)
  501.     {
  502.     case FEV_CREDIT_CARD_TYPE_ENROUTE:
  503.         //EnRoute cards can have any Checksum
  504.         break;
  505.     default:
  506.         if (Fev_ComputeLuhnChecksum(strDigits) != 0) return false;
  507.         break;
  508.     }
  509.  
  510.     return true;
  511. }
  512.  
  513. //TODO: TEST
  514. //Valid time format: hh:mm:ss <am|pm>
  515.  
  516. function Fev_isValidTimeAMPM(strTime) {
  517.     strTime = Fev_Trim(strTime);
  518.     if (strTime == null || strTime == '')
  519.         return false;
  520.  
  521.     var timeRE = new RegExp('^' + PATTERN_TIME_AMPM + '?$', 'i');
  522.     return timeRE.test(strTime);
  523. }
  524.  
  525. //TODO: TEST
  526. //Valid time format: hh:mm:ss
  527. //hh: from 0-23 or 00-23
  528. //mm: from 0-59 or 00-59
  529. //ss: from 0-59 or 00-59
  530. function Fev_isValidTime24HR(strTime) {
  531.     strTime = Fev_Trim(strTime);
  532.     if (strTime == null || strTime == '')
  533.         return false;
  534.  
  535.     var timeRE = new RegExp('^' + PATTERN_TIME_24HR + '?$', 'i');
  536.     return timeRE.test(strTime);
  537. }
  538.  
  539.  
  540. //TODO: TEST
  541. //valid USA date [digits - i.e. non alphabetic]:
  542. //[?1-12]/[?1-31]/([00-99]or [0000-9999]) hh:mm:ss[ ]?am/pm
  543. //i.e. month/day/year where
  544. //    month is either 1[january]-12[december], where ? means option ZERO, if under 10
  545. //    day is from 1 to 31, with optional ZERO if under 10.
  546. //    year is either 2 or 4 digits.
  547. //    dividers: slash, space or dash
  548. //hh: from 0-12 or 00-12 (where 0 = 12), or 0-24/00-24
  549. //mm: from 0-59 or 00-59
  550. //ss: from 0-59 or 00-59
  551. //am or pm is optional
  552. function Fev_isValidUsaDate_digits(strDate, isAllowTime)
  553. {
  554.     strDate = Fev_Trim(strDate);
  555.     if (strDate == null || strDate == '')
  556.         return false;
  557.  
  558.     var timePattern = "";
  559.     if (isAllowTime) {
  560.         timePattern += "([\ ](" + PATTERN_TIME_AMPM + "|" + PATTERN_TIME_24HR + "))?";
  561.     }
  562.  
  563.     var dateArray = new Array('^(([0]?[1-9])|10|11|12)', '(([0]?[0-9])|([1-2][0-9])|30|31)', '(([0-9]{4})|([0-9]{2}))' + timePattern + '$');
  564.  
  565.     var separatorArray = new Array('\ ', '/', '-');
  566.  
  567.     var separator;
  568.     var i;
  569.     var found = false;
  570.     var RE;
  571.     for (i = 0; i < separatorArray.length && !found; i++) {
  572.         RE = new RegExp(dateArray.join(separatorArray[i]), 'i');
  573.         if (RE.test(strDate)) {
  574.             found = true;
  575.             separator = separatorArray[i];
  576.         }
  577.     }
  578.     if (!found) return false;
  579.  
  580.     var dateArr = strDate.split(separator);
  581.     var month = parseInt(dateArr[0], 10);
  582.     var day = parseInt(dateArr[1], 10);
  583.     var year = parseInt(dateArr[2], 10);
  584.  
  585.     year = Fev_NormalizeYear(year);
  586.  
  587.     var highestDayOfMonth = Fev_GetHighestDayOfMonth(month, year);
  588.     return (day >= 1 && day <= highestDayOfMonth);
  589. }
  590.  
  591.  
  592. //TODO: Test
  593. //valid USA date [alphanumeric]:
  594. //([jan-dec][.]? or [january-december])/[?1-31]/([00-99]or [0000-9999])
  595. //i.e. month/day/year where
  596. //    month is either january-december, or jan-dec or jan.-dec. (notice abbreviation can have a PERIOD)
  597. //    day is from 1 to 31, with optional ZERO if under 10.
  598. //    year is either 2 or 4 digits.
  599. //    dividers: slash, space or dash
  600. //hh: from 0-12 or 00-12 (where 0 = 12), or 0-24/00-24
  601. //mm: from 0-59 or 00-59
  602. //ss: from 0-59 or 00-59
  603. //am or pm is optional
  604. function Fev_isValidUsaDate_monthinletters(strDate, isAllowTime)
  605. {
  606.     strDate = Fev_Trim(strDate);
  607.     if (strDate == null || strDate == '')
  608.         return false;
  609.  
  610.     var monthsStr = '';
  611.     var i;
  612.  
  613.     monthsStr += '(((';
  614.     for (i = 0; i < Fev_Get_Months_Short().length; i++) {
  615.         if (i > 0) {
  616.             monthsStr += '|';
  617.         }
  618.         monthsStr += Fev_Get_Months_Short()[i];
  619.     }
  620.     monthsStr += ')[\.]?)|';
  621.     for (i = 0; i < Fev_Get_Months_Long().length; i++) {
  622.         if (i > 0) {
  623.             monthsStr += '|';
  624.         }
  625.         monthsStr += Fev_Get_Months_Long()[i];
  626.     }
  627.     monthsStr += ')';
  628.  
  629.     var timePattern = "";
  630.     if (isAllowTime) {
  631.         timePattern += "([\ ](" + PATTERN_TIME_AMPM + "|" + PATTERN_TIME_24HR + "))?";
  632.     }
  633.  
  634.     var dateArray = new Array('^' + monthsStr + '[' , '\ ](([0]?[0-9])|([1-2][0-9])|30|31)([', ']|(,[\ ]?))(([0-9]{4})|([0-9]{2}))' + timePattern + '$');
  635.  
  636.     var separatorArray = new Array('\ ', '/', '-');
  637.  
  638.     var separator;
  639.     var i;
  640.     var found = false;
  641.     var RE;
  642.     for (i = 0; i < separatorArray.length && !found; i++) {
  643.         RE = new RegExp(dateArray.join(separatorArray[i]), 'i');
  644.         if (RE.test(strDate)) {
  645.             found = true;
  646.             separator = separatorArray[i];
  647.         }
  648.     }
  649.     if (!found) return false;
  650.  
  651.     var dateArr = strDate.split(separator);
  652.     var month = Fev_MonthStrToInt(dateArr[0]);
  653.     var day = parseInt(dateArr[1], 10);
  654.     var year = parseInt(dateArr[2], 10);
  655.  
  656.     year = Fev_NormalizeYear(year);
  657.  
  658.     var highestDayOfMonth = Fev_GetHighestDayOfMonth(month, year);
  659.     return (day >= 1 && day <= highestDayOfMonth);
  660. }
  661.  
  662.  
  663. //TODO: Test
  664. //valid: mm/yyyy  (where m can be 1 or 2 digits)
  665. function Fev_isValidCreditCardDate(strCreditCardDate)
  666. {
  667.     var separatorArray = new Array('\ ', '/', '-');
  668.  
  669.     var ccDateArray = new Array('^(([0]?[1-9])|10|11|12)[', '][0-9]{4}$');
  670.  
  671.     var separator;
  672.     var i;
  673.     var found = false;
  674.     var RE;
  675.     for (i = 0; i < separatorArray.length && !found; i++) {
  676.         RE = new RegExp(ccDateArray.join(separatorArray[i]), 'i');
  677.         if (RE.test(strCreditCardDate)) {
  678.             found = true;
  679.             separator = separatorArray[i];
  680.         }
  681.     }
  682.     if (!found) return false;
  683.     return true;
  684. }
  685.  
  686. //TODO: Test    (testing function is in Testing section)
  687. //valid numbers:
  688. // - without commas:    zero
  689. //                        <optional minus>(1st digit is non-zero)[unlimited number of digits]
  690. // - with commas:    zero
  691. //                    <optional minus>(non-zero digit)<0or1or2 digits><(comma)(3 digits)>*
  692. //  also can have unlimited # of leading zero's (in the whole part of the number)
  693. //  also can have unlimited # of trailing zero's in the decimal portion
  694. function Fev_isValidInteger(strInteger, minValue, maxValue)
  695. {
  696.     strInteger = Fev_Trim(strInteger);
  697.     if (strInteger == null || strInteger == '')
  698.         return false;
  699.  
  700.     return Fev_isValidFloatUpToNDecimals(strInteger, 0, minValue, maxValue);
  701. //    var integerRE = new RegExp('^(([-]?[1-9][0-9]*)|[0])$');    //without commas
  702. //    var integerWithCommaRE = new RegExp('^(([-]?[1-9][0-9]{0,2}(,[0-9]{3})*)|0)$');    //with commas
  703. //    return integerRE.test(strInteger) || integerWithCommaRE.test(strInteger);
  704. }
  705.  
  706. //TODO: Test
  707. //same format as Fev_isValidInteger, in addition to:
  708. //    + <(decimal point)(unlimited number of digits)>
  709. //  also can have unlimited # of leading zero's (in the whole part of the number)
  710. //  also can have unlimited # of trailing zero's in the decimal portion
  711. function Fev_isValidFloat(strFloat, minValue, maxValue) {
  712.     return Fev_isValidFloatUpToNDecimals(strFloat, -1, minValue, maxValue);
  713. }
  714.  
  715. //TODO: Test
  716. //called by Fev_isValidFloat.
  717. //can specify the max number of allowed decimal digits
  718. //can specify min value
  719. //can specify max value
  720. //  where a non positive number is unlimited, and any positive number is used as max num of decimal digits
  721. //  also can have unlimited # of leading zero's (in the whole part of the number)
  722. //  also can have unlimited # of trailing zero's in the decimal portion
  723. function Fev_isValidFloatUpToNDecimals(strFloat, maxDecimalDigits, minValue, maxValue)
  724. {
  725.     if (maxDecimalDigits == null || maxDecimalDigits == '')
  726.         maxDecimalDigits = -1;
  727.     minValue = Fev_Trim(minValue);
  728.     maxValue = Fev_Trim(maxValue);
  729.  
  730.     strFloat = Fev_Trim(strFloat);
  731.     if (strFloat == null || strFloat == '')
  732.         return false;
  733.  
  734.     var decStr = "";
  735.     if (isNaN(maxDecimalDigits) || (maxDecimalDigits < 0)) {
  736.         decStr += "[\.][0-9]*";
  737.     } else if (maxDecimalDigits == 0) {
  738.         decStr += "[\.][0]*";
  739.     } else {
  740.         decStr += "[\.][0-9]{0," + parseInt(maxDecimalDigits, 10) + "}0*";
  741.     }
  742.  
  743.     var floatRE = new RegExp('^(([-]?[0]*[0-9]*))(' + decStr + ')?$');    //without commas
  744.     var floatWithCommaRE = new RegExp('^([-]?[0-9]{1,3}(,[0-9]{3})*)(' + decStr + ')?$');    //with commas
  745.  
  746.     if (!(floatRE.test(strFloat) || floatWithCommaRE.test(strFloat))) {
  747.         return false;
  748.     }
  749.  
  750.     var myNum = parseFloat(Fev_StrReplace(strFloat, ",", "", false, -1));
  751.  
  752.     if (!isNaN(minValue)) {
  753.         minValue = parseInt(minValue, 10);
  754.         if (myNum < minValue) {
  755.             return false;
  756.         }
  757.     }
  758.     if (!isNaN(maxValue)) {
  759.         maxValue = parseInt(maxValue, 10);
  760.         if (myNum > maxValue) {
  761.             return false;
  762.         }
  763.     }
  764.  
  765.     return true;
  766. }
  767.  
  768. //TODO: TEST
  769. function Fev_isValidCurrency(strCurrency, numDecimals, minValue, maxValue) {
  770.     // Currency validation is handled by the Parse routine in the VB or CS code to ensure that all international currency formats are supported properly.
  771.     return true;    
  772.  
  773.     strCurrency = Fev_Trim(strCurrency);
  774.     if (strCurrency == null || strCurrency == '')
  775.         return false;
  776.  
  777.     var moneyRE = new RegExp('^([\$])?[\-]?([\$])?([0-9]*[\.]?[0-9]*)$');
  778.     var moneyWithParenthesesRE = new RegExp('^([\$])?[\(]([\$])?([0-9]*[\.]?[0-9]*)([\$])?[\)]([\$])?$');
  779.  
  780.     if (moneyRE.test(strCurrency)) {
  781.         var myArr = strCurrency.match(moneyRE);
  782.  
  783.         if (myArr == null)
  784.             return false;
  785.  
  786.         if (myArr.length > 3) {
  787.             //make sure only one $ sign
  788.             if ((myArr[1] + myArr[2]).length > 1) {
  789.                 return false;
  790.             }
  791.             return Fev_isValidFloatUpToNDecimals(myArr[3], numDecimals, minValue, maxValue);
  792.         }
  793.     } else if (moneyWithParenthesesRE.test(strCurrency)) {
  794.         var myArr = strCurrency.match(moneyWithParenthesesRE);
  795.         if (myArr == null)
  796.             return false;
  797.  
  798.         if (myArr.length > 5) {
  799.             //make sure only one $ sign
  800.             if ((myArr[1] + myArr[2] + myArr[4] + myArr[5]).length > 1) {
  801.                 return false;
  802.             }
  803.             return Fev_isValidFloatUpToNDecimals(myArr[3], numDecimals, minValue, maxValue);
  804.         }
  805.     }
  806.  
  807.     return false;
  808. }
  809.  
  810. //TODO: TEST
  811. function Fev_isValidPercentage(strPercentage, numDecimals, minValue, maxValue) {
  812.     strPercentage = Fev_Trim(strPercentage);
  813.     if (strPercentage == null || strPercentage == '')
  814.         return false;
  815.  
  816.     var percentageRE = new RegExp('^[\-]?([0-9]*[\.]?[0-9]*)[\%]?$');
  817.  
  818.     if (percentageRE.test(strPercentage)) {
  819.         var myArr = strPercentage.match(percentageRE);
  820.  
  821.         if (myArr == null)
  822.             return false;
  823.  
  824.         if (myArr.length > 1) {
  825.             return Fev_isValidFloatUpToNDecimals(myArr[1], numDecimals, minValue, maxValue);
  826.         }
  827.     }
  828.  
  829.     return false;
  830. }
  831.  
  832.  
  833. //TODO: Test
  834. function Fev_isValidEmailAddress(strEmailAddress)
  835. {
  836.     return true; //function is too strict. see http://www.aspemporium.com/aspEmporium/tutorials/emailvalidation.asp
  837.  
  838.     if (bShowAlerts)
  839.         checkTLD = 1;
  840.     else
  841.         checkTLD = 0;
  842.  
  843.     /* The following pattern is used to check if the entered e-mail address
  844.     fits the user@domain format.  It also is used to separate the username
  845.     from the domain. */
  846.  
  847.     var emailPat=/^(.+)@(.+)$/;
  848.  
  849.     /* The following pattern applies if the "user" is a quoted string (in
  850.     which case, there are no rules about which characters are allowed
  851.     and which aren't; anything goes).  E.g. "jiminy cricket"@disney.com
  852.     is a legal e-mail address. */
  853.  
  854.     var quotedUser="(\"[^\"]*\")";
  855.  
  856.     /* The following string represents one word in the typical username.
  857.     For example, in john.doe@somewhere.com, john and doe are words.
  858.     Basically, a word is either an atom or quoted string. */
  859.  
  860.     var word = "(" + atom + "|" + quotedUser + ")";
  861.  
  862.     // The following pattern describes the structure of the user
  863.  
  864.     var userPat = new RegExp("^" + word + "(\\." + word + ")*$");
  865.  
  866.     /* Finally, let's start trying to figure out if the supplied address is valid. */
  867.  
  868.     /* Begin with the coarse pattern to simply break up user@domain into
  869.     different pieces that are easy to analyze. */
  870.  
  871.     var matchArray=strEmailAddress.match(emailPat);
  872.  
  873.     if (matchArray==null) {
  874.         /* Too many/few @'s or something; basically, this address doesn't
  875.         even fit the general mould of a valid e-mail address. */
  876.  
  877.         if (bShowAlerts) alert("Email address seems incorrect (check @ and .'s)");
  878.         return false;
  879.     }
  880.     var strUser = matchArray[1];
  881.     var strDomain = matchArray[2];
  882.  
  883.     // Start by checking that only basic ASCII characters are in the strings (0-127).
  884.  
  885.     for (i=0; i<strUser.length; i++) {
  886.         if (strUser.charCodeAt(i)>127) {
  887.             if (bShowAlerts) alert("Ths username contains invalid characters.");
  888.             return false;
  889.        }
  890.     }
  891.     for (i = 0; i < strDomain.length; i++) {
  892.         if (strDomain.charCodeAt(i)>127) {
  893.             if (bShowAlerts) alert("Ths domain name contains invalid characters.");
  894.             return false;
  895.         }
  896.     }
  897.  
  898.     // See if "user" is valid 
  899.  
  900.     if (strUser.match(userPat)==null) {
  901.         // user is not valid
  902.         if (bShowAlerts) alert("The username doesn't seem to be valid.");
  903.         return false;
  904.     }
  905.  
  906.     return Fev_isIsReallyAValidDomain(strDomain);
  907. }
  908.  
  909. //TODO: Test
  910. function Fev_isValidUrl(strUrl)
  911. {
  912.     var myUrlDataArr = Fev_ParseUrl(strUrl);
  913.     if (myUrlDataArr == null) {
  914.         myUrlDataArr = Fev_ParseUrl("http://" + strUrl);
  915.     }
  916.  
  917.     if (myUrlDataArr == null) {
  918.         return false;
  919.     } else {
  920.         return true;
  921.     }
  922. }
  923.  
  924. //TODO: TEST
  925. //valid boolean values: 'T' for True, 'F' for False.
  926. //that's it, that's all
  927. function Fev_isValidBoolean(strBoolean) {
  928.     return true; //disabled, because it does not handle display string values.
  929.     strBoolean = Fev_Trim(strBoolean);
  930.     if (strBoolean == null || strBoolean.length == '')
  931.         return false;
  932.  
  933.     return (strBoolean == 'T' || strBoolean == 'F');
  934. }
  935.  
  936. //TODO: TEST
  937. function Fev_isValidPassword(strPassword, minLength, maxLength) {
  938.     strPassword = Fev_Trim(strPassword);
  939.     if (strPassword == null || strPassword.length < minLength)
  940.         return false;
  941.  
  942.     if (isNaN(minLength)) {
  943.         minLength = 0;
  944.     } else {
  945.         minLength = parseInt(minLength);
  946.         if (minLength < 0) {
  947.             minLength = 0;
  948.         }
  949.     }
  950.  
  951.     if (isNaN(maxLength)) {
  952.         maxLength = null;
  953.     } else {
  954.         maxLength = parseInt(maxLength);
  955.         if (maxLength < minLength) {    //if maxLength < minLength, then don't even bother checking if the password is too long
  956.             maxLength = null;
  957.         }
  958.     }
  959.  
  960.     if (strPassword.length < minLength)
  961.         return false;
  962.  
  963.     if (maxLength != null && strPassword.length > maxLength)
  964.         return false;
  965.  
  966.     return true;
  967. }
  968.  
  969. //TODO: TEST
  970. //valid phone number formats:
  971. //(ddd)<space or separator>ddd<separator>dddd<(ext<.> or x)<space>(1-5 digits)>
  972. //    note:    opening+closing parentheses come together, and are optional
  973. //            separator is either 'space', '.' or '-'... and try to match only by one kind of separator at a time
  974. //                    e.g. 333-333-3333 or (222).333.4556 or 333 333 3333 are all three OK, but 444-333.3333 is NOT
  975. function Fev_isValidUsaPhoneNumber(strUsaPhoneNumber)
  976. {
  977.     strUsaPhoneNumber = Fev_Trim(strUsaPhoneNumber);
  978.     if (strUsaPhoneNumber == null || strUsaPhoneNumber == '')
  979.         return false;
  980.     var myREasArray = new Array('^((([0-9]{3})|[\(][0-9]{3}[\)])[', '\ ]?)?[0-9]{3}[', ']?[0-9]{4}([\ ]((ext)[\.]?|(x))[\ ]?[0-9]{1,5})?$');
  981.     //var phoneRE = new RegExp('^(([0-9]{3})|[\(][0-9]{3}[\)])[-\.\ ]?[0-9]{3}[-\.\ ]?[0-9]{4}$');
  982.     var phoneRE_dash = new RegExp(myREasArray.join("-"), "i");
  983.     var phoneRE_period = new RegExp(myREasArray.join("\."), "i");
  984.     var phoneRE_space = new RegExp(myREasArray.join("\ "), "i");
  985.     return (phoneRE_dash.test(strUsaPhoneNumber) || phoneRE_period.test(strUsaPhoneNumber) || phoneRE_space.test(strUsaPhoneNumber));
  986. }
  987.  
  988. //TODO: TEST
  989. //valid country format: a-z, dash, space, apostrophe, period, opening parenthesis closing parenthesis
  990. function Fev_isValidCountry(strCountry) {
  991.     strCountry = Fev_Trim(strCountry);
  992.     if (strCountry == null || strCountry == '')
  993.         return false;
  994.     var re = new RegExp("^([a-z\-\ \'\.\(\)])*$", 'i');
  995.  
  996.     return re.test(strCountry);
  997. }
  998.  
  999.  
  1000. //TODO: TEST
  1001. //valid state format: 2-letter abbreviation (e.g. "CA" for California) full name (e.g. "Arkansas", "New York")
  1002. function Fev_isValidUsaState(strUsaState)
  1003. {
  1004.     strUsaState = Fev_Trim(strUsaState);
  1005.     if (strUsaState == null || strUsaState == '')
  1006.         return false;
  1007.  
  1008.     var stateAbbrevRE = new RegExp('^(al|ak|az|ar|ca|co|ct|dc|de|fl|ga|hi|id|il|in|ia|ks|ky|la|me|md|ma|mi|mn|ms|mo|mt|ne|nv|nh|nj|nm|ny|nc|nd|oh|ok|or|pa|ri|sc|sd|tn|tx|ut|vt|va|wa|wv|wi|wy)$', 'i');
  1009.     var stateFullRE = new RegExp('^(alabama|alaska|arizona|arkansas|california|colorado|connecticut|delaware|florida|georgia|hawaii|idaho|illinois|indiana|iowa|kansas|kentucky|louisiana|maine|maryland|massachusetts|michigan|minnesota|mississippi|missouri|montana|nebraska|nevada|new hampshire|new jersey|new mexico|new york|north carolina|north dakota|ohio|oklahoma|oregon|pennsylvania|rhode island|south carolina|south dakota|tennessee|texas|utah|vermont|virginia|washington|(washington((,[\ ]?)|[\ ])((district of columbia)|(d[\.]?c[\.]?)))|west virginia|wisconsin|wyoming)$', 'i');
  1010.  
  1011.     return stateAbbrevRE.test(strUsaState) || stateFullRE.test(strUsaState);
  1012. }
  1013.  
  1014. //TODO: TEST
  1015. //valid zip code formats: ddddd, ddddd-dddd
  1016. function Fev_isValidUsaZipCode(strUsaZipCode) {
  1017.     strUsaZipCode = Fev_Trim(strUsaZipCode);
  1018.     if (strUsaZipCode == null || strUsaZipCode == '')
  1019.         return false;
  1020.     var zipRE = new RegExp('^[0-9]{5}([- ]?[0-9]{4})?$')
  1021.     return zipRE.test(strUsaZipCode);
  1022. }
  1023.  
  1024.  
  1025. //TODO: TEST
  1026. //valid filename: any character other than: backslash, slash, colon, asterisk (*), questionmark, double-quote, >, <, vertical bar (|)
  1027. //ends with jpg|jpe|jpeg|gif|bmp|png
  1028. function Fev_isValidImagePath(strPath) {
  1029.     strPath = Fev_Trim(strPath);
  1030.     if (strPath == null || strPath == '')
  1031.         return false;
  1032.     var imagePathRE = new RegExp('[\.](jpg|jpe|jpeg|gif|bmp|png)$', 'i');
  1033.     return imagePathRE.test(strPath) && Fev_isValidWindowsFileName(strPath);
  1034. }
  1035.  
  1036. //TODO: TEST
  1037. //[drive]:[\(dir)]*[\(dir|filename)]{0,1}
  1038. function Fev_isValidWindowsFilePath(strPath) {
  1039.     strPath = Fev_Trim(strPath);
  1040.     if (strPath == null || strPath == '')
  1041.         return false;
  1042.     var filePathRE = new RegExp('^[a-z][\:]([\\\\][^\\\/\:\*\?\"\<\>\|]*)*$', 'i');
  1043.     return filePathRE.test(strPath);
  1044. }
  1045.  
  1046. //TODO: TEST
  1047. //valid filename: any character other than: backslash, slash, colon, asterisk (*), questionmark, double-quote, >, <, vertical bar (|)
  1048. function Fev_isValidWindowsFileName(strFilename) {
  1049.     strFilename = Fev_Trim(strFilename);
  1050.     if (strFilename == null || strFilename == '')
  1051.         return false;
  1052.     if (strFilename.indexOf("\\") >= 0)
  1053.         return false;
  1054.     var filePathRE = new RegExp('^[^\\\/\:\*\?\"\<\>\|]*$', 'i');
  1055.     return filePathRE.test(strFilename);
  1056. }
  1057.  
  1058.  
  1059. //
  1060. // Helper Variables
  1061. //
  1062.  
  1063. //private variables, should not be called except by Fev_Get_Months_Long, and Fev_Get_Months_Short
  1064. var PATTERN_TIME_AMPM = '(([0]?[0-9])|10|11|12)[\:]([0-5]?[0-9])[\:]([0-5]?[0-9])([\ ]?(AM|PM))';
  1065. var PATTERN_TIME_24HR = '(([0-1]?[0-9])|20|21|22|23)[\:]([0-5]?[0-9])[\:]([0-5]?[0-9])';
  1066.  
  1067. var Fev_MONTHS_LONG = null;
  1068. var Fev_MONTHS_SHORT = null;
  1069.  
  1070. /* The following variable tells the rest of the function whether or not
  1071. to display alerts that specify why the value is invalid */
  1072.  
  1073. var bShowAlerts = false;
  1074.  
  1075. /* The following string represents the pattern for matching all special
  1076. characters.  We don't want to allow special characters in the address. 
  1077. These characters include ( ) < > @ , ; : \ " . [ ] */
  1078.  
  1079. var specialChars="\\(\\)><@,;:\\\\\\\"\\.\\[\\]";
  1080.  
  1081. /* The following string represents the range of characters allowed in a 
  1082. username or domainname.  It really states which chars aren't allowed.*/
  1083.  
  1084. var validChars="\[^\\s" + specialChars + "\]";
  1085.  
  1086. /* The following string represents an atom (basically a series of non-special characters.)
  1087. */
  1088.  
  1089. var atom=validChars + '+';
  1090.  
  1091. /* The following variable tells the rest of the function whether or not
  1092. to verify that the address ends in a two-letter country or well-known
  1093. TLD.  1 means check it, 0 means don't. */
  1094.  
  1095. var checkTLD = 0;
  1096.  
  1097.  
  1098.  
  1099. //
  1100. // Validation Helper functions
  1101. //
  1102.  
  1103. //This function returns an array containing the error message strings of 
  1104. //all invalid validators in the page.  Duplicates are ignored.
  1105. function Fev_GetInvalidValidatorErrorMessages()
  1106. {
  1107.     var i, j;
  1108.     var msgArray = new Array();
  1109.     if (!Page_IsValid)
  1110.     {
  1111.         for (i = 0; i < Page_Validators.length; i++)
  1112.         {
  1113.             if (!Page_Validators[i].isvalid && typeof(Page_Validators[i].errormessage) == "string")
  1114.             {
  1115.                 var msg = Page_Validators[i].errormessage;
  1116.                 var b = false;
  1117.                 for (j = 0; j < msgArray.length; j++)
  1118.                 {
  1119.                     if (msgArray[j] == msg)
  1120.                     {
  1121.                         b = true;
  1122.                         break;
  1123.                     }
  1124.                 }   
  1125.                 if (!b)
  1126.                 {
  1127.                     msgArray[msgArray.length] = msg;
  1128.                 }
  1129.             }
  1130.         }   
  1131.     }
  1132.     return msgArray;
  1133. }
  1134.  
  1135. //returns an int between 0 and 9 (inclusive)
  1136. function Fev_ComputeLuhnChecksum(strDigits) 
  1137. {
  1138.     strDigits = Fev_RemoveNonDigits(strDigits);
  1139.     var digit;
  1140.     var i;
  1141.     var sum = 0;
  1142.  
  1143.     for (i = strDigits.length - 2; i >= 0; i -= 2)
  1144.     {
  1145.         digit = parseInt(strDigits.charAt(i), 10);
  1146.         digit *= 2;
  1147.         sum += ((digit > 9) ? (digit - 9) : (digit));
  1148.     }
  1149.     for (i = strDigits.length - 1; i >= 0; i -= 2)
  1150.     {
  1151.         digit = parseInt(strDigits.charAt(i), 10);
  1152.         sum += digit;
  1153.     }
  1154.  
  1155.     return (sum % 10);
  1156. }
  1157.  
  1158. //Returns one of the Credit Card Type constants (FEV_CREDIT_CARD_TYPE_*)
  1159. function Fev_ParseCreditCardNumberPrefix(strCardNumber, bIgnoreNonDigits)
  1160. {
  1161.     //Card Types             Prefix            Width      Luhn Checksum        Example
  1162.     //American Express       34, 37            15         Mod 10 = 0           3400 0000 0000 009
  1163.     //Diners Club            300 to 305, 36    14         Mod 10 = 0           3000 0000 0000 04
  1164.     //Carte Blanche          38                14         Mod 10 = 0           3000 0000 0000 04
  1165.     //Discover               6011              16         Mod 10 = 0           6011 0000 0000 0004
  1166.     //EnRoute                2014, 2149        15         Any                  2014 0000 0000 009
  1167.     //JCB                    3                 16         Mod 10 = 0           3088 0000 0000 0009
  1168.     //JCB                    2131, 1800        15         Mod 10 = 0           
  1169.     //Master Card            51 to 55          16         Mod 10 = 0           5500 0000 0000 0004
  1170.     //Visa                   4                 13, 16     Mod 10 = 0           4111 1111 1111 1111
  1171.  
  1172.     if (bIgnoreNonDigits)
  1173.         strCardNumber = Fev_RemoveNonDigits(strCardNumber);
  1174.  
  1175.     if (strCardNumber.length < 4)
  1176.         return FEV_CREDIT_CARD_TYPE_INVALID;
  1177.     if (Fev_RemoveNonDigits(strCardNumber.substr(0, 4)).length < 4)
  1178.         return FEV_CREDIT_CARD_TYPE_INVALID;
  1179.  
  1180.     //Parse 1st 2 digits
  1181.     switch (parseInt(strCardNumber.substr(0, 2), 10))
  1182.     {
  1183.     case 51:
  1184.     case 52:
  1185.     case 53:
  1186.     case 54:
  1187.     case 55:
  1188.         return FEV_CREDIT_CARD_TYPE_MASTER_CARD;
  1189.     case 34:
  1190.     case 37:
  1191.         return FEV_CREDIT_CARD_TYPE_AMERICAN_EXPRESS;
  1192.     case 36:
  1193.         return FEV_CREDIT_CARD_TYPE_DINERS_CLUB;
  1194.     case 38:
  1195.         return FEV_CREDIT_CARD_TYPE_CARTE_BLANCHE;
  1196.     }
  1197.  
  1198.     //Parse 1st 4 digits
  1199.     switch (parseInt(strCardNumber.substr(0, 4), 10))
  1200.     {
  1201.     case 6011:
  1202.         return FEV_CREDIT_CARD_TYPE_DISCOVER;
  1203.     case 2014:
  1204.     case 2149:
  1205.         return FEV_CREDIT_CARD_TYPE_ENROUTE;
  1206.     case 2131:
  1207.     case 1800:
  1208.         return FEV_CREDIT_CARD_TYPE_JCB;
  1209.     }
  1210.  
  1211.     //Parse 1st 3 digits
  1212.     switch (parseInt(strCardNumber.substr(0, 3), 10))
  1213.     {
  1214.     case 300:
  1215.     case 301:
  1216.     case 302:
  1217.     case 303:
  1218.     case 304:
  1219.     case 305:
  1220.         return FEV_CREDIT_CARD_TYPE_DINERS_CLUB;
  1221.     }
  1222.  
  1223.     //Parse 1st digit
  1224.     switch (parseInt(strCardNumber.substr(0, 1), 10))
  1225.     {
  1226.     case 4:
  1227.         return FEV_CREDIT_CARD_TYPE_VISA;
  1228.     case 3:
  1229.         return FEV_CREDIT_CARD_TYPE_JCB;
  1230.     }
  1231.  
  1232.     return FEV_CREDIT_CARD_TYPE_UNKNOWN;
  1233. }
  1234.  
  1235. function Fev_Get_Months_Long() {
  1236.     if (Fev_MONTHS_LONG == null) {
  1237.         Fev_MONTHS_LONG = new Array('january','february','march','april','may','june','july','august','september','october','november','december');
  1238.     }
  1239.     return Fev_MONTHS_LONG;
  1240. }
  1241.  
  1242. function Fev_Get_Months_Short() {
  1243.     if (Fev_MONTHS_SHORT == null) {
  1244.         Fev_MONTHS_SHORT = new Array('jan','feb','mar','apr','may','jun','jul','aug','(sep[t]?)','oct','nov','dec');
  1245.     }
  1246.     return Fev_MONTHS_SHORT;
  1247. }
  1248.  
  1249. function Fev_MonthStrToInt(strMonth) {
  1250.     var INVALID_MONTH = -1;
  1251.     if (strMonth == null || strMonth == '')
  1252.         return INVALID_MONTH;
  1253.  
  1254.     strMonth = strMonth.toLowerCase();
  1255.     var i;
  1256.     for (i = 0; i < Fev_Get_Months_Long().length; i++) {
  1257.         if (strMonth == Fev_Get_Months_Long()[i] || strMonth == Fev_Get_Months_Short()[i] || strMonth == (Fev_Get_Months_Short()[i] + '.')) {
  1258.             return i+1;
  1259.         }
  1260.     }
  1261.  
  1262.     return -1;
  1263. }
  1264.  
  1265. function Fev_isValidMonth(month) {
  1266.     var myMonth = parseInt(month, 10);
  1267.     if (isNaN(myMonth)) {
  1268.         return false;
  1269.         //will need to support non numeric months
  1270.     } else {
  1271.         return (myMonth >= 1 && myMonth <= 12);
  1272.     }
  1273. }
  1274.  
  1275. function Fev_NormalizeYear(intYear) {
  1276.     if (intYear < 100) {
  1277.         if (intYear > 30) {
  1278.             intYear += 1900;
  1279.         } else {
  1280.             intYear += 2000;
  1281.         }
  1282.     }
  1283.     return intYear;
  1284. }
  1285.  
  1286. function Fev_GetHighestDayOfMonth(intMonth, intYear) {
  1287.     var isLeapYear = Fev_isLeapYear(intYear);
  1288.  
  1289.     var highestDayOfMonth = -1;
  1290.     switch (intMonth) {
  1291.         case 1:
  1292.         case 3:
  1293.         case 5:
  1294.         case 7:
  1295.         case 8:
  1296.         case 10:
  1297.         case 12:
  1298.             highestDayOfMonth = 31;
  1299.             break;
  1300.         case 4:
  1301.         case 6:
  1302.         case 9:
  1303.         case 11:
  1304.             highestDayOfMonth = 30;
  1305.             break;
  1306.         case 2:
  1307.             if (isLeapYear) {
  1308.                 highestDayOfMonth = 29;
  1309.             } else {
  1310.                 highestDayOfMonth = 28;
  1311.             }
  1312.             break;
  1313.         default:
  1314.             break;
  1315.     }
  1316.  
  1317.     return highestDayOfMonth;
  1318. }
  1319.  
  1320. function Fev_isLeapYear(strYear) {
  1321.     if ((strYear == null) || (strYear == ''))
  1322.         return false;
  1323.  
  1324.     var strYearFormat = new RegExp('^([0-9]{4}|[0-9]{2})');
  1325.  
  1326.     if (!strYearFormat.test(strYear))
  1327.         return false;
  1328.  
  1329.     var intYear = parseInt(strYear, 10);
  1330.  
  1331.     if (intYear % 400 == 0)
  1332.         return true;
  1333.     if (intYear % 100 == 0)
  1334.         return false;
  1335.     if (intYear % 4 == 0)
  1336.         return true;
  1337.  
  1338.     return false;
  1339. }
  1340.  
  1341. function Fev_ParseUrl(strUrl) {
  1342. //[a-zA-Z0-9]([\$-_\.\+][a-zA-Z0-9])*[a-zA-Z0-9]
  1343. //(http|https|ftp)://(<user>(:<password>)+[\@])+<host>(:<port>)+(/<url-path>)+
  1344.  
  1345.     var myStuffStr = "";
  1346.     var myStuffArr = null;
  1347.  
  1348. //    var urlRE = new RegExp('^(http|https|ftp)\://([0-9a-z]+([\.\-][0-9a-z]+)*)([/][0-9a-z]*)*$', 'i');
  1349.     var urlRE = new RegExp('^(http|https|ftp)\://(([^\/:]+)([\:]([^\/:]*))?\@)?([a-z0-9]([a-z0-9\-\.]+[a-z0-9])?)(:([0-9]{1,5}))?([/][^\/]*)*$', 'i');
  1350.  
  1351.     if (!urlRE.test(strUrl)) return myStuffArr;
  1352.  
  1353.     var myArr = strUrl.match(urlRE);
  1354.  
  1355.     var strProtocol, strHost, strPath, strPort, strUsername, strPassword;
  1356.  
  1357. //alert("test for " + strUrl + "...\ndoes it fit url pattern? = " + urlRE.test(strUrl));
  1358.  
  1359.     if (myArr != null) {
  1360.         var i = 0;
  1361.         for (i = 0; i < myArr.length; i++) {
  1362.             switch (i) {
  1363.                 case 1:
  1364.                     //myStuffStr += "protocol: ";
  1365.                     strProtocol = myArr[i];
  1366.                     break;
  1367.                 case 3:
  1368.                     //myStuffStr += "username: ";
  1369.                     strUsername = myArr[i];
  1370.                     break;
  1371.                 case 5:
  1372.                     //myStuffStr += "password: ";
  1373.                     strPassword = myArr[i];
  1374.                     break;
  1375.                 case 6:
  1376.                     //myStuffStr += "host: ";
  1377.                     strHost = myArr[i];
  1378.                     break;
  1379.                 case 9:
  1380.                     //myStuffStr += "port: ";
  1381.                     strPort = myArr[i];
  1382.                     break;
  1383.                 case 10:
  1384.                     //myStuffStr += "path: ";
  1385.                     strPath = myArr[i];
  1386.                     break;
  1387.                 default:
  1388.                     break;
  1389.             }
  1390.             //alert(myArr[i]);
  1391.         }
  1392.  
  1393.         if (Fev_isIsReallyAValidDomain(strHost)) {
  1394.             myStuffArr = new Array(7);
  1395.             myStuffArr[0] = strUrl;
  1396.             myStuffArr[1] = strProtocol;
  1397.             myStuffArr[2] = strHost;
  1398.             myStuffArr[3] = strPort;
  1399.             myStuffArr[4] = strPath;
  1400.             myStuffArr[5] = strUsername;
  1401.             myStuffArr[6] = strPassword;
  1402.         }
  1403.  
  1404.         myStuffStr += "url: " + strUrl + "\n";
  1405.         myStuffStr += "protocol: " + strProtocol + "\n";
  1406.         myStuffStr += "host: " + strHost + "\n";
  1407.         myStuffStr += "port: " + strPort + "\n";
  1408.         myStuffStr += "path: " + strPath + "\n";
  1409.         myStuffStr += "username: " + strUsername + "\n";
  1410.         myStuffStr += "password: " + strPassword;
  1411.     }
  1412.  
  1413.     //alert(myStuffStr);
  1414.     //alert(myStuffStr + "\n\n" + strHost + " is Valid domain?: " + Fev_isIsReallyAValidDomain(strHost));
  1415.  
  1416.     //alert(strHost + " is Valid domain?: " + Fev_isIsReallyAValidDomain(strHost));
  1417.     
  1418.     return myStuffArr;
  1419. }
  1420.  
  1421. function Fev_isIsReallyAValidDomain(strDomain) {
  1422.     if (Fev_isAQuadDomain(strDomain)) {
  1423.         return Fev_isValidIP(strDomain);
  1424.     } else {
  1425.         return Fev_isValidDomain(strDomain);
  1426.     }
  1427. }
  1428.  
  1429. // determines if a domain is in "ddd.ddd.ddd.ddd" format
  1430. function Fev_isAQuadDomain(strDomain) {
  1431.     var ipDomainPat= new RegExp('^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$');
  1432.  
  1433.     var IPArray = strDomain.match(ipDomainPat);
  1434.     return (IPArray != null);
  1435. }
  1436.  
  1437. //given a str, detemine if it's a valid IP address
  1438. function Fev_isValidIP(strDomain) {
  1439.     var ipDomainPat= new RegExp('^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$');
  1440.  
  1441.     var IPArray = strDomain.match(ipDomainPat);
  1442.     if (IPArray != null) {
  1443.         // this is an IP address
  1444.  
  1445.         for (var i=1; i<=4; i++) {
  1446.             if (IPArray[i] > 255) {
  1447.                 return false;
  1448.             }
  1449.         }
  1450.         return true;
  1451.     }
  1452.     return false;
  1453. }
  1454.  
  1455. //given a str, detemine if it's a valid domain name
  1456. function Fev_isValidDomain(strDomain) {
  1457.  
  1458.     /* The following pattern describes the structure of a normal symbolic
  1459.     domain, as opposed to ipDomainPat, shown above. */
  1460.  
  1461.     var domainPat = new RegExp("^" + atom + "(\\." + atom +")*$");
  1462.  
  1463.     // Domain is symbolic name.  Check if it's valid.
  1464.      
  1465.     var atomPat = new RegExp("^" + atom + "$");
  1466.     var domArr = strDomain.split(".");
  1467.     var len = domArr.length;
  1468.     for (i = 0; i < len; i++) {
  1469.         if (domArr[i].search(atomPat)==-1) {
  1470.             if (bShowAlerts) alert("The domain name does not seem to be valid.");
  1471.             return false;
  1472.         }
  1473.     }
  1474.  
  1475.     /* The following is the list of known TLDs that an e-mail address must end with. */
  1476.     var knownDomsPat=/^(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum)$/;
  1477.  
  1478.     /* domain name seems valid, but now make sure that it ends in a
  1479.     known top-level domain (like com, edu, gov) or a two-letter word,
  1480.     representing country (uk, nl), and that there's a hostname preceding 
  1481.     the domain or country. */
  1482.  
  1483.     if (checkTLD && domArr[domArr.length-1].length!=2 && 
  1484.         domArr[domArr.length-1].search(knownDomsPat)==-1) {
  1485.             if (bShowAlerts)
  1486.                 alert("The address must end in a well-known domain or two letter " + "country.");
  1487.             return false;
  1488.     }
  1489.  
  1490.     // Make sure there's a host name preceding the domain.
  1491.     // this requires SOMETHING.TLD
  1492. //    if (len<2) {
  1493. //        if (bShowAlerts)
  1494. //            alert("This address is missing a hostname!");
  1495. //        return false;
  1496. //    }
  1497.  
  1498.     // If we've gotten this far, everything's valid!
  1499.     return true;
  1500. }
  1501.  
  1502.