1/******************************************************************************\ 2* Copyright (c) 2002-2003 MiEnterprise Pty Ltd. All rights reserved. 3* See end of file for complete source history. 4******************************************************************************* 5* GENERAL VALIDATION LIBRARY 6* 7* Adapted from various sources including: 8* (1) http://builder.cnet.com/webbuilding/pages/Programming/Kahn/102198/ss01.html 9* (2) http://javascript.internet.com/. 10\******************************************************************************/ 11/*************************************************************************\ 12* define and instantiate validation objects 13* the validation object accepts the following parameters: 14* realName: name used in the alerts (same as label on the page) 15* formEltName: this must be the name of the corresponding 16* HTML form element; make it the same as the object name 17* eltType: element type (we have to create this since IE3 18* doesn't support the type property for for elements) 19* text 20* textarea 21* checkbox 22* radio 23* select 24* uptoSnuff: function call that's evaluated during validation check 25* isXXXX(args) 26* format: text representation of required format; 27* pass 'null' if no required format; 28* used in alert as an aid to user 29\*************************************************************************/ 30function setCookie(c_name,value,exdays) { 31 var exdate=new Date(); 32 exdate.setDate(exdate.getDate() + exdays); 33 var c_value= value + "; path=/" + ((exdays==null) ? "" : "; expires="+exdate.toUTCString()); 34 document.cookie=c_name + "=" + c_value; 35} 36// Setting the cookie is done first - needs to be before any AJAX requests so cookie is available right away to serverside 37setCookie("clientTimezoneOffset", new Date().getTimezoneOffset(), 1); 38 39function validation(realName, formEltName, eltType, upToSnuff, format){ 40this.realName=realName; 41this.formEltName=formEltName; 42this.eltType=eltType; 43this.upToSnuff=upToSnuff; 44this.format=format;} 45var elts=new Array(); 46var allAtOnce=true; 47var beginRequestAlertForText="Please include: "; 48var beginRequestAlertGeneric="Please choose: "; 49var endRequestAlert="."; 50var beginInvalidAlert=" is an invalid "; 51var endInvalidAlert="!"; 52var beginFormatAlert=" Use this format: "; 53function ltrim(s){return s.replace( /^\s*/, "" );} 54function rtrim(s){return s.replace( /\s*$/, "" );} 55function trim(s){return rtrim(ltrim(s));} 56function isEqual(str1,str2){return strcmp(str1,str2)==0;} 57function isNumber(str, min, max){return (isText(str)&&(parseInt(str) >= min)&&(parseInt(str) <= max));} 58function isFloat(str, min, max){return (isText(str)&&(parseFloat(str) >= parseFloat(min))&&(parseFloat(str) <= parseFloat(max)));} 59function isPositiveWholeNumber(str){ 60for(j=0; j<str.length; j++){ 61if((str.charAt(j) < "0")||(str.charAt(j) > "9")){return false;}} 62return (parseInt(str) > 0);} 63function isNonNegativeWholeNumber(str){ 64for(j=0; j<str.length; j++){ 65if((str.charAt(j) < "0")||(str.charAt(j) > "9")){ 66return false;}} 67return (parseInt(str) >= 0);} 68function is24HourTime(str){ 69return (str.length==5)&&isNumber(str.charAt(0) + str.charAt(1), 0, 23) 70&& (str.charAt(2)==':')&&isNumber(str.charAt(3) + str.charAt(4), 0, 59);} 71function isText(str){ 72return (str!="");} 73function isTextRange(str, minLength, maxLength){ 74return (str.length >= minLength)&&(str.length <= maxLength);} 75function isPlainText(str){ 76for(j=0; j<str.length; j++){ 77if(!isLetter(str.charAt(j))){ 78return false;}} 79return true;} 80function isPlainTextLen(str, minLength){ 81return (isText(str)&&isPlainText(str)&&isTextLen(str, minLength));} 82function isPlainNameText(str){ 83for(j=0; j<str.length; j++){ 84if( ( !isLetter( str.charAt(j) ) )&&( "'"!=str.charAt(j) )&&( " "!=str.charAt(j) )&&( "-"!=str.charAt(j) ) ) 85{return false;}} 86return true;} 87function isPlainNameTextLen(str, minLength){ 88return (isText(str)&&isPlainNameText(str)&&isTextLen(str, minLength));} 89function isPassword(str,minLength){ 90if(str.length < minLength){ 91return false;} 92var digitCount=0; 93var letterCount=0; 94for(j=0; j<str.length; j++){ 95if(isDigit(str.charAt(j))){digitCount++;} 96else{letterCount++;}} 97return (digitCount>0)&&(letterCount>0);} 98function isTextLen(str,minLength){return (str.length>=minLength);}
99function isSelect(formObj){ 100return (formObj.selectedIndex!=0);} 101function isRadio(formObj){ 102for(j=0;j<formObj.length;j++){ 103if(formObj[j].checked){ 104return true;}}return false;} 105function isCheck(formObj,form,begin,num){ 106for(j=begin;j<begin+num;j++){ 107if(form.elements[j].checked){ 108return true;}} 109return false;} 110function isUrl(str){ 111return ((str.length>=12)&&(str.indexOf("http://")==0))} 112function isOptionalUrl(str){ 113return ((str.length==0)||isUrl(str));} 114function isEmail(emailStr){ 115var emailPat=/^(.+)@(.+)$/ 116var specialChars="\\(\\)<>@,;:\\\\\\\"\\.\\[\\]" 117var validChars="\[^\\s"+specialChars+"\]" 118var quotedUser="(\"[^\"]*\")" 119var ipDomainPat=/^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/ 120var atom=validChars+'+' 121var word="("+atom+"|"+quotedUser+")" 122var userPat=new RegExp("^"+word+"(\\."+word+")*$") 123var domainPat=new RegExp("^"+atom+"(\\."+atom+")*$") 124var matchArray=emailStr.match(emailPat) 125if(matchArray==null){ 126return false} 127var user=matchArray[1] 128var domain=matchArray[2] 129if(user.match(userPat)==null){ 130return false;} 131var IPArray=domain.match(ipDomainPat) 132if(IPArray!=null){ 133for(var i=1;i<=4;i++){ 134if(IPArray[i]>255){ 135return false;}} 136return true} 137var domainArray=domain.match(domainPat) 138if(domainArray==null){ 139return false;} 140var atomPat=new RegExp(atom,"g") 141var domArr=domain.match(atomPat) 142var len=domArr.length 143if(domArr[domArr.length-1].length<2||domArr[domArr.length-1].length>3){ 144return false;} 145if(len<2){ 146return false;} 147return true;} 148function isOptionalEmail(str){ 149return ((str.length==0)||isEmail(str));} 150function isAustralianPhoneNum(str){ 151if(str.length==0){return false} 152if(str.charAt(0)=="+"){return true} 153if(str.length!=12){return false} 154for(j=0;j<str.length;j++){ 155if((j==2)||(j==7)){ 156if(str.charAt(j)!=" "){return false} 157}else{ 158if((str.charAt(j)<"0")||(str.charAt(j)>"9")){return false} 159}}return true;} 160function isOptionalAustralianPhoneNum(str){ 161return ((str.length==0)||isAustralianPhoneNum(str));} 162function isAustralianMobilePhoneNum(str){ 163if(str.length==0){ return false } 164if(str.charAt(0)=="+"){ return true } 165if(str.length!=12){ return false } 166for(j=0; j<str.length; j++){ 167if((j==4)||(j==8)){ 168if(str.charAt(j)!=" "){ return false } 169}else{ 170if((str.charAt(j) < "0")||(str.charAt(j) > "9")){ return false } 171}} 172return true;} 173function isOptionalAustralianMobilePhoneNum(str){ 174return ((str.length==0)||isAustralianMobilePhoneNum(str));} 175function isLetter (c){ 176return ( ((c >= "a")&&(c <= "z"))||((c >= "A")&&(c <= "Z")) );} 177function isDigit (c){ 178return ((c >= "0")&&(c <= "9"));} 179function isLetterOrDigit (c){ 180return (isLetter(c)||isDigit(c));} 181function isOptionalTimestamp(str){ 182return (str.length==0)||isTimestamp(str);} 183function isTimestamp(str){ 184if(str.length < 16){ return false } 185return (isTimestampDate(str.substring(0,10))&&isTimestampTime(str.substring(11)));} 186function isOptionalTimestampDate(str){ 187return (str.length==0)||isTimestampDate(str);} 188function isTimestampDate(str){ 189if(str.length!=10){ return false } 190for(j=0; j<str.length; j++){ 191if((j==4)||(j==7)){ 192if(str.charAt(j)!="-"){ return false }} 193else{ 194if((str.charAt(j) < "0")||(str.charAt(j) > "9")){ return false }}} 195return true;} 196function isTimestampTime(str){ 197if(str.length < 5){ return false } 198for(j=0; j<str.length; j++){ 199if((j==2)||(j==5)){ 200if(str.charAt(j)!=":"){ return false }} 201else if(j==8){ 202if(str.charAt(j)!="."){ return false } 203}else{ 204if((str.charAt(j) < "0")||(str.charAt(j) > "9")){ return false } 205}} 206return true;} 207function isAusDate(str){ 208var numSlashes=0; 209var month=0; 210var day=0; 211var year=0; 212for(j=0; j<str.length; j++){ 213if(str.charAt(j)=="/"){ 214numSlashes++;} 215else if((str.charAt(j) < "0")||(str.charAt(j) > "9")){ 216return false;} 217else if(numSlashes==0){ 218day=day * 10 + parseInt(str.charAt(j));} 219else if(numSlashes==1){ 220month=month * 10 + parseInt(str.charAt(j));} 221else if(numSlashes==2){ 222year=year * 10 + parseInt(str.charAt(j));} 223else{ 224return false;}} 225if(day <= 0){ return false } 226if(month==0||month > 12){ return false } 227if(month==1||month==3||month==5||month==7||month==8||month==10||month==12){ 228if(day > 31){ return false }} 229else if(month==4||month==6||month==9||month==11){ 230if(day > 30){ return false }} 231else{ 232if(year%400==0){ 233if(day > 29){ return false }} 234else if(year%100==0){ 235if(day > 28){ return false }} 236else if(year%4==0){ 237if(day > 29){ return false }} 238else{ 239if(day > 28){ return false }}} 240if(year < 1900){return false;} 241if(year > 2100){return false;} 242return true;} 243function isDate(str){ 244var numSlashes=0; 245var month=0; 246var day=0; 247var year=0; 248for(j=0; j<str.length; j++){ 249if(str.charAt(j)=="/"){ 250numSlashes++;} 251else if((str.charAt(j) < "0")||(str.charAt(j) > "9")){ 252return false;} 253else if(numSlashes==0){ 254month=month * 10 + parseInt(str.charAt(j));} 255else if(numSlashes==1){ 256day=day * 10 + parseInt(str.charAt(j));} 257else if(numSlashes==2){ 258year=year * 10 + parseInt(str.charAt(j));} 259else{ 260return false;}} 261if(day <= 0){ return false } 262if(month==0||month > 12){ return false } 263if(month==1||month==3||month==5||month==7||month==8||month==10||month==12){ 264if(day > 31){ return false }} 265else if(month==4||month==6||month==9||month==11){ 266if(day > 30){ return false }} 267else{ 268if(year%400==0){ 269if(day > 29){ return false }} 270else if(year%100==0){ 271if(day > 28){ return false }} 272else if(year%4==0){ 273if(day > 29){ return false }} 274else{ 275if(day > 28){ return false }}} 276if(year < 1900){return false;} 277if(year > 2100){return false;} 278return true;} 279/*************************************************************************\ 280* This section defines variables and tokens needed for date checking. 281* Original: Sandeep Tamhankar ([email protected]) 282* 283* Here's the list of tokens we support:
284* m (or M) : month number, one or two digits. 285* mm (or MM) : month number, strictly two digits (i.e. April is 04). 286* d (or D) : day number, one or two digits. 287* dd (or DD) : day number, strictly two digits. 288* y (or Y) : year, two or four digits. 289* yy (or YY) : year, strictly two digits. 290* yyyy (or YYYY) : year, strictly four digits. 291* mon : abbreviated month name (April is apr, Apr, APR, etc.) 292* Mon : abbreviated month name, mixed-case (i.e. April is Apr only). 293* MON : abbreviated month name, all upper-case (i.e. April is APR only). 294* mon_strict : abbreviated month name, all lower-case (i.e. April is apr 295* only). 296* month : full month name (April is april, April, APRIL, etc.) 297* Month : full month name, mixed-case (i.e. April only). 298* MONTH: full month name, all upper-case (i.e. APRIL only). 299* month_strict : full month name, all lower-case (i.e. april only). 300* h (or H) : hour, one or two digits. 301* hh (or HH) : hour, strictly two digits. 302* min (or MIN): minutes, one or two digits. 303* mins (or MINS) : minutes, strictly two digits. 304* s (or S) : seconds, one or two digits. 305* ss (or SS) : seconds, strictly two digits. 306* ampm (or AMPM) : am/pm setting. Valid values to match this token are 307* am, pm, AM, PM, a.m., p.m., A.M., P.M. 308\*************************************************************************/ 309 310// Be careful with this pattern. Longer tokens should be placed before shorter 311// tokens to disambiguate them. For example, parsing "mon_strict" should
312// result in one token "mon_strict" and not two tokens "mon" and a literal 313// "_strict". 314var tokPat=new RegExp("^month_strict|month|Month|MONTH|yyyy|YYYY|mins|MINS|mon_strict|ampm|AMPM|mon|Mon|MON|min|MIN|dd|DD|mm|MM|yy|YY|hh|HH|ss|SS|m|M|d|D|y|Y|h|H|s|S"); 315// lowerMonArr is used to map months to their numeric values. 316var lowerMonArr={jan:1, feb:2, mar:3, apr:4, may:5, jun:6, jul:7, aug:8, sep:9, oct:10, nov:11, dec:12} 317// monPatArr contains regular expressions used for matching abbreviated months 318// in a date string. 319var monPatArr=new Array(); 320monPatArr['mon_strict']=new RegExp(/jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec/); 321monPatArr['Mon']=new RegExp(/Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec/); 322monPatArr['MON']=new RegExp(/JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC/); 323monPatArr['mon']=new RegExp("jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec",'i'); 324// monthPatArr contains regular expressions used for matching full months 325// in a date string. 326var monthPatArr=new Array(); 327monthPatArr['month']=new RegExp(/^january|february|march|april|may|june|july|august|september|october|november|december/i); 328monthPatArr['Month']=new RegExp(/^January|February|March|April|May|June|July|August|September|October|November|December/); 329monthPatArr['MONTH']=new RegExp(/^JANUARY|FEBRUARY|MARCH|APRIL|MAY|JUNE|JULY|AUGUST|SEPTEMBER|OCTOBER|NOVEMBER|DECEMBER/); 330monthPatArr['month_strict']=new RegExp(/^january|february|march|april|may|june|july|august|september|october|november|december/); 331// cutoffYear is the cut-off for assigning "19" or "20" as century. Any 332// two-digit year >= cutoffYear will get a century of "19", and everything 333// else gets a century of "20". 334var cutoffYear=50; 335// FormatToken is a datatype we use for storing extracted tokens from the 336// format string. 337function FormatToken (token, type){ 338this.token=token; 339this.type=type;} 340function parseFormatString (formatStr){ 341var tokArr=new Array; 342var tokInd=0; 343var strInd=0; 344var foundTok=0; 345while (strInd < formatStr.length){ 346if(formatStr.charAt(strInd)=="%" && 347(matchArray=formatStr.substr(strInd+1).match(tokPat))!=null){ 348strInd+=matchArray[0].length+1; 349tokArr[tokInd++]=new FormatToken(matchArray[0],"symbolic"); 350}else{ 351// No token matched current position, so current character should 352// be saved as a required literal. 353if(tokInd>0&&tokArr[tokInd-1].type=="literal"){ 354// Literal tokens can be combined.Just add to the last token. 355tokArr[tokInd-1].token+=formatStr.charAt(strInd++);} 356else{ 357tokArr[tokInd++]=new FormatToken(formatStr.charAt(strInd++), "literal"); 358}}} 359return tokArr;} 360/* buildDate does all the real work.It takes a date string and format string, 361tries to match the two up, and returns a Date object (with the supplied date 362string value).If a date string doesn't contain all the fields that a Date 363object contains (for example, a date string with just the month), all 364unprovided fields are defaulted to those characteristics of the current 365date. Time fields that aren't provided default to 0.Thus, a date string 366like "3/30/2000" in "%mm/%dd/%yyyy" format results in a Date object for that 367date at midnight.formatStr is a free-form string that indicates special 368tokens via the % character.Here are some examples that will return a Date 369object: 370buildDate('3/30/2000','%mm/%dd/%y') // March 30, 2000 371buildDate('March 30, 2000','%Mon %d, %y') // Same as above. 372buildDate('Here is the date: 30-3-00','Here is the date: %dd-%m-%yy') 373If the format string does not match the string provided, an error message 374(i.e. String object) is returned.Thus, to see if buildDate succeeded, the 375caller can use the "typeof" command on the return value.For example, 376here's the isDate function, which returns true if a given date is 377valid,and false otherwise (and reports an error in the false case): 378*/ 379function buildDate(dateStr,formatStr){ 380// parse the format string first. 381var tokArr=parseFormatString(formatStr); 382var strInd=0; 383var tokInd=0; 384var intMonth; 385var intDay; 386var intYear; 387var intHour; 388var intMin; 389var intSec; 390var ampm=""; 391var strOffset; 392// Create a date object with the current date so that if the user only 393// gives a month or day string, we can still return a valid date. 394var curdate=new Date(); 395intMonth=curdate.getMonth()+1; 396intDay=curdate.getDate(); 397intYear=curdate.getFullYear(); 398// Default time to midnight, so that if given just date info, we return a Date object for that date at midnight. 399intHour=0; 400intMin=0; 401intSec=0; 402// Walk across dateStr, matching the parsed formatStr until we find a mismatch or succeed. 403while (strInd < dateStr.length&&tokInd < tokArr.length){ 404// Start with the easy case of matching a literal. 405if(tokArr[tokInd].type=="literal"){ 406if(dateStr.indexOf(tokArr[tokInd].token,strInd)==strInd){ 407// The current position in the string does match the format pattern. 408strInd+=tokArr[tokInd++].token.length; 409continue;} 410else{ 411// There was a mismatch; return error. 412if(dateStr.length==0){ 413return "Please specify a date.";} 414else{ 415return "\"" + dateStr + "\" does not conform to the expected format: " + formatStr; 416}}} 417// If we get here, we're matching to a symbolic token. 418switch (tokArr[tokInd].token){ 419case 'm': 420case 'M': 421case 'd': 422case 'D': 423case 'h': 424case 'H': 425case 'min': 426case 'MIN': 427case 's': 428case 'S':
429// Extract one or two characters from the date-time string and if 430// it's a number, save it as the month, day, hour, or minute, as 431// appropriate. 432curChar=dateStr.charAt(strInd); 433nextChar=dateStr.charAt(strInd+1); 434matchArr=dateStr.substr(strInd).match(/^\d{1,2}/); 435if(matchArr==null){ 436// First character isn't a number; there's a mismatch between 437// the pattern and date string, so return error. 438switch (tokArr[tokInd].token.toLowerCase()){ 439case 'd': var unit="day"; break; 440case 'm': var unit="month"; break; 441case 'h': var unit="hour"; break; 442case 'min': var unit="minute"; break; 443case 's': var unit="second"; break; 444} 445return "Bad " + unit + " \"" + curChar + "\" or \"" + curChar + 446nextChar + "\".";} 447strOffset=matchArr[0].length; 448switch (tokArr[tokInd].token.toLowerCase()){ 449case 'd': intDay=parseInt(matchArr[0],10); break; 450case 'm': intMonth=parseInt(matchArr[0],10); break; 451case 'h': intHour=parseInt(matchArr[0],10); break; 452case 'min': intMin=parseInt(matchArr[0],10); break; 453case 's': intSec=parseInt(matchArr[0],10); break; 454} 455break; 456case 'mm': 457case 'MM': 458case 'dd': 459case 'DD': 460case 'hh': 461case 'HH': 462case 'mins': 463case 'MINS': 464case 'ss': 465case 'SS': 466// Extract two characters from the date string and if it's a 467// number, save it as the month, day, or hour, as appropriate. 468strOffset=2; 469matchArr=dateStr.substr(strInd).match(/^\d{2}/); 470if(matchArr==null){ 471// The two characters aren't a number; there's a mismatch 472// between the pattern and date string, so return an error 473// message. 474switch (tokArr[tokInd].token.toLowerCase()){ 475case 'dd': var unit="day"; break; 476case 'mm': var unit="month"; break; 477case 'hh': var unit="hour"; break; 478case 'mins': var unit="minute"; break; 479case 'ss': var unit="second"; break; 480} 481return "Bad " + unit + " \"" + dateStr.substr(strInd,2) + 482"\"."; 483} 484switch (tokArr[tokInd].token.toLowerCase()){ 485case 'dd': intDay=parseInt(matchArr[0],10); break; 486case 'mm': intMonth=parseInt(matchArr[0],10); break; 487case 'hh': intHour=parseInt(matchArr[0],10); break; 488case 'mins': intMin=parseInt(matchArr[0],10); break; 489case 'ss': intSec=parseInt(matchArr[0],10); break; 490} 491break; 492case 'y': 493case 'Y': 494// Extract two or four characters from the date string and if it's 495// a number, save it as the year.Convert two-digit years to four 496// digit years by assigning a century of '19' if the year is >= 497// cutoffYear, and '20' otherwise. 498if(dateStr.substr(strInd,4).search(/\d{4}/)!=-1){ 499// Four digit year. 500intYear=parseInt(dateStr.substr(strInd,4),10); 501strOffset=4; 502}else{ 503if(dateStr.substr(strInd,2).search(/\d{2}/)!=-1){ 504// Two digit year. 505intYear=parseInt(dateStr.substr(strInd,2),10); 506if(intYear>=cutoffYear){ 507intYear+=1900; 508}else{ 509intYear+=2000; 510} 511strOffset=2; 512}else{ 513// Bad year; return error. 514return "Bad year \"" + dateStr.substr(strInd,2) + 515"\". Must be two or four digits."; 516}} 517break; 518case 'yy': 519case 'YY': 520// Extract two characters from the date string and if it's a 521// number, save it as the year.Convert two-digit years to four 522// digit years by assigning a century of '19' if the year is >= 523// cutoffYear, and '20' otherwise. 524if(dateStr.substr(strInd,2).search(/\d{2}/)!=-1){ 525// Two digit year. 526intYear=parseInt(dateStr.substr(strInd,2),10); 527if(intYear>=cutoffYear){ 528intYear+=1900; 529}else{ 530intYear+=2000;} 531strOffset=2; 532}else{ 533// Bad year; return error 534return "Bad year \"" + dateStr.substr(strInd,2) + 535"\". Must be two digits."; 536} 537break; 538case 'yyyy': 539case 'YYYY': 540// Extract four characters from the date string and if it's a 541// number, save it as the year. 542if(dateStr.substr(strInd,4).search(/\d{4}/)!=-1){ 543// Four digit year. 544intYear=parseInt(dateStr.substr(strInd,4),10); 545strOffset=4; 546}else{ 547// Bad year; return error. 548return "Bad year \"" + dateStr.substr(strInd,4) + 549"\". Must be four digits."; 550}break; 551case 'mon': 552case 'Mon': 553case 'MON': 554case 'mon_strict': 555// Extract three characters from dateStr and parse them as 556// lower-case, mixed-case, or upper-case abbreviated months, 557// as appropriate. 558monPat=monPatArr[tokArr[tokInd].token]; 559if(dateStr.substr(strInd,3).search(monPat)!=-1){ 560intMonth=lowerMonArr[dateStr.substr(strInd,3).toLowerCase()]; 561}else{ 562// Bad month, return error. 563switch (tokArr[tokInd].token){ 564case 'mon_strict': caseStat="lower-case"; break; 565case 'Mon': caseStat="mixed-case"; break; 566case 'MON': caseStat="upper-case"; break; 567case 'mon': caseStat="between Jan and Dec"; break; 568} 569return "Bad month \"" + dateStr.substr(strInd,3) + 570"\". Must be " + caseStat + "."; 571} 572strOffset=3; 573break; 574case 'month': 575case 'Month': 576case 'MONTH': 577case 'month_strict': 578// Extract a full month name at strInd from dateStr if possible. 579monPat=monthPatArr[tokArr[tokInd].token]; 580matchArray=dateStr.substr(strInd).match(monPat); 581if(matchArray==null){ 582// Bad month, return error. 583return "Can't find a month beginning at \"" + 584dateStr.substr(strInd) + "\"."; 585} 586// It's a good month. 587intMonth=lowerMonArr[matchArray[0].substr(0,3).toLowerCase()]; 588strOffset=matchArray[0].length; 589break; 590case 'ampm': 591case 'AMPM': 592matchArr=dateStr.substr(strInd).match(/^(am|pm|AM|PM|a\.m\.|p\.m\.|A\.M\.|P\.M\.)/); 593if(matchArr==null){ 594// There's no am/pm in the string.Return error msg. 595return "Missing am/pm designation."; 596} 597// Store am/pm value for later (as just am or pm, to make things 598// easier later). 599if(matchArr[0].substr(0,1).toLowerCase()=="a"){ 600// This is am. 601ampm="am"; 602} 603else{ 604ampm="pm"; 605} 606strOffset=matchArr[0].length; 607break; 608} 609strInd+=strOffset; 610tokInd++; 611} 612if(tokInd!=tokArr.length||strInd!=dateStr.length){
613/* We got through the whole date string or format string, but there's 614more data in the other, so there's a mismatch. */ 615return "\"" + dateStr + "\" is either missing desired information or has more information than the expected format: " + formatStr; 616} 617// Make sure all components are in the right ranges. 618if(intMonth < 1||intMonth > 12){ 619return "Month must be between 1 and 12."; 620} 621if(intDay < 1||intDay > 31){ 622return "Day must be between 1 and 31."; 623} 624// Make sure user doesn't put 31 for a month that only has 30 days 625if((intMonth==4||intMonth==6||intMonth==9||intMonth==11)&&intDay==31){ 626return "Month "+intMonth+" doesn't have 31 days!"; 627} 628// Check for February date validity (including leap years) 629if(intMonth==2){ 630// figure out if "year" is a leap year; don't forget that 631// century years are only leap years if divisible by 400 632var isleap=(intYear%4==0&&(intYear%100!=0||intYear%400==0)); 633if(intDay > 29||(intDay==29&&!isleap)){ 634return "February " + intYear + " doesn't have " + intDay + 635" days!"; 636}} 637// Check that if am/pm is not provided, hours are between 0 and 23. 638if(ampm==""){ 639if(intHour < 0||intHour > 23){ 640return "Hour must be between 0 and 23 for military time."; 641}}else{ 642// non-military time, so make sure it's between 1 and 12. 643if(intHour < 1|| intHour > 12){ 644return "Hour must be between 1 and 12 for standard time."; 645}} 646// If user specified amor pm, convert intHour to military. 647if(ampm=="am"&&intHour==12){ 648intHour=0; 649} 650if(ampm=="pm"&&intHour < 12){ 651intHour+=12; 652} 653if(intMin < 0||intMin > 59){ 654return "Minute must be between 0 and 59."; 655} 656if(intSec < 0||intSec > 59){ 657return "Second must be between 0 and 59."; 658} 659return new Date(intYear,intMonth-1,intDay,intHour,intMin,intSec); 660} 661function isDate(dateStr,formatStr){ 662var myObj=buildDate(dateStr,formatStr); 663if(typeof myObj=="object"){ 664return true; 665}else{ 666return false; 667}} 668/*************************************************************************\ 669* The validateFormElements() function validates the form elements 670* previously defined as validation objects and as members of 671* the elts array. We loop through the elts array, testing each 672* element in turn, and alerting the user when they've missed 673* a required field 674\*************************************************************************/ 675function validateFormElements(form,elts){ 676var formEltName=""; 677var formObj=""; 678var str=""; 679var realName=""; 680var alertText=""; 681var firstMissingElt=null; 682var hardReturn="\r\n"; 683for(i=0;i<elts.length;i++){ 684formEltName=elts[i].formEltName; 685formObj=form.elements[formEltName]; 686realName=elts[i].realName; 687formObj.value=trim(formObj.value); 688if(elts[i].eltType=="text"){ 689str=formObj.value; 690if(eval(elts[i].upToSnuff)) continue; 691if(str==""){ 692if(allAtOnce){ 693alertText+=beginRequestAlertForText+realName+endRequestAlert+hardReturn; 694if(firstMissingElt==null){firstMissingElt=formObj}; 695}else{ 696alertText=beginRequestAlertForText+realName+endRequestAlert+hardReturn; 697alert(alertText); 698}}else{ 699if(allAtOnce){ 700alertText+=str+beginInvalidAlert+realName+endInvalidAlert+hardReturn; 701}else{ 702alertText=str+beginInvalidAlert+realName+endInvalidAlert+hardReturn;} 703if(elts[i].format!=null){ 704alertText+=beginFormatAlert+elts[i].format+hardReturn;} 705if(allAtOnce){ 706if(firstMissingElt==null){firstMissingElt=formObj}; 707}else{ 708alert(alertText); 709}}}else{ 710if(eval(elts[i].upToSnuff)) continue; 711if(allAtOnce){ 712alertText+=beginRequestAlertGeneric + realName + endRequestAlert + hardReturn; 713if(firstMissingElt==null){firstMissingElt=formObj};} 714else{ 715alertText=beginRequestAlertGeneric+realName+endRequestAlert+hardReturn; 716alert(alertText);}} 717var goToObj=(allAtOnce)?firstMissingElt:formObj; 718if(goToObj.select) goToObj.select(); 719if(goToObj.focus) goToObj.focus(); 720if(!allAtOnce){return false};} 721if(allAtOnce){ 722if(alertText!=""){ 723alert(alertText); 724return false;}} 725return true;} 726function decision(message, url){ 727// Hack for deleting files which contain an & in the file name 728if((url.indexOf("file=")>0)&&(url.indexOf("action=delete"))){ 729filename=url.substring(url.indexOf("file=")); 730url=url.substring(0, url.indexOf("file=")); 731filename=filename.replace( /&/g,"%26"); 732url=url+filename;} 733if(confirm(message)) location.href=url; 734} 735function numTo2dpDecimal(field){ 736var tmp1=fraction=whole=""; 737var dec=-1; 738var num=0; 739num=field.value; 740num=""+(Math.round(num * 100)/100); 741dec=num.indexOf("."); 742fraction=((dec > 0)?num.substring(dec,num.length):".00"); 743if(fraction.length==2) fraction+="0"; 744whole=parseInt(num); 745num=whole+fraction; 746field.value=num; 747return true;} 748function MM_openBrWindow(theURL,winName) 749{mywindow=window.open(theURL,winName,'scrollbars=yes,width=450,height=500,resizable=no'); 750mywindow.focus();} 751function MM_openNewWindow(theURL,winName,width,height,resizable) 752{mywindow=window.open(theURL,winName,'scrollbars=yes,width='+width+',height='+height+',resizable='+resizable); 753mywindow.focus();} 754function MM_openNewWindowNoScroll(theURL,winName,width,height,resizable) 755{mywindow=window.open(theURL,winName,'scrollbars=no,width='+width+',height='+height+',resizable='+resizable); 756mywindow.focus();} 757function MM_openHelpWindow(theURL) 758{mywindow=window.open(theURL,'HELP','scrollbars=yes,width=500,height=300,resizable=yes'); 759mywindow.focus();} 760function openModalDialog(url, title, width, height) 761{Modalbox.show(url, {title: title, width: width, height: height, slideDownDuration: 0});} 762function setFocus(target){ 763if(target.select) target.select();
764if(target.focus) target.focus(); 765} 766function setDefaultFocus(skip){ 767try{ 768done=false; 769allForms=document.forms; 770if(allForms!=null&&allForms.length>0){ 771for(n=0;n<allForms.length;n++){ 772if(done==false){ 773if(allForms[n]!=null&&allForms[n].elements!=null){ 774allElements=allForms[n].elements; 775if(allElements!=null){ 776for(i=0;i<allElements.length;i++){ 777if(done==false){ 778element=allElements[i]; 779if(element!=null&&element.type!=null&&element.enabled&&(element.type.indexOf("text")!=-1||element.type.indexOf("select")!=-1||element.type.indexOf("radio")!=-1||element.type.indexOf("checkbox")!=-1||element.type.indexOf("password")!=-1)){ 780if(n>=skip){ 781element.focus(); 782done=true; 783}}}}}}}}} 784}catch(exception){ 785}} 786var hitCount =0; 787function checkFirstClick(){ 788if(hitCount==0){ 789hitCount=1; 790setTimeout("clearHitCount()",1000); 791return true;} 792return false;} 793function clearHitCount(){ 794hitCount=0;} 795function include(filename){ 796var head=document.getElementsByTagName('head')[0]; 797script=document.createElement('script'); 798script.src=filename; 799script.type='application/javascript'; 800head.appendChild(script)} 801include('/scripts/sortable.js'); 802 803function loadPortalContentByAjax(url, portalEleId, extraContent) { 804 var isExtraContent = false; 805 if (extraContent == true) { 806 isExtraContent = true; 807 } 808 809 if (($(portalEleId).innerHTML == null || $(portalEleId).innerHTML == '') || isExtraContent) { 810 811 if (!isExtraContent) 812 { 813 $(portalEleId).innerHTML = '<img width="15" height="15" border="0" src="/icons/spinner.gif"></img> content loading - please wait'; 814 } 815 816 new Ajax.Request(url, 817 { 818 method: 'get', 819 asynchronous: true, 820 onSuccess: function(transport) 821 { 822 if (isExtraContent) { 823 $(portalEleId).innerHTML += transport.responseText; 824 } 825 else 826 { 827 $(portalEleId).innerHTML = transport.responseText; 828 } 829 }, 830 onFailure: function(){} 831 }); 832 833 return true; 834 } 835 836 return false; 837} 838 839function loadNoticeBoardContentByAjax(name, portalEleId, extraContent) { 840 return loadPortalContentByAjax('/jsp/templates/noticeBoard.jsp?name='+name, portalEleId, extraContent); 841} 842 843var ajaxPortalEnabled = false; 844try { 845new Ajax.Request('/common/Ajax?doAction=getProperty&name=ajax.load.portal.content', 846{ 847 method: 'get', 848 asynchronous: false, 849 onSuccess: function(transport) 850 { 851 if (transport.responseText == 'true') 852 { 853 ajaxPortalEnabled = true; 854 } 855 }, 856 onFailure: function(){} 857}); 858} catch (e) {} 859 860function copyToClipboard(s, copyEleId) 861{ 862 if( window.clipboardData && clipboardData.setData ) 863 { 864 clipboardData.setData("Text", s); 865 } 866 else 867 { 868 try 869 { 870 // You have to sign the code to enable this or allow the action in about:config by changing user_pref("signed.applets.codebase_principal_support", true); 871 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect'); 872 873 var copytext = s; 874 875 var str = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString); 876 if (!str) return false; 877 878 str.data = copytext; 879 880 var trans = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable); 881 if (!trans) return false; 882 883 trans.addDataFlavor("text/unicode"); 884 trans.setTransferData("text/unicode", str, copytext.length * 2); 885 886 var clipid = Components.interfaces.nsIClipboard; 887 var clip = Components.classes["@mozilla.org/widget/clipboard;1"].getService(clipid); 888 if (!clip) return false; 889 890 clip.setData(trans, null, clipid.kGlobalClipboard); 891 } 892 catch (e) 893 { 894 var outputEle = $(copyEleId); 895 if (outputEle != null) 896 { 897 outputEle.innerHTML = s; 898 } 899 else 900 { 901 //alert(s); 902 } 903 } 904 } 905}
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.