1// FormChek.js 2// 3// SUMMARY 4// 5// This is a set of JavaScript functions for validating input on 6// an HTML form. Functions are provided to validate: 7// 8// - U.S. and international phone/fax numbers 9// - U.S. ZIP codes (5 or 9 digit postal codes) 10// - U.S. Postal Codes (2 letter abbreviations for names of states) 11// - U.S. Social Security Numbers (abbreviated as SSNs) 12// - email addresses 13// - dates (entry of year, month, and day and validity of combined date) 14// - credit card numbers 15// 16// Supporting utility functions validate that: 17// 18// - characters are Letter, Digit, or LetterOrDigit 19// - strings are a Signed, Positive, Negative, Nonpositive, or 20// Nonnegative integer 21// - strings are a Float or a SignedFloat 22// - strings are Alphabetic, Alphanumeric, or Whitespace 23// - strings contain an integer within a specified range 24// 25// Functions are also provided to interactively check the 26// above kinds of data and prompt the user if they have 27// been entered incorrectly. 28// 29// Other utility functions are provided to: 30// 31// - remove from a string characters which are/are not 32// in a "bag" of selected characters 33// - reformat a string, adding delimiter characters 34// - strip whitespace/leading whitespace from a string 35// - reformat U.S. phone numbers, ZIP codes, and Social 36// Security numbers 37// 38// 39// Many of the below functions take an optional parameter eok (for "emptyOK") 40// which determines whether the empty string will return true or false. 41// Default behavior is controlled by global variable defaultEmptyOK. 42// 43// BASIC DATA VALIDATION FUNCTIONS: 44// 45// isWhitespace (s) Check whether string s is empty or whitespace. 46// isLetter (c) Check whether character c is an English letter 47// isDigit (c) Check whether character c is a digit 48// isLetterOrDigit (c) Check whether character c is a letter or digit. 49// isInteger (s [,eok]) True if all characters in string s are numbers. 50// isSignedInteger (s [,eok]) True if all characters in string s are numbers; leading + or - allowed. 51// isPositiveInteger (s [,eok]) True if string s is an integer > 0. 52// isNonnegativeInteger (s [,eok]) True if string s is an integer >= 0. 53// isNegativeInteger (s [,eok]) True if s is an integer < 0. 54// isNonpositiveInteger (s [,eok]) True if s is an integer <= 0. 55// isFloat (s [,eok]) True if string s is an unsigned floating point (real) number. (Integers also OK.) 56// isSignedFloat (s [,eok]) True if string s is a floating point number; leading + or - allowed. (Integers also OK.) 57// isAlphabetic (s [,eok]) True if string s is English letters 58// isAlphanumeric (s [,eok]) True if string s is English letters and numbers only. 59// 60// isSSN (s [,eok]) True if string s is a valid U.S. Social Security Number. 61// isUSPhoneNumber (s [,eok]) True if string s is a valid U.S. Phone Number. 62// isInternationalPhoneNumber (s [,eok]) True if string s is a valid international phone number. 63// isZIPCode (s [,eok]) True if string s is a valid U.S. ZIP code. 64// isStateCode (s [,eok]) True if string s is a valid U.S. Postal Code 65// isEmail (s [,eok]) True if string s is a valid email address. 66// isYear (s [,eok]) True if string s is a valid Year number. 67// isIntegerInRange (s, a, b [,eok]) True if string s is an integer between a and b, inclusive. 68// isMonth (s [,eok]) True if string s is a valid month between 1 and 12. 69// isDay (s [,eok]) True if string s is a valid day between 1 and 31. 70// daysInFebruary (year) Returns number of days in February of that year. 71// isDate (year, month, day) True if string arguments form a valid date. 72// isValidIPAddress True si el string es una ip 73 74// FUNCTIONS TO REFORMAT DATA: 75// 76// stripCharsInBag (s, bag) Removes all characters in string bag from string s. 77// stripCharsNotInBag (s, bag) Removes all characters NOT in string bag from string s. 78// stripWhitespace (s) Removes all whitespace characters from s. 79// stripInitialWhitespace (s) Removes initial (leading) whitespace characters from s. 80// reformat (TARGETSTRING, STRING, Function for inserting formatting characters or
81// INTEGER, STRING, INTEGER ... ) delimiters into TARGETSTRING. 82// reformatZIPCode (ZIPString) If 9 digits, inserts separator hyphen. 83// reformatSSN (SSN) Reformats as 123-45-6789. 84// reformatUSPhone (USPhone) Reformats as (123) 456-789. 85 86 87// FUNCTIONS TO PROMPT USER: 88// 89// prompt (s) Display prompt string s in status bar. 90// promptEntry (s) Display data entry prompt string s in status bar. 91// warnEmpty (theField, s) Notify user that required field theField is empty. 92// warnInvalid (theField, s) Notify user that contents of field theField are invalid. 93 94 95// FUNCTIONS TO INTERACTIVELY CHECK FIELD CONTENTS: 96// 97// checkString (theField, s [,eok]) Check that theField.value is not empty or all whitespace. 98// checkStateCode (theField) Check that theField.value is a valid U.S. state code. 99// checkZIPCode (theField [,eok]) Check that theField.value is a valid ZIP code. 100// checkUSPhone (theField [,eok]) Check that theField.value is a valid US Phone. 101// checkInternationalPhone (theField [,eok]) Check that theField.value is a valid International Phone. 102// checkEmail (theField [,eok]) Check that theField.value is a valid Email. 103// checkSSN (theField [,eok]) Check that theField.value is a valid SSN. 104// checkYear (theField [,eok]) Check that theField.value is a valid Year. 105// checkMonth (theField [,eok]) Check that theField.value is a valid Month. 106// checkDay (theField [,eok]) Check that theField.value is a valid Day. 107// checkDate (yearField, monthField, dayField, labelString, OKtoOmitDay) 108// Check that field values form a valid date. 109// getRadioButtonValue (radio) Get checked value from radio button. 110// checkCreditCard (radio, theField) Validate credit card info. 111 112 113// CREDIT CARD DATA VALIDATION FUNCTIONS 114// 115// isCreditCard (st) True if credit card number passes the Luhn Mod-10 test. 116// isVisa (cc) True if string cc is a valid VISA number. 117// isMasterCard (cc) True if string cc is a valid MasterCard number. 118// isAmericanExpress (cc) True if string cc is a valid American Express number. 119// isDinersClub (cc) True if string cc is a valid Diner's Club number. 120// isCarteBlanche (cc) True if string cc is a valid Carte Blanche number. 121// isDiscover (cc) True if string cc is a valid Discover card number. 122// isEnRoute (cc) True if string cc is a valid enRoute card number. 123// isJCB (cc) True if string cc is a valid JCB card number. 124// isAnyCard (cc) True if string cc is a valid card number for any of the accepted types. 125// isCardMatch (Type, Number) True if Number is valid for credic card of type Type. 126// 127// Other stub functions are retained for backward compatibility with LivePayment code. 128// See comments below for details. 129// 130// Performance hint: when you deploy this file on your website, strip out the 131// comment lines from the source code as well as any of the functions which 132// you don't need. This will give you a smaller .js file and achieve faster 133// downloads. 134// 135// 18 Feb 97 created Eric Krock 136// 137// (c) 1997 Netscape Communications Corporation 138 139 140 141// VARIABLE DECLARATIONS 142 143var digits = "0123456789"; 144 145var lowercaseLetters = "abcdefghijklmnopqrstuvwxyz" 146 147var uppercaseLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 148 149 150// whitespace characters 151var whitespace = " \t\n\r"; 152 153 154// decimal point character differs by language and culture 155var decimalPointDelimiter = "," 156 157 158// non-digit characters which are allowed in phone numbers 159var phoneNumberDelimiters = "()- "; 160 161 162// characters which are allowed in US phone numbers 163var validUSPhoneChars = digits + phoneNumberDelimiters; 164 165 166// characters which are allowed in international phone numbers 167// (a leading + is OK) 168var validWorldPhoneChars = digits + phoneNumberDelimiters + "+"; 169 170 171// non-digit characters which are allowed in 172// Social Security Numbers 173var SSNDelimiters = "- "; 174 175 176 177// characters which are allowed in Social Security Numbers 178var validSSNChars = digits + SSNDelimiters; 179 180 181 182// U.S. Social Security Numbers have 9 digits. 183// They are formatted as 123-45-6789. 184var digitsInSocialSecurityNumber = 9; 185 186 187 188// U.S. phone numbers have 10 digits. 189// They are formatted as 123 456 7890 or (123) 456-7890. 190var digitsInUSPhoneNumber = 10; 191 192 193 194// non-digit characters which are allowed in ZIP Codes 195var ZIPCodeDelimiters = "-"; 196 197 198
199// our preferred delimiter for reformatting ZIP Codes 200var ZIPCodeDelimeter = "-" 201 202 203// characters which are allowed in Social Security Numbers 204var validZIPCodeChars = digits + ZIPCodeDelimiters 205 206 207 208// U.S. ZIP codes have 5 or 9 digits. 209// They are formatted as 12345 or 12345-6789. 210var digitsInZIPCode1 = 5 211var digitsInZIPCode2 = 9 212 213 214// non-digit characters which are allowed in credit card numbers 215var creditCardDelimiters = " " 216 217 218// CONSTANT STRING DECLARATIONS 219// (grouped for ease of translation and localization) 220 221// m is an abbreviation for "missing" 222 223var mPrefix = "You did not enter a value into the " 224var mSuffix = " field. This is a required field. Please enter it now." 225 226// s is an abbreviation for "string" 227 228var sUSLastName = "Last Name" 229var sUSFirstName = "First Name" 230var sWorldLastName = "Family Name" 231var sWorldFirstName = "Given Name" 232var sTitle = "Title" 233var sCompanyName = "Company Name" 234var sUSAddress = "Street Address" 235var sWorldAddress = "Address" 236var sCity = "City" 237var sStateCode = "State Code" 238var sWorldState = "State, Province, or Prefecture" 239var sCountry = "Country" 240var sZIPCode = "ZIP Code" 241var sWorldPostalCode = "Postal Code" 242var sPhone = "Phone Number" 243var sFax = "Fax Number" 244var sDateOfBirth = "Date of Birth" 245var sExpirationDate = "Expiration Date" 246var sEmail = "Email" 247var sSSN = "Social Security Number" 248var sCreditCardNumber = "Credit Card Number" 249var sOtherInfo = "Other Information" 250 251 252 253 254// i is an abbreviation for "invalid" 255 256var iStateCode = "This field must be a valid two character U.S. state abbreviation (like CA for California). Please reenter it now." 257var iZIPCode = "This field must be a 5 or 9 digit U.S. ZIP Code (like 94043). Please reenter it now." 258var iUSPhone = "This field must be a 10 digit U.S. phone number (like 415 555 1212). Please reenter it now." 259var iWorldPhone = "This field must be a valid international phone number. Please reenter it now." 260var iSSN = "This field must be a 9 digit U.S. social security number (like 123 45 6789). Please reenter it now." 261var iEmail = "This field must be a valid email address (like [email protected]). Please reenter it now." 262var iCreditCardPrefix = "This is not a valid " 263var iCreditCardSuffix = " credit card number. (Click the link on this form to see a list of sample numbers.) Please reenter it now." 264var iDay = "This field must be a day number between 1 and 31. Please reenter it now." 265var iMonth = "This field must be a month number between 1 and 12. Please reenter it now." 266var iYear = "This field must be a 2 or 4 digit year number. Please reenter it now." 267var iDatePrefix = "The Day, Month, and Year for " 268var iDateSuffix = " do not form a valid date. Please reenter them now." 269 270 271 272// p is an abbreviation for "prompt" 273 274var pEntryPrompt = "Please enter a " 275var pStateCode = "2 character code (like CA)." 276var pZIPCode = "5 or 9 digit U.S. ZIP Code (like 94043)." 277var pUSPhone = "10 digit U.S. phone number (like 415 555 1212)." 278var pWorldPhone = "international phone number." 279var pSSN = "9 digit U.S. social security number (like 123 45 6789)." 280var pEmail = "Introduzca un email vlido (ejemplo: [email protected])" 281var pCreditCard = "valid credit card number." 282var pDay = "day number between 1 and 31." 283var pMonth = "month number between 1 and 12." 284var pYear = "2 or 4 digit year number." 285 286 287// Global variable defaultEmptyOK defines default return value 288// for many functions when they are passed the empty string. 289// By default, they will return defaultEmptyOK. 290// 291// defaultEmptyOK is false, which means that by default, 292// these functions will do "strict" validation. Function 293// isInteger, for example, will only return true if it is 294// passed a string containing an integer; if it is passed 295// the empty string, it will return false. 296// 297// You can change this default behavior globally (for all 298// functions which use defaultEmptyOK) by changing the value 299// of defaultEmptyOK. 300// 301// Most of these functions have an optional argument emptyOK 302// which allows you to override the default behavior for 303// the duration of a function call. 304// 305// This functionality is useful because it is possible to 306// say "if the user puts anything in this field, it must 307// be an integer (or a phone number, or a string, etc.), 308// but it's OK to leave the field empty too." 309// This is the case for fields which are optional but which
310// must have a certain kind of content if filled in. 311 312var defaultEmptyOK = false 313 314 315 316 317// Attempting to make this library run on Navigator 2.0, 318// so I'm supplying this array creation routine as per 319// JavaScript 1.0 documentation. If you're using 320// Navigator 3.0 or later, you don't need to do this; 321// you can use the Array constructor instead. 322 323function makeArray(n) { 324//*** BUG: If I put this line in, I get two error messages: 325//(1) Window.length can't be set by assignment 326//(2) daysInMonth has no property indexed by 4 327//If I leave it out, the code works fine. 328// this.length = n; 329 for (var i = 1; i <= n; i++) { 330 this[i] = 0 331 } 332 return this 333} 334 335 336 337var daysInMonth = makeArray(12); 338daysInMonth[1] = 31; 339daysInMonth[2] = 29; // must programmatically check this 340daysInMonth[3] = 31; 341daysInMonth[4] = 30; 342daysInMonth[5] = 31; 343daysInMonth[6] = 30; 344daysInMonth[7] = 31; 345daysInMonth[8] = 31; 346daysInMonth[9] = 30; 347daysInMonth[10] = 31; 348daysInMonth[11] = 30; 349daysInMonth[12] = 31; 350 351 352 353 354// Valid U.S. Postal Codes for states, territories, armed forces, etc. 355// See http://www.usps.gov/ncsc/lookups/abbr_state.txt. 356 357var USStateCodeDelimiter = "|"; 358var USStateCodes = "AL|AK|AS|AZ|AR|CA|CO|CT|DE|DC|FM|FL|GA|GU|HI|ID|IL|IN|IA|KS|KY|LA|ME|MH|MD|MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ|NM|NY|NC|ND|MP|OH|OK|OR|PW|PA|PR|RI|SC|SD|TN|TX|UT|VT|VI|VA|WA|WV|WI|WY|AE|AA|AE|AE|AP" 359 360 361 362 363// Check whether string s is empty. 364 365function isEmpty(s) 366{ return ((s == null) || (s.length == 0)) 367} 368 369 370 371// Returns true if string s is empty or 372// whitespace characters only. 373 374function isWhitespace (s) 375 376{ var i; 377 378 // Is s empty? 379 if (isEmpty(s)) return true; 380 381 // Search through string's characters one by one 382 // until we find a non-whitespace character. 383 // When we do, return false; if we don't, return true. 384 385 for (i = 0; i < s.length; i++) 386 { 387 // Check that current character isn't whitespace. 388 var c = s.charAt(i); 389 390 if (whitespace.indexOf(c) == -1) return false; 391 } 392 393 // All characters are whitespace. 394 return true; 395} 396 397 398 399// Removes all characters which appear in string bag from string s. 400 401function stripCharsInBag (s, bag) 402 403{ var i; 404 var returnString = ""; 405 406 // Search through string's characters one by one. 407 // If character is not in bag, append to returnString. 408 409 for (i = 0; i < s.length; i++) 410 { 411 // Check that current character isn't whitespace. 412 var c = s.charAt(i); 413 if (bag.indexOf(c) == -1) returnString += c; 414 } 415 416 return returnString; 417} 418 419 420 421// Removes all characters which do NOT appear in string bag 422// from string s. 423 424function stripCharsNotInBag (s, bag) 425 426{ var i; 427 var returnString = ""; 428 429 // Search through string's characters one by one. 430 // If character is in bag, append to returnString. 431 432 for (i = 0; i < s.length; i++) 433 { 434 // Check that current character isn't whitespace. 435 var c = s.charAt(i); 436 if (bag.indexOf(c) != -1) returnString += c; 437 } 438 439 return returnString; 440} 441 442 443 444// Removes all whitespace characters from s. 445// Global variable whitespace (see above) 446// defines which characters are considered whitespace. 447 448function stripWhitespace (s) 449 450{ return stripCharsInBag (s, whitespace) 451} 452 453 454 455 456// WORKAROUND FUNCTION FOR NAVIGATOR 2.0.2 COMPATIBILITY. 457// 458// The below function *should* be unnecessary. In general, 459// avoid using it. Use the standard method indexOf instead. 460// 461// However, because of an apparent bug in indexOf on 462// Navigator 2.0.2, the below loop does not work as the 463// body of stripInitialWhitespace: 464// 465// while ((i < s.length) && (whitespace.indexOf(s.charAt(i)) != -1)) 466// i++; 467// 468// ... so we provide this workaround function charInString 469// instead. 470// 471// charInString (CHARACTER c, STRING s) 472// 473// Returns true if single character c (actually a string) 474// is contained within string s. 475 476function charInString (c, s) 477{ for (i = 0; i < s.length; i++) 478 { if (s.charAt(i) == c) return true; 479 } 480 return false 481} 482 483 484 485// Removes initial (leading) whitespace characters from s. 486// Global variable whitespace (see above) 487// defines which characters are considered whitespace. 488 489function stripInitialWhitespace (s) 490{ var i = 0; 491 492 while ((i < s.length) && charInString (s.charAt(i), whitespace)) 493 i++; 494 495 return s.substring (i, s.length); 496} 497 498 499 500 501 502 503 504// Returns true if character c is an English letter 505// (A .. Z, a..z). 506// 507// NOTE: Need i18n version to support European characters. 508// This could be tricky due to different character 509// sets and orderings for various languages and platforms. 510 511function isLetter (c) 512{ return ( ((c >= "a") && (c <= "z")) || ((c >= "A") && (c <= "Z")) ) 513} 514 515 516 517// Returns true if character c is a digit 518// (0 .. 9). 519 520function isDigit (c) 521{ return ((c >= "0") && (c <= "9")) 522} 523 524 525 526// Returns true if character c is a letter or digit. 527 528function isLetterOrDigit (c) 529{ return (isLetter(c) || isDigit(c)) 530} 531 532 533 534// isInteger (STRING s [, BOOLEAN emptyOK]) 535// 536// Returns true if all characters in string s are numbers. 537// 538// Accepts non-signed integers only. Does not accept floating 539// point, exponential notation, etc. 540// 541// We don't use parseInt because that would accept a string 542// with trailing non-numeric characters. 543// 544// By default, returns defaultEmptyOK if s is empty. 545// There is an optional second argument called emptyOK. 546// emptyOK is used to override for a single function call 547// the default behavior which is specified globally by 548// defaultEmptyOK. 549// If emptyOK is false (or any value other than true), 550// the function will return false if s is empty. 551// If emptyOK is true, the function will return true if s is empty. 552// 553// EXAMPLE FUNCTION CALL: RESULT: 554// isInteger ("5") true 555// isInteger ("") defaultEmptyOK 556// isInteger ("-5") false 557// isInteger ("", true) true 558// isInteger ("", false) false 559// isInteger ("5", false) true 560 561function isInteger (s) 562 563{ var i; 564 565 if (isEmpty(s)) 566 if (isInteger.arguments.length == 1) return defaultEmptyOK; 567 else return (isInteger.arguments[1] == true); 568 569 // Search through string's characters one by one 570 // until we find a non-numeric character. 571 // When we do, return false; if we don't, return true. 572 573 for (i = 0; i < s.length; i++) 574 { 575 // Check that current character is number. 576 var c = s.charAt(i); 577 578 if (!isDigit(c)) return false; 579 } 580 581 // All characters are numbers. 582 return true; 583} 584 585 586 587 588 589 590 591// isSignedInteger (STRING s [, BOOLEAN emptyOK]) 592// 593// Returns true if all characters are numbers; 594// first character is allowed to be + or - as well. 595// 596// Does not accept floating point, exponential notation, etc. 597// 598// We don't use parseInt because that would accept a string 599// with trailing non-numeric characters. 600// 601// For explanation of optional argument emptyOK, 602// see comments of function isInteger. 603// 604// EXAMPLE FUNCTION CALL: RESULT: 605// isSignedInteger ("5") true 606// isSignedInteger ("") defaultEmptyOK 607// isSignedInteger ("-5") true 608// isSignedInteger ("+5") true 609// isSignedInteger ("", false) false 610// isSignedInteger ("", true) true 611 612function isSignedInteger (s) 613 614{ if (isEmpty(s)) 615 if (isSignedInteger.arguments.length == 1) return defaultEmptyOK; 616 else return (isSignedInteger.arguments[1] == true); 617 618 else { 619 var startPos = 0; 620 var secondArg = defaultEmptyOK; 621 622 if (isSignedInteger.arguments.length > 1) 623 secondArg = isSignedInteger.arguments[1]; 624 625 // skip leading + or - 626 if ( (s.charAt(0) == "-") || (s.charAt(0) == "+") ) 627 startPos = 1; 628 return (isInteger(s.substring(startPos, s.length), secondArg)) 629 } 630} 631 632 633 634 635// isPositiveInteger (STRING s [, BOOLEAN emptyOK]) 636// 637// Returns true if string s is an integer > 0. 638// 639// For explanation of optional argument emptyOK, 640// see comments of function isInteger. 641 642function isPositiveInteger (s) 643{ var secondArg = defaultEmptyOK; 644 645 if (isPositiveInteger.arguments.length > 1) 646 secondArg = isPositiveInteger.arguments[1]; 647 648 // The next line is a bit byzantine. What it means is:
649 // a) s must be a signed integer, AND 650 // b) one of the following must be true: 651 // i) s is empty and we are supposed to return true for 652 // empty strings 653 // ii) this is a positive, not negative, number 654 655 return (isSignedInteger(s, secondArg) 656 && ( (isEmpty(s) && secondArg) || (parseInt (s) > 0) ) ); 657} 658 659 660 661 662 663 664// isNonnegativeInteger (STRING s [, BOOLEAN emptyOK]) 665// 666// Returns true if string s is an integer >= 0. 667// 668// For explanation of optional argument emptyOK, 669// see comments of function isInteger. 670 671function isNonnegativeInteger (s) 672{ var secondArg = defaultEmptyOK; 673 674 if (isNonnegativeInteger.arguments.length > 1) 675 secondArg = isNonnegativeInteger.arguments[1]; 676 677 // The next line is a bit byzantine. What it means is: 678 // a) s must be a signed integer, AND 679 // b) one of the following must be true: 680 // i) s is empty and we are supposed to return true for 681 // empty strings 682 // ii) this is a number >= 0 683 684 return (isSignedInteger(s, secondArg) 685 && ( (isEmpty(s) && secondArg) || (parseInt (s) >= 0) ) ); 686} 687 688 689 690 691 692 693// isNegativeInteger (STRING s [, BOOLEAN emptyOK]) 694// 695// Returns true if string s is an integer < 0. 696// 697// For explanation of optional argument emptyOK, 698// see comments of function isInteger. 699 700function isNegativeInteger (s) 701{ var secondArg = defaultEmptyOK; 702 703 if (isNegativeInteger.arguments.length > 1) 704 secondArg = isNegativeInteger.arguments[1]; 705 706 // The next line is a bit byzantine. What it means is: 707 // a) s must be a signed integer, AND 708 // b) one of the following must be true: 709 // i) s is empty and we are supposed to return true for 710 // empty strings 711 // ii) this is a negative, not positive, number 712 713 return (isSignedInteger(s, secondArg) 714 && ( (isEmpty(s) && secondArg) || (parseInt (s) < 0) ) ); 715} 716 717 718 719 720 721 722// isNonpositiveInteger (STRING s [, BOOLEAN emptyOK]) 723// 724// Returns true if string s is an integer <= 0. 725// 726// For explanation of optional argument emptyOK, 727// see comments of function isInteger. 728 729function isNonpositiveInteger (s) 730{ var secondArg = defaultEmptyOK; 731 732 if (isNonpositiveInteger.arguments.length > 1)
733 secondArg = isNonpositiveInteger.arguments[1]; 734 735 // The next line is a bit byzantine. What it means is: 736 // a) s must be a signed integer, AND 737 // b) one of the following must be true: 738 // i) s is empty and we are supposed to return true for 739 // empty strings 740 // ii) this is a number <= 0 741 742 return (isSignedInteger(s, secondArg) 743 && ( (isEmpty(s) && secondArg) || (parseInt (s) <= 0) ) ); 744} 745 746 747 748 749 750// isFloat (STRING s [, BOOLEAN emptyOK]) 751// 752// True if string s is an unsigned floating point (real) number. 753// 754// Also returns true for unsigned integers. If you wish 755// to distinguish between integers and floating point numbers, 756// first call isInteger, then call isFloat. 757// 758// Does not accept exponential notation. 759// 760// For explanation of optional argument emptyOK, 761// see comments of function isInteger. 762 763function isFloat (s) 764 765{ var i; 766 var seenDecimalPoint = false; 767 768 if (isEmpty(s)) 769 if (isFloat.arguments.length == 1) return defaultEmptyOK; 770 else return (isFloat.arguments[1] == true); 771 772 if (s == decimalPointDelimiter) return false; 773 774 // Search through string's characters one by one 775 // until we find a non-numeric character. 776 // When we do, return false; if we don't, return true. 777 778 for (i = 0; i < s.length; i++) 779 { 780 // Check that current character is number. 781 var c = s.charAt(i); 782 783 if ((c == decimalPointDelimiter) && !seenDecimalPoint) seenDecimalPoint = true; 784 else if (!isDigit(c)) return false; 785 } 786 787 // All characters are numbers. 788 return true; 789} 790 791 792 793 794 795 796 797// isSignedFloat (STRING s [, BOOLEAN emptyOK]) 798// 799// True if string s is a signed or unsigned floating point 800// (real) number. First character is allowed to be + or -. 801// 802// Also returns true for unsigned integers. If you wish 803// to distinguish between integers and floating point numbers, 804// first call isSignedInteger, then call isSignedFloat. 805// 806// Does not accept exponential notation. 807// 808// For explanation of optional argument emptyOK, 809// see comments of function isInteger. 810 811function isSignedFloat (s) 812 813{ if (isEmpty(s)) 814 if (isSignedFloat.arguments.length == 1) return defaultEmptyOK; 815 else return (isSignedFloat.arguments[1] == true); 816 817 else { 818 var startPos = 0; 819 var secondArg = defaultEmptyOK; 820 821 if (isSignedFloat.arguments.length > 1) 822 secondArg = isSignedFloat.arguments[1]; 823 824 // skip leading + or - 825 if ( (s.charAt(0) == "-") || (s.charAt(0) == "+") ) 826 startPos = 1; 827 return (isFloat(s.substring(startPos, s.length), secondArg)) 828 } 829} 830 831 832 833 834// isAlphabetic (STRING s [, BOOLEAN emptyOK]) 835// 836// Returns true if string s is English letters 837// (A .. Z, a..z) only. 838// 839// For explanation of optional argument emptyOK, 840// see comments of function isInteger. 841// 842// NOTE: Need i18n version to support European characters. 843// This could be tricky due to different character 844// sets and orderings for various languages and platforms. 845 846function isAlphabetic (s) 847 848{ var i; 849 850 if (isEmpty(s)) 851 if (isAlphabetic.arguments.length == 1) return defaultEmptyOK; 852 else return (isAlphabetic.arguments[1] == true); 853 854 // Search through string's characters one by one 855 // until we find a non-alphabetic character. 856 // When we do, return false; if we don't, return true. 857 858 for (i = 0; i < s.length; i++) 859 { 860 // Check that current character is letter. 861 var c = s.charAt(i); 862 863 if (!isLetter(c)) 864 return false; 865 } 866 867 // All characters are letters. 868 return true; 869} 870 871 872 873 874// isAlphanumeric (STRING s [, BOOLEAN emptyOK]) 875// 876// Returns true if string s is English letters 877// (A .. Z, a..z) and numbers only. 878// 879// For explanation of optional argument emptyOK, 880// see comments of function isInteger. 881// 882// NOTE: Need i18n version to support European characters. 883// This could be tricky due to different character 884// sets and orderings for various languages and platforms. 885 886function isAlphanumeric (s) 887 888{ var i; 889 890 if (isEmpty(s)) 891 if (isAlphanumeric.arguments.length == 1) return defaultEmptyOK; 892 else return (isAlphanumeric.arguments[1] == true); 893 894 // Search through string's characters one by one 895 // until we find a non-alphanumeric character. 896 // When we do, return false; if we don't, return true. 897 898 for (i = 0; i < s.length; i++) 899 { 900 // Check that current character is number or letter. 901 var c = s.charAt(i); 902 903 if (! (isLetter(c) || isDigit(c) ) ) 904 return false; 905 } 906 907 // All characters are numbers or letters. 908 return true; 909} 910 911function isValidIPAddress(ipaddr) { 912 var re = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
913 if (re.test(ipaddr)) { 914 var parts = ipaddr.split("."); 915 if (parseInt(parseFloat(parts[0])) == 0) { return false; } 916 for (var i=0; i<parts.length; i++) { 917 if (parseInt(parseFloat(parts[i])) > 255) { return false; } 918 } 919 return true; 920 } else { 921 return false; 922 } 923} 924 925 926 927// reformat (TARGETSTRING, STRING, INTEGER, STRING, INTEGER ... ) 928// 929// Handy function for arbitrarily inserting formatting characters 930// or delimiters of various kinds within TARGETSTRING. 931// 932// reformat takes one named argument, a string s, and any number 933// of other arguments. The other arguments must be integers or 934// strings. These other arguments specify how string s is to be 935// reformatted and how and where other strings are to be inserted 936// into it. 937// 938// reformat processes the other arguments in order one by one. 939// * If the argument is an integer, reformat appends that number 940// of sequential characters from s to the resultString. 941// * If the argument is a string, reformat appends the string 942// to the resultString. 943// 944// NOTE: The first argument after TARGETSTRING must be a string. 945// (It can be empty.) The second argument must be an integer. 946// Thereafter, integers and strings must alternate. This is to 947// provide backward compatibility to Navigator 2.0.2 JavaScript 948// by avoiding use of the typeof operator. 949// 950// It is the caller's responsibility to make sure that we do not 951// try to copy more characters from s than s.length. 952// 953// EXAMPLES: 954// 955// * To reformat a 10-digit U.S. phone number from "1234567890" 956// to "(123) 456-7890" make this function call: 957// reformat("1234567890", "(", 3, ") ", 3, "-", 4) 958// 959// * To reformat a 9-digit U.S. Social Security number from 960// "123456789" to "123-45-6789" make this function call: 961// reformat("123456789", "", 3, "-", 2, "-", 4) 962// 963// HINT: 964// 965// If you have a string which is already delimited in one way 966// (example: a phone number delimited with spaces as "123 456 7890") 967// and you want to delimit it in another way using function reformat, 968// call function stripCharsNotInBag to remove the unwanted 969// characters, THEN call function reformat to delimit as desired. 970// 971// EXAMPLE: 972// 973// reformat (stripCharsNotInBag ("123 456 7890", digits), 974// "(", 3, ") ", 3, "-", 4) 975 976function reformat (s) 977 978{ var arg; 979 var sPos = 0; 980 var resultString = ""; 981 982 for (var i = 1; i < reformat.arguments.length; i++) { 983 arg = reformat.arguments[i]; 984 if (i % 2 == 1) resultString += arg; 985 else { 986 resultString += s.substring(sPos, sPos + arg); 987 sPos += arg; 988 } 989 } 990 return resultString; 991} 992 993 994 995 996// isSSN (STRING s [, BOOLEAN emptyOK]) 997// 998// isSSN returns true if string s is a valid U.S. Social 999// Security Number. Must be 9 digits. 1000// 1001// NOTE: Strip out any delimiters (spaces, hyphens, etc.) 1002// from string s before calling this function. 1003// 1004// For explanation of optional argument emptyOK, 1005// see comments of function isInteger. 1006 1007function isSSN (s) 1008{ if (isEmpty(s)) 1009 if (isSSN.arguments.length == 1) return defaultEmptyOK; 1010 else return (isSSN.arguments[1] == true); 1011 return (isInteger(s) && s.length == digitsInSocialSecurityNumber) 1012} 1013 1014 1015 1016 1017// isUSPhoneNumber (STRING s [, BOOLEAN emptyOK]) 1018// 1019// isUSPhoneNumber returns true if string s is a valid U.S. Phone 1020// Number. Must be 10 digits. 1021// 1022// NOTE: Strip out any delimiters (spaces, hyphens, parentheses, etc.) 1023// from string s before calling this function. 1024// 1025// For explanation of optional argument emptyOK, 1026// see comments of function isInteger. 1027 1028function isUSPhoneNumber (s) 1029{ if (isEmpty(s)) 1030 if (isUSPhoneNumber.arguments.length == 1) return defaultEmptyOK; 1031 else return (isUSPhoneNumber.arguments[1] == true); 1032 return (isInteger(s) && s.length == digitsInUSPhoneNumber) 1033} 1034 1035 1036 1037 1038// isInternationalPhoneNumber (STRING s [, BOOLEAN emptyOK]) 1039// 1040// isInternationalPhoneNumber returns true if string s is a valid
1041// international phone number. Must be digits only; any length OK. 1042// May be prefixed by + character. 1043// 1044// NOTE: A phone number of all zeros would not be accepted. 1045// I don't think that is a valid phone number anyway. 1046// 1047// NOTE: Strip out any delimiters (spaces, hyphens, parentheses, etc.) 1048// from string s before calling this function. You may leave in 1049// leading + character if you wish. 1050// 1051// For explanation of optional argument emptyOK, 1052// see comments of function isInteger. 1053 1054function isInternationalPhoneNumber (s) 1055{ if (isEmpty(s)) 1056 if (isInternationalPhoneNumber.arguments.length == 1) return defaultEmptyOK; 1057 else return (isInternationalPhoneNumber.arguments[1] == true); 1058 return (isPositiveInteger(s)) 1059} 1060 1061 1062 1063 1064// isZIPCode (STRING s [, BOOLEAN emptyOK]) 1065// 1066// isZIPCode returns true if string s is a valid 1067// U.S. ZIP code. Must be 5 or 9 digits only. 1068// 1069// NOTE: Strip out any delimiters (spaces, hyphens, etc.) 1070// from string s before calling this function. 1071// 1072// For explanation of optional argument emptyOK, 1073// see comments of function isInteger. 1074 1075function isZIPCode (s) 1076{ if (isEmpty(s)) 1077 if (isZIPCode.arguments.length == 1) return defaultEmptyOK; 1078 else return (isZIPCode.arguments[1] == true); 1079 return (isInteger(s) && 1080 ((s.length == digitsInZIPCode1) || 1081 (s.length == digitsInZIPCode2))) 1082} 1083 1084 1085 1086 1087 1088// isStateCode (STRING s [, BOOLEAN emptyOK]) 1089// 1090// Return true if s is a valid U.S. Postal Code 1091// (abbreviation for state). 1092// 1093// For explanation of optional argument emptyOK, 1094// see comments of function isInteger. 1095 1096function isStateCode(s) 1097{ if (isEmpty(s)) 1098 if (isStateCode.arguments.length == 1) return defaultEmptyOK; 1099 else return (isStateCode.arguments[1] == true); 1100 return ( (USStateCodes.indexOf(s) != -1) && 1101 (s.indexOf(USStateCodeDelimiter) == -1) ) 1102} 1103 1104 1105 1106 1107// isEmail (STRING s [, BOOLEAN emptyOK]) 1108// 1109// Email address must be of form [email protected] -- in other words: 1110// * there must be at least one character before the @ 1111// * there must be at least one character before and after the . 1112// * the characters @ and . are both required 1113// 1114// For explanation of optional argument emptyOK, 1115// see comments of function isInteger. 1116 1117function isEmail (s) 1118{ if (isEmpty(s)) 1119 if (isEmail.arguments.length == 1) return defaultEmptyOK; 1120 else return (isEmail.arguments[1] == true); 1121 1122 // is s whitespace? 1123 if (isWhitespace(s)) return false; 1124 1125 // there must be >= 1 character before @, so we 1126 // start looking at character position 1 1127 // (i.e. second character) 1128 var i = 1; 1129 var sLength = s.length; 1130 1131 // look for @ 1132 while ((i < sLength) && (s.charAt(i) != "@")) 1133 { i++ 1134 } 1135 1136 if ((i >= sLength) || (s.charAt(i) != "@")) return false; 1137 else i += 2; 1138 1139 // look for . 1140 while ((i < sLength) && (s.charAt(i) != ".")) 1141 { i++ 1142 } 1143 1144 // there must be at least one character after the . 1145 if ((i >= sLength - 1) || (s.charAt(i) != ".")) return false; 1146 else return true; 1147} 1148 1149 1150 1151 1152 1153// isYear (STRING s [, BOOLEAN emptyOK]) 1154// 1155// isYear returns true if string s is a valid 1156// Year number. Must be 2 or 4 digits only. 1157// 1158// For Year 2000 compliance, you are advised 1159// to use 4-digit year numbers everywhere. 1160// 1161// And yes, this function is not Year 10000 compliant, but 1162// because I am giving you 8003 years of advance notice, 1163// I don't feel very guilty about this ... 1164// 1165// For B.C. compliance, write your own function. ;-> 1166// 1167// For explanation of optional argument emptyOK, 1168// see comments of function isInteger. 1169 1170function isYear (s) 1171{ if (isEmpty(s)) 1172 if (isYear.arguments.length == 1) return defaultEmptyOK; 1173 else return (isYear.arguments[1] == true); 1174 if (!isNonnegativeInteger(s)) return false; 1175 return ((s.length == 2) || (s.length == 4)); 1176} 1177 1178 1179 1180// isIntegerInRange (STRING s, INTEGER a, INTEGER b [, BOOLEAN emptyOK]) 1181// 1182// isIntegerInRange returns true if string s is an integer 1183// within the range of integer arguments a and b, inclusive. 1184//
1185// For explanation of optional argument emptyOK, 1186// see comments of function isInteger. 1187 1188 1189function isIntegerInRange (s, a, b) 1190{ if (isEmpty(s)) 1191 if (isIntegerInRange.arguments.length == 1) return defaultEmptyOK; 1192 else return (isIntegerInRange.arguments[1] == true); 1193 1194 // Catch non-integer strings to avoid creating a NaN below, 1195 // which isn't available on JavaScript 1.0 for Windows. 1196 if (!isInteger(s, false)) return false; 1197 1198 // Now, explicitly change the type to integer via parseInt 1199 // so that the comparison code below will work both on 1200 // JavaScript 1.2 (which typechecks in equality comparisons) 1201 // and JavaScript 1.1 and before (which doesn't). 1202 var num = parseInt (s); 1203 return ((num >= a) && (num <= b)); 1204} 1205 1206 1207 1208// isMonth (STRING s [, BOOLEAN emptyOK]) 1209// 1210// isMonth returns true if string s is a valid 1211// month number between 1 and 12. 1212// 1213// For explanation of optional argument emptyOK, 1214// see comments of function isInteger. 1215 1216function isMonth (s) 1217{ if (isEmpty(s)) 1218 if (isMonth.arguments.length == 1) return defaultEmptyOK; 1219 else return (isMonth.arguments[1] == true); 1220 return isIntegerInRange (s, 1, 12); 1221} 1222 1223 1224 1225// isDay (STRING s [, BOOLEAN emptyOK]) 1226// 1227// isDay returns true if string s is a valid 1228// day number between 1 and 31. 1229// 1230// For explanation of optional argument emptyOK, 1231// see comments of function isInteger. 1232 1233function isDay (s) 1234{ if (isEmpty(s)) 1235 if (isDay.arguments.length == 1) return defaultEmptyOK; 1236 else return (isDay.arguments[1] == true); 1237 return isIntegerInRange (s, 1, 31); 1238} 1239 1240 1241 1242// daysInFebruary (INTEGER year) 1243// 1244// Given integer argument year, 1245// returns number of days in February of that year. 1246 1247function daysInFebruary (year) 1248{ // February has 29 days in any year evenly divisible by four, 1249 // EXCEPT for centurial years which are not also divisible by 400. 1250 return ( ((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0) ) ) ? 29 : 28 ); 1251} 1252 1253 1254 1255// isDate (STRING year, STRING month, STRING day) 1256// 1257// isDate returns true if string arguments year, month, and day 1258// form a valid date. 1259// 1260 1261function isDate (year, month, day) 1262{ // catch invalid years (not 2- or 4-digit) and invalid months and days. 1263 if (! (isYear(year, false) && isMonth(month, false) && isDay(day, false))) return false; 1264 1265 // Explicitly change type to integer to make code work in both 1266 // JavaScript 1.1 and JavaScript 1.2. 1267 var intYear = parseInt(year); 1268 var intMonth = parseInt(month); 1269 var intDay = parseInt(day); 1270 1271 // catch invalid days, except for February 1272 if (intDay > daysInMonth[intMonth]) return false; 1273 1274 if ((intMonth == 2) && (intDay > daysInFebruary(intYear))) return false; 1275 1276 return true; 1277} 1278 1279 1280 1281 1282/* FUNCTIONS TO NOTIFY USER OF INPUT REQUIREMENTS OR MISTAKES. */ 1283 1284 1285// Display prompt string s in status bar. 1286 1287function prompt (s) 1288{ window.status = s 1289} 1290 1291 1292 1293// Display data entry prompt string s in status bar. 1294 1295function promptEntry (s) 1296{ window.status = pEntryPrompt + s 1297} 1298 1299 1300 1301 1302// Notify user that required field theField is empty. 1303// String s describes expected contents of theField.value. 1304// Put focus in theField and return false. 1305 1306function warnEmpty (theField, s) 1307{ theField.focus() 1308 alert(mPrefix + s + mSuffix) 1309 return false 1310} 1311 1312 1313 1314// Notify user that contents of field theField are invalid. 1315// String s describes expected contents of theField.value. 1316// Put select theField, pu focus in it, and return false. 1317 1318function warnInvalid (theField, s) 1319{ theField.focus() 1320 theField.select() 1321 alert(s) 1322 return false 1323} 1324 1325 1326 1327 1328/* FUNCTIONS TO INTERACTIVELY CHECK VARIOUS FIELDS. */ 1329 1330// checkString (TEXTFIELD theField, STRING s, [, BOOLEAN emptyOK==false]) 1331// 1332// Check that string theField.value is not all whitespace. 1333// 1334// For explanation of optional argument emptyOK, 1335// see comments of function isInteger. 1336 1337function checkString (theField, s, emptyOK) 1338{ // Next line is needed on NN3 to avoid "undefined is not a number" error 1339 // in equality comparison below. 1340 if (checkString.arguments.length == 2) emptyOK = defaultEmptyOK; 1341 if ((emptyOK == true) && (isEmpty(theField.value))) return true; 1342 if (isWhitespace(theField.value)) 1343 return warnEmpty (theField, s); 1344 else return true; 1345} 1346 1347 1348 1349// checkStateCode (TEXTFIELD theField [, BOOLEAN emptyOK==false]) 1350// 1351// Check that string theField.value is a valid U.S. state code.
1352// 1353// For explanation of optional argument emptyOK, 1354// see comments of function isInteger. 1355 1356function checkStateCode (theField, emptyOK) 1357{ if (checkStateCode.arguments.length == 1) emptyOK = defaultEmptyOK; 1358 if ((emptyOK == true) && (isEmpty(theField.value))) return true; 1359 else 1360 { theField.value = theField.value.toUpperCase(); 1361 if (!isStateCode(theField.value, false)) 1362 return warnInvalid (theField, iStateCode); 1363 else return true; 1364 } 1365} 1366 1367 1368 1369// takes ZIPString, a string of 5 or 9 digits; 1370// if 9 digits, inserts separator hyphen 1371 1372function reformatZIPCode (ZIPString) 1373{ if (ZIPString.length == 5) return ZIPString; 1374 else return (reformat (ZIPString, "", 5, "-", 4)); 1375} 1376 1377 1378 1379 1380// checkZIPCode (TEXTFIELD theField [, BOOLEAN emptyOK==false]) 1381// 1382// Check that string theField.value is a valid ZIP code. 1383// 1384// For explanation of optional argument emptyOK, 1385// see comments of function isInteger. 1386 1387function checkZIPCode (theField, emptyOK) 1388{ if (checkZIPCode.arguments.length == 1) emptyOK = defaultEmptyOK; 1389 if ((emptyOK == true) && (isEmpty(theField.value))) return true; 1390 else 1391 { var normalizedZIP = stripCharsInBag(theField.value, ZIPCodeDelimiters) 1392 if (!isZIPCode(normalizedZIP, false)) 1393 return warnInvalid (theField, iZIPCode); 1394 else 1395 { // if you don't want to insert a hyphen, comment next line out 1396 theField.value = reformatZIPCode(normalizedZIP) 1397 return true; 1398 } 1399 } 1400} 1401 1402 1403 1404// takes USPhone, a string of 10 digits 1405// and reformats as (123) 456-789 1406 1407function reformatUSPhone (USPhone) 1408{ return (reformat (USPhone, "(", 3, ") ", 3, "-", 4)) 1409} 1410 1411 1412 1413// checkUSPhone (TEXTFIELD theField [, BOOLEAN emptyOK==false]) 1414// 1415// Check that string theField.value is a valid US Phone. 1416// 1417// For explanation of optional argument emptyOK, 1418// see comments of function isInteger. 1419 1420function checkUSPhone (theField, emptyOK) 1421{ if (checkUSPhone.arguments.length == 1) emptyOK = defaultEmptyOK; 1422 if ((emptyOK == true) && (isEmpty(theField.value))) return true; 1423 else 1424 { var normalizedPhone = stripCharsInBag(theField.value, phoneNumberDelimiters) 1425 if (!isUSPhoneNumber(normalizedPhone, false)) 1426 return warnInvalid (theField, iUSPhone); 1427 else 1428 { // if you don't want to reformat as (123) 456-789, comment next line out 1429 theField.value = reformatUSPhone(normalizedPhone) 1430 return true; 1431 } 1432 } 1433} 1434 1435 1436 1437// checkInternationalPhone (TEXTFIELD theField [, BOOLEAN emptyOK==false]) 1438// 1439// Check that string theField.value is a valid International Phone. 1440// 1441// For explanation of optional argument emptyOK, 1442// see comments of function isInteger. 1443 1444function checkInternationalPhone (theField, emptyOK) 1445{ if (checkInternationalPhone.arguments.length == 1) emptyOK = defaultEmptyOK; 1446 if ((emptyOK == true) && (isEmpty(theField.value))) return true; 1447 else 1448 { if (!isInternationalPhoneNumber(theField.value, false)) 1449 return warnInvalid (theField, iWorldPhone); 1450 else return true; 1451 } 1452} 1453 1454 1455 1456// checkEmail (TEXTFIELD theField [, BOOLEAN emptyOK==false]) 1457// 1458// Check that string theField.value is a valid Email. 1459// 1460// For explanation of optional argument emptyOK, 1461// see comments of function isInteger. 1462 1463function checkEmail (theField, emptyOK) 1464{ if (checkEmail.arguments.length == 1) emptyOK = defaultEmptyOK; 1465 if ((emptyOK == true) && (isEmpty(theField.value))) return true; 1466 else if (!isEmail(theField.value, false)) 1467 return warnInvalid (theField, iEmail); 1468 else return true; 1469} 1470 1471 1472 1473// takes SSN, a string of 9 digits 1474// and reformats as 123-45-6789 1475 1476function reformatSSN (SSN) 1477{ return (reformat (SSN, "", 3, "-", 2, "-", 4)) 1478} 1479 1480 1481// Check that string theField.value is a valid SSN. 1482// 1483// For explanation of optional argument emptyOK, 1484// see comments of function isInteger. 1485 1486function checkSSN (theField, emptyOK) 1487{ if (checkSSN.arguments.length == 1) emptyOK = defaultEmptyOK; 1488 if ((emptyOK == true) && (isEmpty(theField.value))) return true; 1489 else 1490 { var normalizedSSN = stripCharsInBag(theField.value, SSNDelimiters) 1491 if (!isSSN(normalizedSSN, false))
1492 return warnInvalid (theField, iSSN); 1493 else 1494 { // if you don't want to reformats as 123-456-7890, comment next line out 1495 theField.value = reformatSSN(normalizedSSN) 1496 return true; 1497 } 1498 } 1499} 1500 1501 1502 1503 1504// Check that string theField.value is a valid Year. 1505// 1506// For explanation of optional argument emptyOK, 1507// see comments of function isInteger. 1508 1509function checkYear (theField, emptyOK) 1510{ if (checkYear.arguments.length == 1) emptyOK = defaultEmptyOK; 1511 if ((emptyOK == true) && (isEmpty(theField.value))) return true; 1512 if (!isYear(theField.value, false)) 1513 return warnInvalid (theField, iYear); 1514 else return true; 1515} 1516 1517 1518// Check that string theField.value is a valid Month. 1519// 1520// For explanation of optional argument emptyOK, 1521// see comments of function isInteger. 1522 1523function checkMonth (theField, emptyOK) 1524{ if (checkMonth.arguments.length == 1) emptyOK = defaultEmptyOK; 1525 if ((emptyOK == true) && (isEmpty(theField.value))) return true; 1526 if (!isMonth(theField.value, false)) 1527 return warnInvalid (theField, iMonth); 1528 else return true; 1529} 1530 1531 1532// Check that string theField.value is a valid Day. 1533// 1534// For explanation of optional argument emptyOK, 1535// see comments of function isInteger. 1536 1537function checkDay (theField, emptyOK) 1538{ if (checkDay.arguments.length == 1) emptyOK = defaultEmptyOK; 1539 if ((emptyOK == true) && (isEmpty(theField.value))) return true; 1540 if (!isDay(theField.value, false)) 1541 return warnInvalid (theField, iDay); 1542 else return true; 1543} 1544 1545 1546 1547// checkDate (yearField, monthField, dayField, STRING labelString [, OKtoOmitDay==false]) 1548// 1549// Check that yearField.value, monthField.value, and dayField.value 1550// form a valid date. 1551// 1552// If they don't, labelString (the name of the date, like "Birth Date") 1553// is displayed to tell the user which date field is invalid. 1554// 1555// If it is OK for the day field to be empty, set optional argument 1556// OKtoOmitDay to true. It defaults to false. 1557 1558function checkDate (yearField, monthField, dayField, labelString, OKtoOmitDay) 1559{ // Next line is needed on NN3 to avoid "undefined is not a number" error 1560 // in equality comparison below. 1561 if (checkDate.arguments.length == 4) OKtoOmitDay = false; 1562 if (!isYear(yearField.value)) return warnInvalid (yearField, iYear); 1563 if (!isMonth(monthField.value)) return warnInvalid (monthField, iMonth); 1564 if ( (OKtoOmitDay == true) && isEmpty(dayField.value) ) return true; 1565 else if (!isDay(dayField.value)) 1566 return warnInvalid (dayField, iDay); 1567 if (isDate (yearField.value, monthField.value, dayField.value)) 1568 return true; 1569 alert (iDatePrefix + labelString + iDateSuffix) 1570 return false 1571} 1572 1573 1574 1575// Get checked value from radio button. 1576 1577function getRadioButtonValue (radio) 1578{ for (var i = 0; i < radio.length; i++) 1579 { if (radio[i].checked) { break } 1580 } 1581 return radio[i].value 1582} 1583 1584 1585 1586 1587// Validate credit card info. 1588 1589function checkCreditCard (radio, theField) 1590{ var cardType = getRadioButtonValue (radio) 1591 var normalizedCCN = stripCharsInBag(theField.value, creditCardDelimiters) 1592 if (!isCardMatch(cardType, normalizedCCN)) 1593 return warnInvalid (theField, iCreditCardPrefix + cardType + iCreditCardSuffix); 1594 else 1595 { theField.value = normalizedCCN 1596 return true 1597 } 1598} 1599 1600 1601 1602/* ================================================================ 1603 Credit card verification functions 1604 Originally included as Starter Application 1.0.0 in LivePayment. 1605 20 Feb 1997 modified by egk: 1606 changed naming convention to initial lowercase 1607 (isMasterCard instead of IsMasterCard, etc.) 1608 changed isCC to isCreditCard 1609 retained functions named with older conventions from 1610 LivePayment as stub functions for backward 1611 compatibility only 1612 added "AMERICANEXPRESS" as equivalent of "AMEX" 1613 for naming consistency 1614 ================================================================ */ 1615 1616 1617/* ================================================================ 1618 FUNCTION: isCreditCard(st) 1619 1620 INPUT: st - a string representing a credit card number 1621 1622 RETURNS: true, if the credit card number passes the Luhn Mod-10 1623 test. 1624 false, otherwise 1625 ================================================================ */ 1626 1627function isCreditCard(st) { 1628 // Encoding only works on cards with less than 19 digits 1629 if (st.length > 19) 1630 return (false); 1631 1632 sum = 0; mul = 1; l = st.length; 1633 for (i = 0; i < l; i++) { 1634 digit = st.substring(l-i-1,l-i); 1635 tproduct = parseInt(digit ,10)*mul; 1636 if (tproduct >= 10) 1637 sum += (tproduct % 10) + 1; 1638 else 1639 sum += tproduct; 1640 if (mul == 1) 1641 mul++; 1642 else 1643 mul--; 1644 } 1645// Uncomment the following line to help create credit card numbers 1646// 1. Create a dummy number with a 0 as the last digit 1647// 2. Examine the sum written out 1648// 3. Replace the last digit with the difference between the sum and 1649// the next multiple of 10. 1650 1651// document.writeln("<BR>Sum = ",sum,"<BR>"); 1652// alert("Sum = " + sum); 1653 1654 if ((sum % 10) == 0) 1655 return (true); 1656 else 1657 return (false); 1658 1659} // END FUNCTION isCreditCard() 1660 1661 1662 1663/* ================================================================ 1664 FUNCTION: isVisa() 1665 1666 INPUT: cc - a string representing a credit card number 1667 1668 RETURNS: true, if the credit card number is a valid VISA number. 1669 1670 false, otherwise 1671 1672 Sample number: 4111 1111 1111 1111 (16 digits) 1673 ================================================================ */ 1674 1675function isVisa(cc) 1676{ 1677 if (((cc.length == 16) || (cc.length == 13)) && 1678 (cc.substring(0,1) == 4)) 1679 return isCreditCard(cc); 1680 return false; 1681} // END FUNCTION isVisa() 1682 1683 1684 1685 1686/* ================================================================ 1687 FUNCTION: isMasterCard() 1688 1689 INPUT: cc - a string representing a credit card number 1690 1691 RETURNS: true, if the credit card number is a valid MasterCard 1692 number. 1693 1694 false, otherwise 1695 1696 Sample number: 5500 0000 0000 0004 (16 digits) 1697 ================================================================ */ 1698 1699function isMasterCard(cc) 1700{ 1701 firstdig = cc.substring(0,1); 1702 seconddig = cc.substring(1,2); 1703 if ((cc.length == 16) && (firstdig == 5) && 1704 ((seconddig >= 1) && (seconddig <= 5))) 1705 return isCreditCard(cc); 1706 return false; 1707 1708} // END FUNCTION isMasterCard() 1709 1710 1711 1712 1713 1714/* ================================================================ 1715 FUNCTION: isAmericanExpress() 1716 1717 INPUT: cc - a string representing a credit card number 1718 1719 RETURNS: true, if the credit card number is a valid American 1720 Express number. 1721 1722 false, otherwise 1723 1724 Sample number: 340000000000009 (15 digits) 1725 ================================================================ */ 1726 1727function isAmericanExpress(cc) 1728{ 1729 firstdig = cc.substring(0,1); 1730 seconddig = cc.substring(1,2); 1731 if ((cc.length == 15) && (firstdig == 3) && 1732 ((seconddig == 4) || (seconddig == 7))) 1733 return isCreditCard(cc); 1734 return false; 1735 1736} // END FUNCTION isAmericanExpress() 1737 1738 1739 1740 1741/* ================================================================ 1742 FUNCTION: isDinersClub() 1743 1744 INPUT: cc - a string representing a credit card number 1745 1746 RETURNS: true, if the credit card number is a valid Diner's 1747 Club number. 1748 1749 false, otherwise 1750 1751 Sample number: 30000000000004 (14 digits) 1752 ================================================================ */ 1753 1754function isDinersClub(cc) 1755{ 1756 firstdig = cc.substring(0,1); 1757 seconddig = cc.substring(1,2); 1758 if ((cc.length == 14) && (firstdig == 3) && 1759 ((seconddig == 0) || (seconddig == 6) || (seconddig == 8))) 1760 return isCreditCard(cc); 1761 return false; 1762} 1763 1764 1765 1766/* ================================================================ 1767 FUNCTION: isCarteBlanche() 1768 1769 INPUT: cc - a string representing a credit card number 1770 1771 RETURNS: true, if the credit card number is a valid Carte 1772 Blanche number. 1773 1774 false, otherwise 1775 ================================================================ */ 1776 1777function isCarteBlanche(cc) 1778{ 1779 return isDinersClub(cc); 1780} 1781 1782 1783 1784 1785/* ================================================================ 1786 FUNCTION: isDiscover() 1787 1788 INPUT: cc - a string representing a credit card number 1789 1790 RETURNS: true, if the credit card number is a valid Discover 1791 card number. 1792 1793 false, otherwise 1794 1795 Sample number: 6011000000000004 (16 digits) 1796 ================================================================ */ 1797 1798function isDiscover(cc) 1799{ 1800 first4digs = cc.substring(0,4); 1801 if ((cc.length == 16) && (first4digs == "6011")) 1802 return isCreditCard(cc); 1803 return false; 1804 1805} // END FUNCTION isDiscover() 1806 1807 1808 1809 1810 1811/* ================================================================ 1812 FUNCTION: isEnRoute() 1813 1814 INPUT: cc - a string representing a credit card number 1815 1816 RETURNS: true, if the credit card number is a valid enRoute 1817 card number. 1818 1819 false, otherwise 1820 1821 Sample number: 201400000000009 (15 digits) 1822 ================================================================ */ 1823 1824function isEnRoute(cc) 1825{ 1826 first4digs = cc.substring(0,4); 1827 if ((cc.length == 15) && 1828 ((first4digs == "2014") || 1829 (first4digs == "2149"))) 1830 return isCreditCard(cc); 1831 return false; 1832} 1833 1834 1835 1836/* ================================================================ 1837 FUNCTION: isJCB() 1838 1839 INPUT: cc - a string representing a credit card number 1840 1841 RETURNS: true, if the credit card number is a valid JCB 1842 card number. 1843 1844 false, otherwise 1845 ================================================================ */ 1846 1847function isJCB(cc) 1848{ 1849 first4digs = cc.substring(0,4); 1850 if ((cc.length == 16) && 1851 ((first4digs == "3088") || 1852 (first4digs == "3096") || 1853 (first4digs == "3112") || 1854 (first4digs == "3158") || 1855 (first4digs == "3337") || 1856 (first4digs == "3528"))) 1857 return isCreditCard(cc); 1858 return false; 1859 1860} // END FUNCTION isJCB() 1861 1862 1863 1864/* ================================================================ 1865 FUNCTION: isAnyCard() 1866 1867 INPUT: cc - a string representing a credit card number 1868 1869 RETURNS: true, if the credit card number is any valid credit 1870 card number for any of the accepted card types. 1871 1872 false, otherwise 1873 ================================================================ */ 1874 1875function isAnyCard(cc) 1876{ 1877 if (!isCreditCard(cc)) 1878 return false; 1879 if (!isMasterCard(cc) && !isVisa(cc) && !isAmericanExpress(cc) && !isDinersClub(cc) && 1880 !isDiscover(cc) && !isEnRoute(cc) && !isJCB(cc)) { 1881 return false; 1882 } 1883 return true; 1884 1885} // END FUNCTION isAnyCard() 1886 1887 1888 1889/* ================================================================ 1890 FUNCTION: isCardMatch() 1891 1892 INPUT: cardType - a string representing the credit card type 1893 cardNumber - a string representing a credit card number 1894 1895 RETURNS: true, if the credit card number is valid for the particular 1896 credit card type given in "cardType". 1897 1898 false, otherwise 1899 ================================================================ */ 1900 1901function isCardMatch (cardType, cardNumber) 1902{ 1903 1904 cardType = cardType.toUpperCase(); 1905 var doesMatch = true; 1906 1907 if ((cardType == "VISA") && (!isVisa(cardNumber))) 1908 doesMatch = false; 1909 if ((cardType == "MASTERCARD") && (!isMasterCard(cardNumber))) 1910 doesMatch = false; 1911 if ( ( (cardType == "AMERICANEXPRESS") || (cardType == "AMEX") ) 1912 && (!isAmericanExpress(cardNumber))) doesMatch = false; 1913 if ((cardType == "DISCOVER") && (!isDiscover(cardNumber))) 1914 doesMatch = false; 1915 if ((cardType == "JCB") && (!isJCB(cardNumber))) 1916 doesMatch = false; 1917 if ((cardType == "DINERS") && (!isDinersClub(cardNumber))) 1918 doesMatch = false; 1919 if ((cardType == "CARTEBLANCHE") && (!isCarteBlanche(cardNumber))) 1920 doesMatch = false; 1921 if ((cardType == "ENROUTE") && (!isEnRoute(cardNumber))) 1922 doesMatch = false; 1923 return doesMatch; 1924 1925} // END FUNCTION CardMatch() 1926 1927 1928 1929 1930/* ================================================================ 1931 The below stub functions are retained for backward compatibility
1932 with the original LivePayment code so that it should be possible 1933 in principle to swap in this new module as a replacement for the 1934 older module without breaking existing code. (There are no 1935 guarantees, of course, but it should work.) 1936 1937 When writing new code, do not use these stub functions; use the 1938 functions defined above. 1939 ================================================================ */ 1940 1941function IsCC (st) { 1942 return isCreditCard(st); 1943} 1944 1945function IsVisa (cc) { 1946 return isVisa(cc); 1947} 1948 1949function IsVISA (cc) { 1950 return isVisa(cc); 1951} 1952 1953function IsMasterCard (cc) { 1954 return isMasterCard(cc); 1955} 1956 1957function IsMastercard (cc) { 1958 return isMasterCard(cc); 1959} 1960 1961function IsMC (cc) { 1962 return isMasterCard(cc); 1963} 1964 1965function IsAmericanExpress (cc) { 1966 return isAmericanExpress(cc); 1967} 1968 1969function IsAmEx (cc) { 1970 return isAmericanExpress(cc); 1971} 1972 1973function IsDinersClub (cc) { 1974 return isDinersClub(cc); 1975} 1976 1977function IsDC (cc) { 1978 return isDinersClub(cc); 1979} 1980 1981function IsDiners (cc) { 1982 return isDinersClub(cc); 1983} 1984 1985function IsCarteBlanche (cc) { 1986 return isCarteBlanche(cc); 1987} 1988 1989function IsCB (cc) { 1990 return isCarteBlanche(cc); 1991} 1992 1993function IsDiscover (cc) { 1994 return isDiscover(cc); 1995} 1996 1997function IsEnRoute (cc) { 1998 return isEnRoute(cc); 1999} 2000 2001function IsenRoute (cc) { 2002 return isEnRoute(cc); 2003} 2004 2005function IsJCB (cc) { 2006 return isJCB(cc); 2007} 2008 2009function IsAnyCard(cc) { 2010 return isAnyCard(cc); 2011} 2012 2013function IsCardMatch (cardType, cardNumber) { 2014 return isCardMatch (cardType, cardNumber); 2015} 2016 2017
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.