PluginProbe
Calendar / 1.2.2
Calendar v1.2.2
trunk 1.0 1.1 1.1.1 1.1.2 1.2 1.2.1 1.2.2 1.2.3 1.3 1.3.1 1.3.10 1.3.11 1.3.12 1.3.13 1.3.14 1.3.15 1.3.16 1.3.17 1.3.18 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 All 28 releases
calendar / javascript.js

javascript.js in Calendar 1.2.2, at javascript.js

1,468 lines 57.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 // ===================================================================
2 // Author: Matt Kruse <matt@mattkruse.com>
3 // WWW: http://www.mattkruse.com/
4 //
5 // NOTICE: You may use this code for any purpose, commercial or
6 // private, without any further permission from the author. You may
7 // remove this notice from your final code if you wish, however it is
8 // appreciated by the author if at least my web site address is kept.
9 //
10 // You may *NOT* re-distribute this code in any way except through its
11 // use. That means, you can include it in your product, or your web
12 // site, or any other form where the code is actually being used. You
13 // may not put the plain javascript up on your site for download or
14 // include it in your javascript libraries for download.
15 // If you wish to share this code with others, please just point them
16 // to the URL instead.
17 // Please DO NOT link directly to my .js files from your site. Copy
18 // the files to your server and use them there. Thank you.
19 // ===================================================================
20
21
22 /* SOURCE FILE: AnchorPosition.js */
23
24 /*
25 AnchorPosition.js
26 Author: Matt Kruse
27 Last modified: 10/11/02
28
29 DESCRIPTION: These functions find the position of an <A> tag in a document,
30 so other elements can be positioned relative to it.
31
32 COMPATABILITY: Netscape 4.x,6.x,Mozilla, IE 5.x,6.x on Windows. Some small
33 positioning errors - usually with Window positioning - occur on the
34 Macintosh platform.
35
36 FUNCTIONS:
37 getAnchorPosition(anchorname)
38 Returns an Object() having .x and .y properties of the pixel coordinates
39 of the upper-left corner of the anchor. Position is relative to the PAGE.
40
41 getAnchorWindowPosition(anchorname)
42 Returns an Object() having .x and .y properties of the pixel coordinates
43 of the upper-left corner of the anchor, relative to the WHOLE SCREEN.
44
45 NOTES:
46
47 1) For popping up separate browser windows, use getAnchorWindowPosition.
48 Otherwise, use getAnchorPosition
49
50 2) Your anchor tag MUST contain both NAME and ID attributes which are the
51 same. For example:
52 <A NAME="test" ID="test"> </A>
53
54 3) There must be at least a space between <A> </A> for IE5.5 to see the
55 anchor tag correctly. Do not do <A></A> with no space.
56 */
57
58 // getAnchorPosition(anchorname)
59 // This function returns an object having .x and .y properties which are the coordinates
60 // of the named anchor, relative to the page.
61 function getAnchorPosition(anchorname) {
62 // This function will return an Object with x and y properties
63 var useWindow=false;
64 var coordinates=new Object();
65 var x=0,y=0;
66 // Browser capability sniffing
67 var use_gebi=false, use_css=false, use_layers=false;
68 if (document.getElementById) { use_gebi=true; }
69 else if (document.all) { use_css=true; }
70 else if (document.layers) { use_layers=true; }
71 // Logic to find position
72 if (use_gebi && document.all) {
73 x=AnchorPosition_getPageOffsetLeft(document.all[anchorname]);
74 y=AnchorPosition_getPageOffsetTop(document.all[anchorname]);
75 }
76 else if (use_gebi) {
77 var o=document.getElementById(anchorname);
78 x=AnchorPosition_getPageOffsetLeft(o);
79 y=AnchorPosition_getPageOffsetTop(o);
80 }
81 else if (use_css) {
82 x=AnchorPosition_getPageOffsetLeft(document.all[anchorname]);
83 y=AnchorPosition_getPageOffsetTop(document.all[anchorname]);
84 }
85 else if (use_layers) {
86 var found=0;
87 for (var i=0; i<document.anchors.length; i++) {
88 if (document.anchors[i].name==anchorname) { found=1; break; }
89 }
90 if (found==0) {
91 coordinates.x=0; coordinates.y=0; return coordinates;
92 }
93 x=document.anchors[i].x;
94 y=document.anchors[i].y;
95 }
96 else {
97 coordinates.x=0; coordinates.y=0; return coordinates;
98 }
99 coordinates.x=x;
100 coordinates.y=y;
101 return coordinates;
102 }
103
104 // getAnchorWindowPosition(anchorname)
105 // This function returns an object having .x and .y properties which are the coordinates
106 // of the named anchor, relative to the window
107 function getAnchorWindowPosition(anchorname) {
108 var coordinates=getAnchorPosition(anchorname);
109 var x=0;
110 var y=0;
111 if (document.getElementById) {
112 if (isNaN(window.screenX)) {
113 x=coordinates.x-document.body.scrollLeft+window.screenLeft;
114 y=coordinates.y-document.body.scrollTop+window.screenTop;
115 }
116 else {
117 x=coordinates.x+window.screenX+(window.outerWidth-window.innerWidth)-window.pageXOffset;
118 y=coordinates.y+window.screenY+(window.outerHeight-24-window.innerHeight)-window.pageYOffset;
119 }
120 }
121 else if (document.all) {
122 x=coordinates.x-document.body.scrollLeft+window.screenLeft;
123 y=coordinates.y-document.body.scrollTop+window.screenTop;
124 }
125 else if (document.layers) {
126 x=coordinates.x+window.screenX+(window.outerWidth-window.innerWidth)-window.pageXOffset;
127 y=coordinates.y+window.screenY+(window.outerHeight-24-window.innerHeight)-window.pageYOffset;
128 }
129 coordinates.x=x;
130 coordinates.y=y;
131 return coordinates;
132 }
133
134 // Functions for IE to get position of an object
135 function AnchorPosition_getPageOffsetLeft (el) {
136 var ol=el.offsetLeft;
137 while ((el=el.offsetParent) != null) { ol += el.offsetLeft; }
138 return ol;
139 }
140 function AnchorPosition_getWindowOffsetLeft (el) {
141 return AnchorPosition_getPageOffsetLeft(el)-document.body.scrollLeft;
142 }
143 function AnchorPosition_getPageOffsetTop (el) {
144 var ot=el.offsetTop;
145 while((el=el.offsetParent) != null) { ot += el.offsetTop; }
146 return ot;
147 }
148 function AnchorPosition_getWindowOffsetTop (el) {
149 return AnchorPosition_getPageOffsetTop(el)-document.body.scrollTop;
150 }
151
152 /* SOURCE FILE: date.js */
153
154 // HISTORY
155 // ------------------------------------------------------------------
156 // May 17, 2003: Fixed bug in parseDate() for dates <1970
157 // March 11, 2003: Added parseDate() function
158 // March 11, 2003: Added "NNN" formatting option. Doesn't match up
159 // perfectly with SimpleDateFormat formats, but
160 // backwards-compatability was required.
161
162 // ------------------------------------------------------------------
163 // These functions use the same 'format' strings as the
164 // java.text.SimpleDateFormat class, with minor exceptions.
165 // The format string consists of the following abbreviations:
166 //
167 // Field | Full Form | Short Form
168 // -------------+--------------------+-----------------------
169 // Year | yyyy (4 digits) | yy (2 digits), y (2 or 4 digits)
170 // Month | MMM (name or abbr.)| MM (2 digits), M (1 or 2 digits)
171 // | NNN (abbr.) |
172 // Day of Month | dd (2 digits) | d (1 or 2 digits)
173 // Day of Week | EE (name) | E (abbr)
174 // Hour (1-12) | hh (2 digits) | h (1 or 2 digits)
175 // Hour (0-23) | HH (2 digits) | H (1 or 2 digits)
176 // Hour (0-11) | KK (2 digits) | K (1 or 2 digits)
177 // Hour (1-24) | kk (2 digits) | k (1 or 2 digits)
178 // Minute | mm (2 digits) | m (1 or 2 digits)
179 // Second | ss (2 digits) | s (1 or 2 digits)
180 // AM/PM | a |
181 //
182 // NOTE THE DIFFERENCE BETWEEN MM and mm! Month=MM, not mm!
183 // Examples:
184 // "MMM d, y" matches: January 01, 2000
185 // Dec 1, 1900
186 // Nov 20, 00
187 // "M/d/yy" matches: 01/20/00
188 // 9/2/00
189 // "MMM dd, yyyy hh:mm:ssa" matches: "January 01, 2000 12:30:45AM"
190 // ------------------------------------------------------------------
191
192 var MONTH_NAMES=new Array('January','February','March','April','May','June','July','August','September','October','November','December','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
193 var DAY_NAMES=new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sun','Mon','Tue','Wed','Thu','Fri','Sat');
194 function LZ(x) {return(x<0||x>9?"":"0")+x}
195
196 // ------------------------------------------------------------------
197 // isDate ( date_string, format_string )
198 // Returns true if date string matches format of format string and
199 // is a valid date. Else returns false.
200 // It is recommended that you trim whitespace around the value before
201 // passing it to this function, as whitespace is NOT ignored!
202 // ------------------------------------------------------------------
203 function isDate(val,format) {
204 var date=getDateFromFormat(val,format);
205 if (date==0) { return false; }
206 return true;
207 }
208
209 // -------------------------------------------------------------------
210 // compareDates(date1,date1format,date2,date2format)
211 // Compare two date strings to see which is greater.
212 // Returns:
213 // 1 if date1 is greater than date2
214 // 0 if date2 is greater than date1 of if they are the same
215 // -1 if either of the dates is in an invalid format
216 // -------------------------------------------------------------------
217 function compareDates(date1,dateformat1,date2,dateformat2) {
218 var d1=getDateFromFormat(date1,dateformat1);
219 var d2=getDateFromFormat(date2,dateformat2);
220 if (d1==0 || d2==0) {
221 return -1;
222 }
223 else if (d1 > d2) {
224 return 1;
225 }
226 return 0;
227 }
228
229 // ------------------------------------------------------------------
230 // formatDate (date_object, format)
231 // Returns a date in the output format specified.
232 // The format string uses the same abbreviations as in getDateFromFormat()
233 // ------------------------------------------------------------------
234 function formatDate(date,format) {
235 format=format+"";
236 var result="";
237 var i_format=0;
238 var c="";
239 var token="";
240 var y=date.getYear()+"";
241 var M=date.getMonth()+1;
242 var d=date.getDate();
243 var E=date.getDay();
244 var H=date.getHours();
245 var m=date.getMinutes();
246 var s=date.getSeconds();
247 var yyyy,yy,MMM,MM,dd,hh,h,mm,ss,ampm,HH,H,KK,K,kk,k;
248 // Convert real date parts into formatted versions
249 var value=new Object();
250 if (y.length < 4) {y=""+(y-0+1900);}
251 value["y"]=""+y;
252 value["yyyy"]=y;
253 value["yy"]=y.substring(2,4);
254 value["M"]=M;
255 value["MM"]=LZ(M);
256 value["MMM"]=MONTH_NAMES[M-1];
257 value["NNN"]=MONTH_NAMES[M+11];
258 value["d"]=d;
259 value["dd"]=LZ(d);
260 value["E"]=DAY_NAMES[E+7];
261 value["EE"]=DAY_NAMES[E];
262 value["H"]=H;
263 value["HH"]=LZ(H);
264 if (H==0){value["h"]=12;}
265 else if (H>12){value["h"]=H-12;}
266 else {value["h"]=H;}
267 value["hh"]=LZ(value["h"]);
268 if (H>11){value["K"]=H-12;} else {value["K"]=H;}
269 value["k"]=H+1;
270 value["KK"]=LZ(value["K"]);
271 value["kk"]=LZ(value["k"]);
272 if (H > 11) { value["a"]="PM"; }
273 else { value["a"]="AM"; }
274 value["m"]=m;
275 value["mm"]=LZ(m);
276 value["s"]=s;
277 value["ss"]=LZ(s);
278 while (i_format < format.length) {
279 c=format.charAt(i_format);
280 token="";
281 while ((format.charAt(i_format)==c) && (i_format < format.length)) {
282 token += format.charAt(i_format++);
283 }
284 if (value[token] != null) { result=result + value[token]; }
285 else { result=result + token; }
286 }
287 return result;
288 }
289
290 // ------------------------------------------------------------------
291 // Utility functions for parsing in getDateFromFormat()
292 // ------------------------------------------------------------------
293 function _isInteger(val) {
294 var digits="1234567890";
295 for (var i=0; i < val.length; i++) {
296 if (digits.indexOf(val.charAt(i))==-1) { return false; }
297 }
298 return true;
299 }
300 function _getInt(str,i,minlength,maxlength) {
301 for (var x=maxlength; x>=minlength; x--) {
302 var token=str.substring(i,i+x);
303 if (token.length < minlength) { return null; }
304 if (_isInteger(token)) { return token; }
305 }
306 return null;
307 }
308
309 // ------------------------------------------------------------------
310 // getDateFromFormat( date_string , format_string )
311 //
312 // This function takes a date string and a format string. It matches
313 // If the date string matches the format string, it returns the
314 // getTime() of the date. If it does not match, it returns 0.
315 // ------------------------------------------------------------------
316 function getDateFromFormat(val,format) {
317 val=val+"";
318 format=format+"";
319 var i_val=0;
320 var i_format=0;
321 var c="";
322 var token="";
323 var token2="";
324 var x,y;
325 var now=new Date();
326 var year=now.getYear();
327 var month=now.getMonth()+1;
328 var date=1;
329 var hh=now.getHours();
330 var mm=now.getMinutes();
331 var ss=now.getSeconds();
332 var ampm="";
333
334 while (i_format < format.length) {
335 // Get next token from format string
336 c=format.charAt(i_format);
337 token="";
338 while ((format.charAt(i_format)==c) && (i_format < format.length)) {
339 token += format.charAt(i_format++);
340 }
341 // Extract contents of value based on format token
342 if (token=="yyyy" || token=="yy" || token=="y") {
343 if (token=="yyyy") { x=4;y=4; }
344 if (token=="yy") { x=2;y=2; }
345 if (token=="y") { x=2;y=4; }
346 year=_getInt(val,i_val,x,y);
347 if (year==null) { return 0; }
348 i_val += year.length;
349 if (year.length==2) {
350 if (year > 70) { year=1900+(year-0); }
351 else { year=2000+(year-0); }
352 }
353 }
354 else if (token=="MMM"||token=="NNN"){
355 month=0;
356 for (var i=0; i<MONTH_NAMES.length; i++) {
357 var month_name=MONTH_NAMES[i];
358 if (val.substring(i_val,i_val+month_name.length).toLowerCase()==month_name.toLowerCase()) {
359 if (token=="MMM"||(token=="NNN"&&i>11)) {
360 month=i+1;
361 if (month>12) { month -= 12; }
362 i_val += month_name.length;
363 break;
364 }
365 }
366 }
367 if ((month < 1)||(month>12)){return 0;}
368 }
369 else if (token=="EE"||token=="E"){
370 for (var i=0; i<DAY_NAMES.length; i++) {
371 var day_name=DAY_NAMES[i];
372 if (val.substring(i_val,i_val+day_name.length).toLowerCase()==day_name.toLowerCase()) {
373 i_val += day_name.length;
374 break;
375 }
376 }
377 }
378 else if (token=="MM"||token=="M") {
379 month=_getInt(val,i_val,token.length,2);
380 if(month==null||(month<1)||(month>12)){return 0;}
381 i_val+=month.length;}
382 else if (token=="dd"||token=="d") {
383 date=_getInt(val,i_val,token.length,2);
384 if(date==null||(date<1)||(date>31)){return 0;}
385 i_val+=date.length;}
386 else if (token=="hh"||token=="h") {
387 hh=_getInt(val,i_val,token.length,2);
388 if(hh==null||(hh<1)||(hh>12)){return 0;}
389 i_val+=hh.length;}
390 else if (token=="HH"||token=="H") {
391 hh=_getInt(val,i_val,token.length,2);
392 if(hh==null||(hh<0)||(hh>23)){return 0;}
393 i_val+=hh.length;}
394 else if (token=="KK"||token=="K") {
395 hh=_getInt(val,i_val,token.length,2);
396 if(hh==null||(hh<0)||(hh>11)){return 0;}
397 i_val+=hh.length;}
398 else if (token=="kk"||token=="k") {
399 hh=_getInt(val,i_val,token.length,2);
400 if(hh==null||(hh<1)||(hh>24)){return 0;}
401 i_val+=hh.length;hh--;}
402 else if (token=="mm"||token=="m") {
403 mm=_getInt(val,i_val,token.length,2);
404 if(mm==null||(mm<0)||(mm>59)){return 0;}
405 i_val+=mm.length;}
406 else if (token=="ss"||token=="s") {
407 ss=_getInt(val,i_val,token.length,2);
408 if(ss==null||(ss<0)||(ss>59)){return 0;}
409 i_val+=ss.length;}
410 else if (token=="a") {
411 if (val.substring(i_val,i_val+2).toLowerCase()=="am") {ampm="AM";}
412 else if (val.substring(i_val,i_val+2).toLowerCase()=="pm") {ampm="PM";}
413 else {return 0;}
414 i_val+=2;}
415 else {
416 if (val.substring(i_val,i_val+token.length)!=token) {return 0;}
417 else {i_val+=token.length;}
418 }
419 }
420 // If there are any trailing characters left in the value, it doesn't match
421 if (i_val != val.length) { return 0; }
422 // Is date valid for month?
423 if (month==2) {
424 // Check for leap year
425 if ( ( (year%4==0)&&(year%100 != 0) ) || (year%400==0) ) { // leap year
426 if (date > 29){ return 0; }
427 }
428 else { if (date > 28) { return 0; } }
429 }
430 if ((month==4)||(month==6)||(month==9)||(month==11)) {
431 if (date > 30) { return 0; }
432 }
433 // Correct hours value
434 if (hh<12 && ampm=="PM") { hh=hh-0+12; }
435 else if (hh>11 && ampm=="AM") { hh-=12; }
436 var newdate=new Date(year,month-1,date,hh,mm,ss);
437 return newdate.getTime();
438 }
439
440 // ------------------------------------------------------------------
441 // parseDate( date_string [, prefer_euro_format] )
442 //
443 // This function takes a date string and tries to match it to a
444 // number of possible date formats to get the value. It will try to
445 // match against the following international formats, in this order:
446 // y-M-d MMM d, y MMM d,y y-MMM-d d-MMM-y MMM d
447 // M/d/y M-d-y M.d.y MMM-d M/d M-d
448 // d/M/y d-M-y d.M.y d-MMM d/M d-M
449 // A second argument may be passed to instruct the method to search
450 // for formats like d/M/y (european format) before M/d/y (American).
451 // Returns a Date object or null if no patterns match.
452 // ------------------------------------------------------------------
453 function parseDate(val) {
454 var preferEuro=(arguments.length==2)?arguments[1]:false;
455 generalFormats=new Array('y-M-d','MMM d, y','MMM d,y','y-MMM-d','d-MMM-y','MMM d');
456 monthFirst=new Array('M/d/y','M-d-y','M.d.y','MMM-d','M/d','M-d');
457 dateFirst =new Array('d/M/y','d-M-y','d.M.y','d-MMM','d/M','d-M');
458 var checkList=new Array('generalFormats',preferEuro?'dateFirst':'monthFirst',preferEuro?'monthFirst':'dateFirst');
459 var d=null;
460 for (var i=0; i<checkList.length; i++) {
461 var l=window[checkList[i]];
462 for (var j=0; j<l.length; j++) {
463 d=getDateFromFormat(val,l[j]);
464 if (d!=0) { return new Date(d); }
465 }
466 }
467 return null;
468 }
469
470 /* SOURCE FILE: PopupWindow.js */
471
472 /*
473 PopupWindow.js
474 Author: Matt Kruse
475 Last modified: 02/16/04
476
477 DESCRIPTION: This object allows you to easily and quickly popup a window
478 in a certain place. The window can either be a DIV or a separate browser
479 window.
480
481 COMPATABILITY: Works with Netscape 4.x, 6.x, IE 5.x on Windows. Some small
482 positioning errors - usually with Window positioning - occur on the
483 Macintosh platform. Due to bugs in Netscape 4.x, populating the popup
484 window with <STYLE> tags may cause errors.
485
486 USAGE:
487 // Create an object for a WINDOW popup
488 var win = new PopupWindow();
489
490 // Create an object for a DIV window using the DIV named 'mydiv'
491 var win = new PopupWindow('mydiv');
492
493 // Set the window to automatically hide itself when the user clicks
494 // anywhere else on the page except the popup
495 win.autoHide();
496
497 // Show the window relative to the anchor name passed in
498 win.showPopup(anchorname);
499
500 // Hide the popup
501 win.hidePopup();
502
503 // Set the size of the popup window (only applies to WINDOW popups
504 win.setSize(width,height);
505
506 // Populate the contents of the popup window that will be shown. If you
507 // change the contents while it is displayed, you will need to refresh()
508 win.populate(string);
509
510 // set the URL of the window, rather than populating its contents
511 // manually
512 win.setUrl("http://www.site.com/");
513
514 // Refresh the contents of the popup
515 win.refresh();
516
517 // Specify how many pixels to the right of the anchor the popup will appear
518 win.offsetX = 50;
519
520 // Specify how many pixels below the anchor the popup will appear
521 win.offsetY = 100;
522
523 NOTES:
524 1) Requires the functions in AnchorPosition.js
525
526 2) Your anchor tag MUST contain both NAME and ID attributes which are the
527 same. For example:
528 <A NAME="test" ID="test"> </A>
529
530 3) There must be at least a space between <A> </A> for IE5.5 to see the
531 anchor tag correctly. Do not do <A></A> with no space.
532
533 4) When a PopupWindow object is created, a handler for 'onmouseup' is
534 attached to any event handler you may have already defined. Do NOT define
535 an event handler for 'onmouseup' after you define a PopupWindow object or
536 the autoHide() will not work correctly.
537 */
538
539 // Set the position of the popup window based on the anchor
540 function PopupWindow_getXYPosition(anchorname) {
541 var coordinates;
542 if (this.type == "WINDOW") {
543 coordinates = getAnchorWindowPosition(anchorname);
544 }
545 else {
546 coordinates = getAnchorPosition(anchorname);
547 }
548 this.x = coordinates.x;
549 this.y = coordinates.y;
550 }
551 // Set width/height of DIV/popup window
552 function PopupWindow_setSize(width,height) {
553 this.width = width;
554 this.height = height;
555 }
556 // Fill the window with contents
557 function PopupWindow_populate(contents) {
558 this.contents = contents;
559 this.populated = false;
560 }
561 // Set the URL to go to
562 function PopupWindow_setUrl(url) {
563 this.url = url;
564 }
565 // Set the window popup properties
566 function PopupWindow_setWindowProperties(props) {
567 this.windowProperties = props;
568 }
569 // Refresh the displayed contents of the popup
570 function PopupWindow_refresh() {
571 if (this.divName != null) {
572 // refresh the DIV object
573 if (this.use_gebi) {
574 document.getElementById(this.divName).innerHTML = this.contents;
575 }
576 else if (this.use_css) {
577 document.all[this.divName].innerHTML = this.contents;
578 }
579 else if (this.use_layers) {
580 var d = document.layers[this.divName];
581 d.document.open();
582 d.document.writeln(this.contents);
583 d.document.close();
584 }
585 }
586 else {
587 if (this.popupWindow != null && !this.popupWindow.closed) {
588 if (this.url!="") {
589 this.popupWindow.location.href=this.url;
590 }
591 else {
592 this.popupWindow.document.open();
593 this.popupWindow.document.writeln(this.contents);
594 this.popupWindow.document.close();
595 }
596 this.popupWindow.focus();
597 }
598 }
599 }
600 // Position and show the popup, relative to an anchor object
601 function PopupWindow_showPopup(anchorname) {
602 this.getXYPosition(anchorname);
603 this.x += this.offsetX;
604 this.y += this.offsetY;
605 if (!this.populated && (this.contents != "")) {
606 this.populated = true;
607 this.refresh();
608 }
609 if (this.divName != null) {
610 // Show the DIV object
611 if (this.use_gebi) {
612 document.getElementById(this.divName).style.left = this.x + "px";
613 document.getElementById(this.divName).style.top = this.y + "px";
614 document.getElementById(this.divName).style.visibility = "visible";
615 }
616 else if (this.use_css) {
617 document.all[this.divName].style.left = this.x;
618 document.all[this.divName].style.top = this.y;
619 document.all[this.divName].style.visibility = "visible";
620 }
621 else if (this.use_layers) {
622 document.layers[this.divName].left = this.x;
623 document.layers[this.divName].top = this.y;
624 document.layers[this.divName].visibility = "visible";
625 }
626 }
627 else {
628 if (this.popupWindow == null || this.popupWindow.closed) {
629 // If the popup window will go off-screen, move it so it doesn't
630 if (this.x<0) { this.x=0; }
631 if (this.y<0) { this.y=0; }
632 if (screen && screen.availHeight) {
633 if ((this.y + this.height) > screen.availHeight) {
634 this.y = screen.availHeight - this.height;
635 }
636 }
637 if (screen && screen.availWidth) {
638 if ((this.x + this.width) > screen.availWidth) {
639 this.x = screen.availWidth - this.width;
640 }
641 }
642 var avoidAboutBlank = window.opera || ( document.layers && !navigator.mimeTypes['*'] ) || navigator.vendor == 'KDE' || ( document.childNodes && !document.all && !navigator.taintEnabled );
643 this.popupWindow = window.open(avoidAboutBlank?"":"about:blank","window_"+anchorname,this.windowProperties+",width="+this.width+",height="+this.height+",screenX="+this.x+",left="+this.x+",screenY="+this.y+",top="+this.y+"");
644 }
645 this.refresh();
646 }
647 }
648 // Hide the popup
649 function PopupWindow_hidePopup() {
650 if (this.divName != null) {
651 if (this.use_gebi) {
652 document.getElementById(this.divName).style.visibility = "hidden";
653 }
654 else if (this.use_css) {
655 document.all[this.divName].style.visibility = "hidden";
656 }
657 else if (this.use_layers) {
658 document.layers[this.divName].visibility = "hidden";
659 }
660 }
661 else {
662 if (this.popupWindow && !this.popupWindow.closed) {
663 this.popupWindow.close();
664 this.popupWindow = null;
665 }
666 }
667 }
668 // Pass an event and return whether or not it was the popup DIV that was clicked
669 function PopupWindow_isClicked(e) {
670 if (this.divName != null) {
671 if (this.use_layers) {
672 var clickX = e.pageX;
673 var clickY = e.pageY;
674 var t = document.layers[this.divName];
675 if ((clickX > t.left) && (clickX < t.left+t.clip.width) && (clickY > t.top) && (clickY < t.top+t.clip.height)) {
676 return true;
677 }
678 else { return false; }
679 }
680 else if (document.all) { // Need to hard-code this to trap IE for error-handling
681 var t = window.event.srcElement;
682 while (t.parentElement != null) {
683 if (t.id==this.divName) {
684 return true;
685 }
686 t = t.parentElement;
687 }
688 return false;
689 }
690 else if (this.use_gebi && e) {
691 var t = e.originalTarget;
692 while (t.parentNode != null) {
693 if (t.id==this.divName) {
694 return true;
695 }
696 t = t.parentNode;
697 }
698 return false;
699 }
700 return false;
701 }
702 return false;
703 }
704
705 // Check an onMouseDown event to see if we should hide
706 function PopupWindow_hideIfNotClicked(e) {
707 if (this.autoHideEnabled && !this.isClicked(e)) {
708 this.hidePopup();
709 }
710 }
711 // Call this to make the DIV disable automatically when mouse is clicked outside it
712 function PopupWindow_autoHide() {
713 this.autoHideEnabled = true;
714 }
715 // This global function checks all PopupWindow objects onmouseup to see if they should be hidden
716 function PopupWindow_hidePopupWindows(e) {
717 for (var i=0; i<popupWindowObjects.length; i++) {
718 if (popupWindowObjects[i] != null) {
719 var p = popupWindowObjects[i];
720 p.hideIfNotClicked(e);
721 }
722 }
723 }
724 // Run this immediately to attach the event listener
725 function PopupWindow_attachListener() {
726 if (document.layers) {
727 document.captureEvents(Event.MOUSEUP);
728 }
729 window.popupWindowOldEventListener = document.onmouseup;
730 if (window.popupWindowOldEventListener != null) {
731 document.onmouseup = new Function("window.popupWindowOldEventListener(); PopupWindow_hidePopupWindows();");
732 }
733 else {
734 document.onmouseup = PopupWindow_hidePopupWindows;
735 }
736 }
737 // CONSTRUCTOR for the PopupWindow object
738 // Pass it a DIV name to use a DHTML popup, otherwise will default to window popup
739 function PopupWindow() {
740 if (!window.popupWindowIndex) { window.popupWindowIndex = 0; }
741 if (!window.popupWindowObjects) { window.popupWindowObjects = new Array(); }
742 if (!window.listenerAttached) {
743 window.listenerAttached = true;
744 PopupWindow_attachListener();
745 }
746 this.index = popupWindowIndex++;
747 popupWindowObjects[this.index] = this;
748 this.divName = null;
749 this.popupWindow = null;
750 this.width=0;
751 this.height=0;
752 this.populated = false;
753 this.visible = false;
754 this.autoHideEnabled = false;
755
756 this.contents = "";
757 this.url="";
758 this.windowProperties="toolbar=no,location=no,status=no,menubar=no,scrollbars=auto,resizable,alwaysRaised,dependent,titlebar=no";
759 if (arguments.length>0) {
760 this.type="DIV";
761 this.divName = arguments[0];
762 }
763 else {
764 this.type="WINDOW";
765 }
766 this.use_gebi = false;
767 this.use_css = false;
768 this.use_layers = false;
769 if (document.getElementById) { this.use_gebi = true; }
770 else if (document.all) { this.use_css = true; }
771 else if (document.layers) { this.use_layers = true; }
772 else { this.type = "WINDOW"; }
773 this.offsetX = 0;
774 this.offsetY = 0;
775 // Method mappings
776 this.getXYPosition = PopupWindow_getXYPosition;
777 this.populate = PopupWindow_populate;
778 this.setUrl = PopupWindow_setUrl;
779 this.setWindowProperties = PopupWindow_setWindowProperties;
780 this.refresh = PopupWindow_refresh;
781 this.showPopup = PopupWindow_showPopup;
782 this.hidePopup = PopupWindow_hidePopup;
783 this.setSize = PopupWindow_setSize;
784 this.isClicked = PopupWindow_isClicked;
785 this.autoHide = PopupWindow_autoHide;
786 this.hideIfNotClicked = PopupWindow_hideIfNotClicked;
787 }
788
789 /* SOURCE FILE: CalendarPopup.js */
790
791 // HISTORY
792 // ------------------------------------------------------------------
793 // Feb 7, 2005: Fixed a CSS styles to use px unit
794 // March 29, 2004: Added check in select() method for the form field
795 // being disabled. If it is, just return and don't do anything.
796 // March 24, 2004: Fixed bug - when month name and abbreviations were
797 // changed, date format still used original values.
798 // January 26, 2004: Added support for drop-down month and year
799 // navigation (Thanks to Chris Reid for the idea)
800 // September 22, 2003: Fixed a minor problem in YEAR calendar with
801 // CSS prefix.
802 // August 19, 2003: Renamed the function to get styles, and made it
803 // work correctly without an object reference
804 // August 18, 2003: Changed showYearNavigation and
805 // showYearNavigationInput to optionally take an argument of
806 // true or false
807 // July 31, 2003: Added text input option for year navigation.
808 // Added a per-calendar CSS prefix option to optionally use
809 // different styles for different calendars.
810 // July 29, 2003: Fixed bug causing the Today link to be clickable
811 // even though today falls in a disabled date range.
812 // Changed formatting to use pure CSS, allowing greater control
813 // over look-and-feel options.
814 // June 11, 2003: Fixed bug causing the Today link to be unselectable
815 // under certain cases when some days of week are disabled
816 // March 14, 2003: Added ability to disable individual dates or date
817 // ranges, display as light gray and strike-through
818 // March 14, 2003: Removed dependency on graypixel.gif and instead
819 /// use table border coloring
820 // March 12, 2003: Modified showCalendar() function to allow optional
821 // start-date parameter
822 // March 11, 2003: Modified select() function to allow optional
823 // start-date parameter
824 /*
825 DESCRIPTION: This object implements a popup calendar to allow the user to
826 select a date, month, quarter, or year.
827
828 COMPATABILITY: Works with Netscape 4.x, 6.x, IE 5.x on Windows. Some small
829 positioning errors - usually with Window positioning - occur on the
830 Macintosh platform.
831 The calendar can be modified to work for any location in the world by
832 changing which weekday is displayed as the first column, changing the month
833 names, and changing the column headers for each day.
834
835 USAGE:
836 // Create a new CalendarPopup object of type WINDOW
837 var cal = new CalendarPopup();
838
839 // Create a new CalendarPopup object of type DIV using the DIV named 'mydiv'
840 var cal = new CalendarPopup('mydiv');
841
842 // Easy method to link the popup calendar with an input box.
843 cal.select(inputObject, anchorname, dateFormat);
844 // Same method, but passing a default date other than the field's current value
845 cal.select(inputObject, anchorname, dateFormat, '01/02/2000');
846 // This is an example call to the popup calendar from a link to populate an
847 // input box. Note that to use this, date.js must also be included!!
848 <A HREF="#" onClick="cal.select(document.forms[0].date,'anchorname','MM/dd/yyyy'); return false;">Select</A>
849
850 // Set the type of date select to be used. By default it is 'date'.
851 cal.setDisplayType(type);
852
853 // When a date, month, quarter, or year is clicked, a function is called and
854 // passed the details. You must write this function, and tell the calendar
855 // popup what the function name is.
856 // Function to be called for 'date' select receives y, m, d
857 cal.setReturnFunction(functionname);
858 // Function to be called for 'month' select receives y, m
859 cal.setReturnMonthFunction(functionname);
860 // Function to be called for 'quarter' select receives y, q
861 cal.setReturnQuarterFunction(functionname);
862 // Function to be called for 'year' select receives y
863 cal.setReturnYearFunction(functionname);
864
865 // Show the calendar relative to a given anchor
866 cal.showCalendar(anchorname);
867
868 // Hide the calendar. The calendar is set to autoHide automatically
869 cal.hideCalendar();
870
871 // Set the month names to be used. Default are English month names
872 cal.setMonthNames("January","February","March",...);
873
874 // Set the month abbreviations to be used. Default are English month abbreviations
875 cal.setMonthAbbreviations("Jan","Feb","Mar",...);
876
877 // Show navigation for changing by the year, not just one month at a time
878 cal.showYearNavigation();
879
880 // Show month and year dropdowns, for quicker selection of month of dates
881 cal.showNavigationDropdowns();
882
883 // Set the text to be used above each day column. The days start with
884 // sunday regardless of the value of WeekStartDay
885 cal.setDayHeaders("S","M","T",...);
886
887 // Set the day for the first column in the calendar grid. By default this
888 // is Sunday (0) but it may be changed to fit the conventions of other
889 // countries.
890 cal.setWeekStartDay(1); // week is Monday - Sunday
891
892 // Set the weekdays which should be disabled in the 'date' select popup. You can
893 // then allow someone to only select week end dates, or Tuedays, for example
894 cal.setDisabledWeekDays(0,1); // To disable selecting the 1st or 2nd days of the week
895
896 // Selectively disable individual days or date ranges. Disabled days will not
897 // be clickable, and show as strike-through text on current browsers.
898 // Date format is any format recognized by parseDate() in date.js
899 // Pass a single date to disable:
900 cal.addDisabledDates("2003-01-01");
901 // Pass null as the first parameter to mean "anything up to and including" the
902 // passed date:
903 cal.addDisabledDates(null, "01/02/03");
904 // Pass null as the second parameter to mean "including the passed date and
905 // anything after it:
906 cal.addDisabledDates("Jan 01, 2003", null);
907 // Pass two dates to disable all dates inbetween and including the two
908 cal.addDisabledDates("January 01, 2003", "Dec 31, 2003");
909
910 // When the 'year' select is displayed, set the number of years back from the
911 // current year to start listing years. Default is 2.
912 // This is also used for year drop-down, to decide how many years +/- to display
913 cal.setYearSelectStartOffset(2);
914
915 // Text for the word "Today" appearing on the calendar
916 cal.setTodayText("Today");
917
918 // The calendar uses CSS classes for formatting. If you want your calendar to
919 // have unique styles, you can set the prefix that will be added to all the
920 // classes in the output.
921 // For example, normal output may have this:
922 // <SPAN CLASS="cpTodayTextDisabled">Today<SPAN>
923 // But if you set the prefix like this:
924 cal.setCssPrefix("Test");
925 // The output will then look like:
926 // <SPAN CLASS="TestcpTodayTextDisabled">Today<SPAN>
927 // And you can define that style somewhere in your page.
928
929 // When using Year navigation, you can make the year be an input box, so
930 // the user can manually change it and jump to any year
931 cal.showYearNavigationInput();
932
933 // Set the calendar offset to be different than the default. By default it
934 // will appear just below and to the right of the anchorname. So if you have
935 // a text box where the date will go and and anchor immediately after the
936 // text box, the calendar will display immediately under the text box.
937 cal.offsetX = 20;
938 cal.offsetY = 20;
939
940 NOTES:
941 1) Requires the functions in AnchorPosition.js and PopupWindow.js
942
943 2) Your anchor tag MUST contain both NAME and ID attributes which are the
944 same. For example:
945 <A NAME="test" ID="test"> </A>
946
947 3) There must be at least a space between <A> </A> for IE5.5 to see the
948 anchor tag correctly. Do not do <A></A> with no space.
949
950 4) When a CalendarPopup object is created, a handler for 'onmouseup' is
951 attached to any event handler you may have already defined. Do NOT define
952 an event handler for 'onmouseup' after you define a CalendarPopup object
953 or the autoHide() will not work correctly.
954
955 5) The calendar popup display uses style sheets to make it look nice.
956
957 */
958
959 // CONSTRUCTOR for the CalendarPopup Object
960 function CalendarPopup() {
961 var c;
962 if (arguments.length>0) {
963 c = new PopupWindow(arguments[0]);
964 }
965 else {
966 c = new PopupWindow();
967 c.setSize(150,175);
968 }
969 c.offsetX = -152;
970 c.offsetY = 25;
971 c.autoHide();
972 // Calendar-specific properties
973 c.monthNames = new Array("January","February","March","April","May","June","July","August","September","October","November","December");
974 c.monthAbbreviations = new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");
975 c.dayHeaders = new Array("S","M","T","W","T","F","S");
976 c.returnFunction = "CP_tmpReturnFunction";
977 c.returnMonthFunction = "CP_tmpReturnMonthFunction";
978 c.returnQuarterFunction = "CP_tmpReturnQuarterFunction";
979 c.returnYearFunction = "CP_tmpReturnYearFunction";
980 c.weekStartDay = 0;
981 c.isShowYearNavigation = false;
982 c.displayType = "date";
983 c.disabledWeekDays = new Object();
984 c.disabledDatesExpression = "";
985 c.yearSelectStartOffset = 2;
986 c.currentDate = null;
987 c.todayText="Today";
988 c.cssPrefix="";
989 c.isShowNavigationDropdowns=false;
990 c.isShowYearNavigationInput=false;
991 window.CP_calendarObject = null;
992 window.CP_targetInput = null;
993 window.CP_dateFormat = "MM/dd/yyyy";
994 // Method mappings
995 c.copyMonthNamesToWindow = CP_copyMonthNamesToWindow;
996 c.setReturnFunction = CP_setReturnFunction;
997 c.setReturnMonthFunction = CP_setReturnMonthFunction;
998 c.setReturnQuarterFunction = CP_setReturnQuarterFunction;
999 c.setReturnYearFunction = CP_setReturnYearFunction;
1000 c.setMonthNames = CP_setMonthNames;
1001 c.setMonthAbbreviations = CP_setMonthAbbreviations;
1002 c.setDayHeaders = CP_setDayHeaders;
1003 c.setWeekStartDay = CP_setWeekStartDay;
1004 c.setDisplayType = CP_setDisplayType;
1005 c.setDisabledWeekDays = CP_setDisabledWeekDays;
1006 c.addDisabledDates = CP_addDisabledDates;
1007 c.setYearSelectStartOffset = CP_setYearSelectStartOffset;
1008 c.setTodayText = CP_setTodayText;
1009 c.showYearNavigation = CP_showYearNavigation;
1010 c.showCalendar = CP_showCalendar;
1011 c.hideCalendar = CP_hideCalendar;
1012 c.getStyles = getCalendarStyles;
1013 c.refreshCalendar = CP_refreshCalendar;
1014 c.getCalendar = CP_getCalendar;
1015 c.select = CP_select;
1016 c.setCssPrefix = CP_setCssPrefix;
1017 c.showNavigationDropdowns = CP_showNavigationDropdowns;
1018 c.showYearNavigationInput = CP_showYearNavigationInput;
1019 c.copyMonthNamesToWindow();
1020 // Return the object
1021 return c;
1022 }
1023 function CP_copyMonthNamesToWindow() {
1024 // Copy these values over to the date.js
1025 if (typeof(window.MONTH_NAMES)!="undefined" && window.MONTH_NAMES!=null) {
1026 window.MONTH_NAMES = new Array();
1027 for (var i=0; i<this.monthNames.length; i++) {
1028 window.MONTH_NAMES[window.MONTH_NAMES.length] = this.monthNames[i];
1029 }
1030 for (var i=0; i<this.monthAbbreviations.length; i++) {
1031 window.MONTH_NAMES[window.MONTH_NAMES.length] = this.monthAbbreviations[i];
1032 }
1033 }
1034 }
1035 // Temporary default functions to be called when items clicked, so no error is thrown
1036 function CP_tmpReturnFunction(y,m,d) {
1037 if (window.CP_targetInput!=null) {
1038 var dt = new Date(y,m-1,d,0,0,0);
1039 if (window.CP_calendarObject!=null) { window.CP_calendarObject.copyMonthNamesToWindow(); }
1040 window.CP_targetInput.value = formatDate(dt,window.CP_dateFormat);
1041 // Kieran - fixed issue with end date not becoming begin date after begin date is set
1042 if (CP_targetInput.name == 'event_begin') {
1043 document.forms['quoteform'].event_end.value = formatDate(dt,window.CP_dateFormat);
1044 }
1045 }
1046 else {
1047 alert('Use setReturnFunction() to define which function will get the clicked results!');
1048 }
1049 }
1050 function CP_tmpReturnMonthFunction(y,m) {
1051 alert('Use setReturnMonthFunction() to define which function will get the clicked results!\nYou clicked: year='+y+' , month='+m);
1052 }
1053 function CP_tmpReturnQuarterFunction(y,q) {
1054 alert('Use setReturnQuarterFunction() to define which function will get the clicked results!\nYou clicked: year='+y+' , quarter='+q);
1055 }
1056 function CP_tmpReturnYearFunction(y) {
1057 alert('Use setReturnYearFunction() to define which function will get the clicked results!\nYou clicked: year='+y);
1058 }
1059
1060 // Set the name of the functions to call to get the clicked item
1061 function CP_setReturnFunction(name) { this.returnFunction = name; }
1062 function CP_setReturnMonthFunction(name) { this.returnMonthFunction = name; }
1063 function CP_setReturnQuarterFunction(name) { this.returnQuarterFunction = name; }
1064 function CP_setReturnYearFunction(name) { this.returnYearFunction = name; }
1065
1066 // Over-ride the built-in month names
1067 function CP_setMonthNames() {
1068 for (var i=0; i<arguments.length; i++) { this.monthNames[i] = arguments[i]; }
1069 this.copyMonthNamesToWindow();
1070 }
1071
1072 // Over-ride the built-in month abbreviations
1073 function CP_setMonthAbbreviations() {
1074 for (var i=0; i<arguments.length; i++) { this.monthAbbreviations[i] = arguments[i]; }
1075 this.copyMonthNamesToWindow();
1076 }
1077
1078 // Over-ride the built-in column headers for each day
1079 function CP_setDayHeaders() {
1080 for (var i=0; i<arguments.length; i++) { this.dayHeaders[i] = arguments[i]; }
1081 }
1082
1083 // Set the day of the week (0-7) that the calendar display starts on
1084 // This is for countries other than the US whose calendar displays start on Monday(1), for example
1085 function CP_setWeekStartDay(day) { this.weekStartDay = day; }
1086
1087 // Show next/last year navigation links
1088 function CP_showYearNavigation() { this.isShowYearNavigation = (arguments.length>0)?arguments[0]:true; }
1089
1090 // Which type of calendar to display
1091 function CP_setDisplayType(type) {
1092 if (type!="date"&&type!="week-end"&&type!="month"&&type!="quarter"&&type!="year") { alert("Invalid display type! Must be one of: date,week-end,month,quarter,year"); return false; }
1093 this.displayType=type;
1094 }
1095
1096 // How many years back to start by default for year display
1097 function CP_setYearSelectStartOffset(num) { this.yearSelectStartOffset=num; }
1098
1099 // Set which weekdays should not be clickable
1100 function CP_setDisabledWeekDays() {
1101 this.disabledWeekDays = new Object();
1102 for (var i=0; i<arguments.length; i++) { this.disabledWeekDays[arguments[i]] = true; }
1103 }
1104
1105 // Disable individual dates or ranges
1106 // Builds an internal logical test which is run via eval() for efficiency
1107 function CP_addDisabledDates(start, end) {
1108 if (arguments.length==1) { end=start; }
1109 if (start==null && end==null) { return; }
1110 if (this.disabledDatesExpression!="") { this.disabledDatesExpression+= "||"; }
1111 if (start!=null) { start = parseDate(start); start=""+start.getFullYear()+LZ(start.getMonth()+1)+LZ(start.getDate());}
1112 if (end!=null) { end=parseDate(end); end=""+end.getFullYear()+LZ(end.getMonth()+1)+LZ(end.getDate());}
1113 if (start==null) { this.disabledDatesExpression+="(ds<="+end+")"; }
1114 else if (end ==null) { this.disabledDatesExpression+="(ds>="+start+")"; }
1115 else { this.disabledDatesExpression+="(ds>="+start+"&&ds<="+end+")"; }
1116 }
1117
1118 // Set the text to use for the "Today" link
1119 function CP_setTodayText(text) {
1120 this.todayText = text;
1121 }
1122
1123 // Set the prefix to be added to all CSS classes when writing output
1124 function CP_setCssPrefix(val) {
1125 this.cssPrefix = val;
1126 }
1127
1128 // Show the navigation as an dropdowns that can be manually changed
1129 function CP_showNavigationDropdowns() { this.isShowNavigationDropdowns = (arguments.length>0)?arguments[0]:true; }
1130
1131 // Show the year navigation as an input box that can be manually changed
1132 function CP_showYearNavigationInput() { this.isShowYearNavigationInput = (arguments.length>0)?arguments[0]:true; }
1133
1134 // Hide a calendar object
1135 function CP_hideCalendar() {
1136 if (arguments.length > 0) { window.popupWindowObjects[arguments[0]].hidePopup(); }
1137 else { this.hidePopup(); }
1138 }
1139
1140 // Refresh the contents of the calendar display
1141 function CP_refreshCalendar(index) {
1142 var calObject = window.popupWindowObjects[index];
1143 if (arguments.length>1) {
1144 calObject.populate(calObject.getCalendar(arguments[1],arguments[2],arguments[3],arguments[4],arguments[5]));
1145 }
1146 else {
1147 calObject.populate(calObject.getCalendar());
1148 }
1149 calObject.refresh();
1150 }
1151
1152 // Populate the calendar and display it
1153 function CP_showCalendar(anchorname) {
1154 if (arguments.length>1) {
1155 if (arguments[1]==null||arguments[1]=="") {
1156 this.currentDate=new Date();
1157 }
1158 else {
1159 this.currentDate=new Date(parseDate(arguments[1]));
1160 }
1161 }
1162 this.populate(this.getCalendar());
1163 this.showPopup(anchorname);
1164 }
1165
1166 // Simple method to interface popup calendar with a text-entry box
1167 function CP_select(inputobj, linkname, format) {
1168 var selectedDate=(arguments.length>3)?arguments[3]:null;
1169 if (!window.getDateFromFormat) {
1170 alert("calendar.select: To use this method you must also include 'date.js' for date formatting");
1171 return;
1172 }
1173 if (this.displayType!="date"&&this.displayType!="week-end") {
1174 alert("calendar.select: This function can only be used with displayType 'date' or 'week-end'");
1175 return;
1176 }
1177 if (inputobj.type!="text" && inputobj.type!="hidden" && inputobj.type!="textarea") {
1178 alert("calendar.select: Input object passed is not a valid form input object");
1179 window.CP_targetInput=null;
1180 return;
1181 }
1182 if (inputobj.disabled) { return; } // Can't use calendar input on disabled form input!
1183 window.CP_targetInput = inputobj;
1184 window.CP_calendarObject = this;
1185 this.currentDate=null;
1186 var time=0;
1187 if (selectedDate!=null) {
1188 time = getDateFromFormat(selectedDate,format)
1189 }
1190 else if (inputobj.value!="") {
1191 time = getDateFromFormat(inputobj.value,format);
1192 }
1193 if (selectedDate!=null || inputobj.value!="") {
1194 if (time==0) { this.currentDate=null; }
1195 else { this.currentDate=new Date(time); }
1196 }
1197 window.CP_dateFormat = format;
1198 this.showCalendar(linkname);
1199 }
1200
1201 // Get style block needed to display the calendar correctly
1202 function getCalendarStyles() {
1203 var result = "";
1204 var p = "";
1205 if (this!=null && typeof(this.cssPrefix)!="undefined" && this.cssPrefix!=null && this.cssPrefix!="") { p=this.cssPrefix; }
1206 result += "<STYLE>\n";
1207 result += "."+p+"cpYearNavigation,."+p+"cpMonthNavigation { background-color:#C0C0C0; text-align:center; vertical-align:center; text-decoration:none; color:#000000; font-weight:bold; }\n";
1208 result += "."+p+"cpDayColumnHeader, ."+p+"cpYearNavigation,."+p+"cpMonthNavigation,."+p+"cpCurrentMonthDate,."+p+"cpCurrentMonthDateDisabled,."+p+"cpOtherMonthDate,."+p+"cpOtherMonthDateDisabled,."+p+"cpCurrentDate,."+p+"cpCurrentDateDisabled,."+p+"cpTodayText,."+p+"cpTodayTextDisabled,."+p+"cpText { font-family:arial; font-size:8pt; }\n";
1209 result += "TD."+p+"cpDayColumnHeader { text-align:right; border:solid thin #C0C0C0;border-width:0px 0px 1px 0px; }\n";
1210 result += "."+p+"cpCurrentMonthDate, ."+p+"cpOtherMonthDate, ."+p+"cpCurrentDate { text-align:right; text-decoration:none; }\n";
1211 result += "."+p+"cpCurrentMonthDateDisabled, ."+p+"cpOtherMonthDateDisabled, ."+p+"cpCurrentDateDisabled { color:#D0D0D0; text-align:right; text-decoration:line-through; }\n";
1212 result += "."+p+"cpCurrentMonthDate, .cpCurrentDate { color:#000000; }\n";
1213 result += "."+p+"cpOtherMonthDate { color:#808080; }\n";
1214 result += "TD."+p+"cpCurrentDate { color:white; background-color: #C0C0C0; border-width:1px; border:solid thin #800000; }\n";
1215 result += "TD."+p+"cpCurrentDateDisabled { border-width:1px; border:solid thin #FFAAAA; }\n";
1216 result += "TD."+p+"cpTodayText, TD."+p+"cpTodayTextDisabled { border:solid thin #C0C0C0; border-width:1px 0px 0px 0px;}\n";
1217 result += "A."+p+"cpTodayText, SPAN."+p+"cpTodayTextDisabled { height:20px; }\n";
1218 result += "A."+p+"cpTodayText { color:black; }\n";
1219 result += "."+p+"cpTodayTextDisabled { color:#D0D0D0; }\n";
1220 result += "."+p+"cpBorder { border:solid thin #808080; }\n";
1221 result += "</STYLE>\n";
1222 return result;
1223 }
1224
1225 // Return a string containing all the calendar code to be displayed
1226 function CP_getCalendar() {
1227 var now = new Date();
1228 // Reference to window
1229 if (this.type == "WINDOW") { var windowref = "window.opener."; }
1230 else { var windowref = ""; }
1231 var result = "";
1232 // If POPUP, write entire HTML document
1233 if (this.type == "WINDOW") {
1234 result += "<HTML><HEAD><TITLE>Calendar</TITLE>"+this.getStyles()+"</HEAD><BODY MARGINWIDTH=0 MARGINHEIGHT=0 TOPMARGIN=0 RIGHTMARGIN=0 LEFTMARGIN=0>\n";
1235 result += '<CENTER><TABLE WIDTH=100% BORDER=0 BORDERWIDTH=0 CELLSPACING=0 CELLPADDING=0>\n';
1236 }
1237 else {
1238 result += '<TABLE CLASS="'+this.cssPrefix+'cpBorder" WIDTH=144 BORDER=1 BORDERWIDTH=1 CELLSPACING=0 CELLPADDING=1>\n';
1239 result += '<TR><TD ALIGN=CENTER>\n';
1240 result += '<CENTER>\n';
1241 }
1242 // Code for DATE display (default)
1243 // -------------------------------
1244 if (this.displayType=="date" || this.displayType=="week-end") {
1245 if (this.currentDate==null) { this.currentDate = now; }
1246 if (arguments.length > 0) { var month = arguments[0]; }
1247 else { var month = this.currentDate.getMonth()+1; }
1248 if (arguments.length > 1 && arguments[1]>0 && arguments[1]-0==arguments[1]) { var year = arguments[1]; }
1249 else { var year = this.currentDate.getFullYear(); }
1250 var daysinmonth= new Array(0,31,28,31,30,31,30,31,31,30,31,30,31);
1251 if ( ( (year%4 == 0)&&(year%100 != 0) ) || (year%400 == 0) ) {
1252 daysinmonth[2] = 29;
1253 }
1254 var current_month = new Date(year,month-1,1);
1255 var display_year = year;
1256 var display_month = month;
1257 var display_date = 1;
1258 var weekday= current_month.getDay();
1259 var offset = 0;
1260
1261 offset = (weekday >= this.weekStartDay) ? weekday-this.weekStartDay : 7-this.weekStartDay+weekday ;
1262 if (offset > 0) {
1263 display_month--;
1264 if (display_month < 1) { display_month = 12; display_year--; }
1265 display_date = daysinmonth[display_month]-offset+1;
1266 }
1267 var next_month = month+1;
1268 var next_month_year = year;
1269 if (next_month > 12) { next_month=1; next_month_year++; }
1270 var last_month = month-1;
1271 var last_month_year = year;
1272 if (last_month < 1) { last_month=12; last_month_year--; }
1273 var date_class;
1274 if (this.type!="WINDOW") {
1275 result += "<TABLE WIDTH=144 BORDER=0 BORDERWIDTH=0 CELLSPACING=0 CELLPADDING=0>";
1276 }
1277 result += '<TR>\n';
1278 var refresh = windowref+'CP_refreshCalendar';
1279 var refreshLink = 'javascript:' + refresh;
1280 if (this.isShowNavigationDropdowns) {
1281 result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="78" COLSPAN="3"><select CLASS="'+this.cssPrefix+'cpMonthNavigation" name="cpMonth" onChange="'+refresh+'('+this.index+',this.options[this.selectedIndex].value-0,'+(year-0)+');">';
1282 for( var monthCounter=1; monthCounter<=12; monthCounter++ ) {
1283 var selected = (monthCounter==month) ? 'SELECTED' : '';
1284 result += '<option value="'+monthCounter+'" '+selected+'>'+this.monthNames[monthCounter-1]+'</option>';
1285 }
1286 result += '</select></TD>';
1287 result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="10">&nbsp;</TD>';
1288
1289 result += '<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="56" COLSPAN="3"><select CLASS="'+this.cssPrefix+'cpYearNavigation" name="cpYear" onChange="'+refresh+'('+this.index+','+month+',this.options[this.selectedIndex].value-0);">';
1290 for( var yearCounter=year-this.yearSelectStartOffset; yearCounter<=year+this.yearSelectStartOffset; yearCounter++ ) {
1291 var selected = (yearCounter==year) ? 'SELECTED' : '';
1292 result += '<option value="'+yearCounter+'" '+selected+'>'+yearCounter+'</option>';
1293 }
1294 result += '</select></TD>';
1295 }
1296 else {
1297 if (this.isShowYearNavigation) {
1298 result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="10"><A CLASS="'+this.cssPrefix+'cpMonthNavigation" HREF="'+refreshLink+'('+this.index+','+last_month+','+last_month_year+');">&lt;</A></TD>';
1299 result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="58"><SPAN CLASS="'+this.cssPrefix+'cpMonthNavigation">'+this.monthNames[month-1]+'</SPAN></TD>';
1300 result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="10"><A CLASS="'+this.cssPrefix+'cpMonthNavigation" HREF="'+refreshLink+'('+this.index+','+next_month+','+next_month_year+');">&gt;</A></TD>';
1301 result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="10">&nbsp;</TD>';
1302
1303 result += '<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="10"><A CLASS="'+this.cssPrefix+'cpYearNavigation" HREF="'+refreshLink+'('+this.index+','+month+','+(year-1)+');">&lt;</A></TD>';
1304 if (this.isShowYearNavigationInput) {
1305 result += '<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="36"><INPUT NAME="cpYear" CLASS="'+this.cssPrefix+'cpYearNavigation" SIZE="4" MAXLENGTH="4" VALUE="'+year+'" onBlur="'+refresh+'('+this.index+','+month+',this.value-0);"></TD>';
1306 }
1307 else {
1308 result += '<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="36"><SPAN CLASS="'+this.cssPrefix+'cpYearNavigation">'+year+'</SPAN></TD>';
1309 }
1310 result += '<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="10"><A CLASS="'+this.cssPrefix+'cpYearNavigation" HREF="'+refreshLink+'('+this.index+','+month+','+(year+1)+');">&gt;</A></TD>';
1311 }
1312 else {
1313 result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="22"><A CLASS="'+this.cssPrefix+'cpMonthNavigation" HREF="'+refreshLink+'('+this.index+','+last_month+','+last_month_year+');">&lt;&lt;</A></TD>\n';
1314 result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="100"><SPAN CLASS="'+this.cssPrefix+'cpMonthNavigation">'+this.monthNames[month-1]+' '+year+'</SPAN></TD>\n';
1315 result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="22"><A CLASS="'+this.cssPrefix+'cpMonthNavigation" HREF="'+refreshLink+'('+this.index+','+next_month+','+next_month_year+');">&gt;&gt;</A></TD>\n';
1316 }
1317 }
1318 result += '</TR></TABLE>\n';
1319 result += '<TABLE WIDTH=120 BORDER=0 CELLSPACING=0 CELLPADDING=1 ALIGN=CENTER>\n';
1320 result += '<TR>\n';
1321 for (var j=0; j<7; j++) {
1322
1323 result += '<TD CLASS="'+this.cssPrefix+'cpDayColumnHeader" WIDTH="14%"><SPAN CLASS="'+this.cssPrefix+'cpDayColumnHeader">'+this.dayHeaders[(this.weekStartDay+j)%7]+'</TD>\n';
1324 }
1325 result += '</TR>\n';
1326 for (var row=1; row<=6; row++) {
1327 result += '<TR>\n';
1328 for (var col=1; col<=7; col++) {
1329 var disabled=false;
1330 if (this.disabledDatesExpression!="") {
1331 var ds=""+display_year+LZ(display_month)+LZ(display_date);
1332 eval("disabled=("+this.disabledDatesExpression+")");
1333 }
1334 var dateClass = "";
1335 if ((display_month == this.currentDate.getMonth()+1) && (display_date==this.currentDate.getDate()) && (display_year==this.currentDate.getFullYear())) {
1336 dateClass = "cpCurrentDate";
1337 }
1338 else if (display_month == month) {
1339 dateClass = "cpCurrentMonthDate";
1340 }
1341 else {
1342 dateClass = "cpOtherMonthDate";
1343 }
1344 if (disabled || this.disabledWeekDays[col-1]) {
1345 result += ' <TD CLASS="'+this.cssPrefix+dateClass+'"><SPAN CLASS="'+this.cssPrefix+dateClass+'Disabled">'+display_date+'</SPAN></TD>\n';
1346 }
1347 else {
1348 var selected_date = display_date;
1349 var selected_month = display_month;
1350 var selected_year = display_year;
1351 if (this.displayType=="week-end") {
1352 var d = new Date(selected_year,selected_month-1,selected_date,0,0,0,0);
1353 d.setDate(d.getDate() + (7-col));
1354 selected_year = d.getYear();
1355 if (selected_year < 1000) { selected_year += 1900; }
1356 selected_month = d.getMonth()+1;
1357 selected_date = d.getDate();
1358 }
1359 result += ' <TD CLASS="'+this.cssPrefix+dateClass+'"><A HREF="javascript:'+windowref+this.returnFunction+'('+selected_year+','+selected_month+','+selected_date+');'+windowref+'CP_hideCalendar(\''+this.index+'\');" CLASS="'+this.cssPrefix+dateClass+'">'+display_date+'</A></TD>\n';
1360 }
1361 display_date++;
1362 if (display_date > daysinmonth[display_month]) {
1363 display_date=1;
1364 display_month++;
1365 }
1366 if (display_month > 12) {
1367 display_month=1;
1368 display_year++;
1369 }
1370 }
1371 result += '</TR>';
1372 }
1373 var current_weekday = now.getDay() - this.weekStartDay;
1374 if (current_weekday < 0) {
1375 current_weekday += 7;
1376 }
1377 result += '<TR>\n';
1378 result += ' <TD COLSPAN=7 ALIGN=CENTER CLASS="'+this.cssPrefix+'cpTodayText">\n';
1379 if (this.disabledDatesExpression!="") {
1380 var ds=""+now.getFullYear()+LZ(now.getMonth()+1)+LZ(now.getDate());
1381 eval("disabled=("+this.disabledDatesExpression+")");
1382 }
1383 if (disabled || this.disabledWeekDays[current_weekday+1]) {
1384 result += ' <SPAN CLASS="'+this.cssPrefix+'cpTodayTextDisabled">'+this.todayText+'</SPAN>\n';
1385 }
1386 else {
1387 result += ' <A CLASS="'+this.cssPrefix+'cpTodayText" HREF="javascript:'+windowref+this.returnFunction+'(\''+now.getFullYear()+'\',\''+(now.getMonth()+1)+'\',\''+now.getDate()+'\');'+windowref+'CP_hideCalendar(\''+this.index+'\');">'+this.todayText+'</A>\n';
1388 }
1389 result += ' <BR>\n';
1390 result += ' </TD></TR></TABLE></CENTER></TD></TR></TABLE>\n';
1391 }
1392
1393 // Code common for MONTH, QUARTER, YEAR
1394 // ------------------------------------
1395 if (this.displayType=="month" || this.displayType=="quarter" || this.displayType=="year") {
1396 if (arguments.length > 0) { var year = arguments[0]; }
1397 else {
1398 if (this.displayType=="year") { var year = now.getFullYear()-this.yearSelectStartOffset; }
1399 else { var year = now.getFullYear(); }
1400 }
1401 if (this.displayType!="year" && this.isShowYearNavigation) {
1402 result += "<TABLE WIDTH=144 BORDER=0 BORDERWIDTH=0 CELLSPACING=0 CELLPADDING=0>";
1403 result += '<TR>\n';
1404 result += ' <TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="22"><A CLASS="'+this.cssPrefix+'cpYearNavigation" HREF="javascript:'+windowref+'CP_refreshCalendar('+this.index+','+(year-1)+');">&lt;&lt;</A></TD>\n';
1405 result += ' <TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="100">'+year+'</TD>\n';
1406 result += ' <TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="22"><A CLASS="'+this.cssPrefix+'cpYearNavigation" HREF="javascript:'+windowref+'CP_refreshCalendar('+this.index+','+(year+1)+');">&gt;&gt;</A></TD>\n';
1407 result += '</TR></TABLE>\n';
1408 }
1409 }
1410
1411 // Code for MONTH display
1412 // ----------------------
1413 if (this.displayType=="month") {
1414 // If POPUP, write entire HTML document
1415 result += '<TABLE WIDTH=120 BORDER=0 CELLSPACING=1 CELLPADDING=0 ALIGN=CENTER>\n';
1416 for (var i=0; i<4; i++) {
1417 result += '<TR>';
1418 for (var j=0; j<3; j++) {
1419 var monthindex = ((i*3)+j);
1420 result += '<TD WIDTH=33% ALIGN=CENTER><A CLASS="'+this.cssPrefix+'cpText" HREF="javascript:'+windowref+this.returnMonthFunction+'('+year+','+(monthindex+1)+');'+windowref+'CP_hideCalendar(\''+this.index+'\');" CLASS="'+date_class+'">'+this.monthAbbreviations[monthindex]+'</A></TD>';
1421 }
1422 result += '</TR>';
1423 }
1424 result += '</TABLE></CENTER></TD></TR></TABLE>\n';
1425 }
1426
1427 // Code for QUARTER display
1428 // ------------------------
1429 if (this.displayType=="quarter") {
1430 result += '<BR><TABLE WIDTH=120 BORDER=1 CELLSPACING=0 CELLPADDING=0 ALIGN=CENTER>\n';
1431 for (var i=0; i<2; i++) {
1432 result += '<TR>';
1433 for (var j=0; j<2; j++) {
1434 var quarter = ((i*2)+j+1);
1435 result += '<TD WIDTH=50% ALIGN=CENTER><BR><A CLASS="'+this.cssPrefix+'cpText" HREF="javascript:'+windowref+this.returnQuarterFunction+'('+year+','+quarter+');'+windowref+'CP_hideCalendar(\''+this.index+'\');" CLASS="'+date_class+'">Q'+quarter+'</A><BR><BR></TD>';
1436 }
1437 result += '</TR>';
1438 }
1439 result += '</TABLE></CENTER></TD></TR></TABLE>\n';
1440 }
1441
1442 // Code for YEAR display
1443 // ---------------------
1444 if (this.displayType=="year") {
1445 var yearColumnSize = 4;
1446 result += "<TABLE WIDTH=144 BORDER=0 BORDERWIDTH=0 CELLSPACING=0 CELLPADDING=0>";
1447 result += '<TR>\n';
1448 result += ' <TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="50%"><A CLASS="'+this.cssPrefix+'cpYearNavigation" HREF="javascript:'+windowref+'CP_refreshCalendar('+this.index+','+(year-(yearColumnSize*2))+');">&lt;&lt;</A></TD>\n';
1449 result += ' <TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="50%"><A CLASS="'+this.cssPrefix+'cpYearNavigation" HREF="javascript:'+windowref+'CP_refreshCalendar('+this.index+','+(year+(yearColumnSize*2))+');">&gt;&gt;</A></TD>\n';
1450 result += '</TR></TABLE>\n';
1451 result += '<TABLE WIDTH=120 BORDER=0 CELLSPACING=1 CELLPADDING=0 ALIGN=CENTER>\n';
1452 for (var i=0; i<yearColumnSize; i++) {
1453 for (var j=0; j<2; j++) {
1454 var currentyear = year+(j*yearColumnSize)+i;
1455 result += '<TD WIDTH=50% ALIGN=CENTER><A CLASS="'+this.cssPrefix+'cpText" HREF="javascript:'+windowref+this.returnYearFunction+'('+currentyear+');'+windowref+'CP_hideCalendar(\''+this.index+'\');" CLASS="'+date_class+'">'+currentyear+'</A></TD>';
1456 }
1457 result += '</TR>';
1458 }
1459 result += '</TABLE></CENTER></TD></TR></TABLE>\n';
1460 }
1461 // Common
1462 if (this.type == "WINDOW") {
1463 result += "</BODY></HTML>\n";
1464 }
1465 return result;
1466 }
1467
1468