PageSourceSearch

https://www.thefugees.com/js/front.js

js thefugees.com collected 2026-09-24 22:33:24 UTC 60,335 bytes, 2,054 lines download raw bytes

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

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.