]> err.no Git - sope/blob - sope-appserver/WEExtensions/calendar.js
added strict OSX bundle dependencies
[sope] / sope-appserver / WEExtensions / calendar.js
1 var monthArray = getMonthSelect();
2 var calDateField;
3 var calDate;
4
5
6 // innerHTML IS ONLY SUPPORTED BY MSIE...
7 function rewriteLayerWithData(obj,data) {
8   if (isNav) {
9     obj.document.clear();
10     obj.document.write(data);
11     obj.document.close();
12   }
13   if (isIE) {
14     obj.innerHTML = data;
15   }
16   if (usesNavImages) {
17     document.images['dateFieldFirstImg'].src = dateFieldFirst.src;
18     document.images['dateFieldPreviousImg'].src = dateFieldPrevious.src;
19     document.images['dateFieldTodayImg'].src = dateFieldToday.src;
20     document.images['dateFieldNextImg'].src = dateFieldNext.src;
21     document.images['dateFieldLastImg'].src = dateFieldLast.src;
22     document.images['dateFieldCloseImg'].src = dateFieldClose.src;
23   }
24 }
25
26 // DETERMINE BROWSER BRAND
27 var isNav = false;
28 var isIE  = false;
29
30 if (navigator.appName == "Netscape") {
31     isNav = true;
32 }
33 else {
34     isIE = true;
35 }
36
37 // PRE-BUILD PORTIONS OF THE CALENDAR WHEN THIS JS LIBRARY LOADS INTO THE BROWSER
38 buildCalParts();
39
40
41 // CALENDAR FUNCTIONS BEGIN HERE ---------------------------------------------------
42
43
44
45 // SET THE INITIAL VALUE OF THE GLOBAL DATE FIELD
46 function setDateField(dateField) {
47
48     // ASSIGN THE INCOMING FIELD OBJECT TO A GLOBAL VARIABLE
49     calDateField = dateField;    
50
51     // GET THE VALUE OF THE INCOMING FIELD
52     inDate = dateField.value;
53
54     // SET calDate TO THE DATE IN THE INCOMING FIELD OR DEFAULT TO TODAY'S DATE
55     setInitialDate();
56
57 }
58
59
60 // SET THE INITIAL CALENDAR DATE TO TODAY OR TO THE EXISTING VALUE IN dateField
61 function setInitialDate() {
62    
63     // CREATE A NEW DATE OBJECT (WILL GENERALLY PARSE CORRECT DATE EXCEPT WHEN "." IS USED AS A DELIMITER)
64     // (THIS ROUTINE DOES *NOT* CATCH ALL DATE FORMATS, IF YOU NEED TO PARSE A CUSTOM DATE FORMAT, DO IT HERE)
65     // ADD CUSTOM DATE PARSING HERE
66
67     ypos = dateFormat.indexOf('%Y');
68     inYear = parseInt(inDate.substr(ypos,4));
69
70     mpos = dateFormat.indexOf('%m');
71     if (ypos < mpos) mpos+=2;  // because %Y stands for yyyy, add 2
72     inMonth = inDate.substr(mpos,2);
73     if (inMonth.charAt(0) == "0") 
74       inMonth = inMonth.substr(1,inMonth.length-1);
75     inMonth = parseInt(inMonth);
76     
77     dpos = dateFormat.indexOf('%d');
78     if (ypos < dpos) dpos+=2;  // same as mpos
79     inDay = inDate.substr(dpos,2);
80     if (inDay.charAt(0) == "0") 
81       inDay = inDay.substr(1,inDay.length-1);
82     inDay = parseInt(inDay);
83
84     if ((inYear) && (inMonth) && (inDay)) {
85
86         calDate = new Date(inYear,inMonth-1,inDay);
87     }
88     else {
89
90         calDate = new Date();
91     }
92
93     // KEEP TRACK OF THE CURRENT DAY VALUE
94     calDay  = calDate.getDate();
95
96     // SET DAY VALUE TO 1... TO AVOID JAVASCRIPT DATE CALCULATION ANOMALIES
97     // (IF THE MONTH CHANGES TO FEB AND THE DAY IS 30, THE MONTH WOULD CHANGE TO MARCH
98     //  AND THE DAY WOULD CHANGE TO 2.  SETTING THE DAY TO 1 WILL PREVENT THAT)
99     calDate.setDate(1);
100 }
101
102
103 // ENABLE MULTIPLE CALENDAR-USING OBJECTS BY USING VARIABLE calendarDiv;
104 var calendarDiv = false;
105
106 function toggleCalendar(dateFieldEl,calObj,calFormat) {
107   if ((calendarDiv) &&  (calendarDiv.id != calObj.id)) {
108     hideCalendar();
109   }
110   calendarDiv = calObj;
111   
112   if (isNav) condition = (calendarDiv.visibility == 'show');
113   if (isIE)  condition = (calendarDiv.style.visibility    == 'visible');
114   if (condition) {
115     hideCalendar();
116   }
117   else {
118     var i,j;
119     var dateField;
120
121     for (i = 0; i < document.forms.length; i++) {
122       for (j = 0; j < document.forms[i].elements.length; j++) {
123         if (document.forms[i].elements[j].name == dateFieldEl) {
124           dateField = document.forms[i].elements[j];
125         }
126       }
127     }
128     dateFormat = calFormat;
129     showCalendar(dateField);
130   }
131 }
132
133 // CAPTURE onMouseMove EVENT IF NETSCAPE FOR POSITIONING calendarDiv
134
135 if (isNav) {
136   document.captureEvents( Event.MOUSEMOVE );
137   document.onmousemove = actPos;
138 }
139
140 var curScreenPosX;
141 var curScreenPosY;
142
143 function actPos(e) {
144   
145   curScreenPosX = e.pageX + 10;
146   curScreenPosY = e.pageY;
147   return true;
148 }
149
150
151 function showCalendar(dateField) {
152
153     // SET INITIAL VALUE OF THE DATE FIELD AND CREATE TOP AND BOTTOM FRAMES
154     setDateField(dateField);
155
156     writeCalendar();
157     if (isNav) {
158       calendarDiv.visibility   = 'show';
159       calendarDiv.left = curScreenPosX;
160       calendarDiv.top  = curScreenPosY;
161     }
162     if (isIE) {
163       calendarDiv.style.visibility      = 'visible';
164     }
165
166     return true;
167 }
168
169 function hideCalendar() {
170     if (isNav) {
171       calendarDiv.visibility = 'hide';
172     }
173     if (isIE) {
174       calendarDiv.style.visibility = 'hidden';
175     }
176     calendarDiv = false;
177 }
178
179 // NEW: NO FRAMES ANYMORE, ONE <DIV> INSTEAD
180 function writeCalendar() {
181
182   data = buildTopCalFrame() + buildBottomCalFrame();
183   if (isNav) rewriteLayerWithData(calendarDiv, data);
184   if (isIE)  rewriteLayerWithData(calendarDiv, data);
185 }
186
187
188 // CREATE month/year DISPLAY
189 function buildCalControlMonthYear() {
190   month = calDate.getMonth();
191   year  = calDate.getFullYear();
192   return String(monthArray[month])+" "+String(year);
193 }
194
195
196
197 var obj=false;
198 var X,Y;
199
200 function MD() {
201   if (isIE) {
202     ob = true;
203     X=event.offsetX;
204     Y=event.offsetY;
205     document.onmousemove = MM;
206     document.onmouseup   = MU;
207   }
208 }
209
210 function MM() {
211   if (ob) {
212     calendarDiv.style.pixelLeft = event.clientX-X + document.body.scrollLeft;
213     calendarDiv.style.pixelTop = event.clientY-Y + document.body.scrollTop;
214     return false;
215   }
216 }
217
218 function MU() {
219   ob = false;
220 //  document.onmousemove = null;
221 //  document.onmouseup   = null;
222 }
223
224 // CREATE THE TOP CALENDAR PART
225 function buildTopCalFrame() {
226
227      var calDoc =
228        "<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0><TR><TD BGCOLOR=black>" +
229        "<TABLE CELLPADDING=0 CELLSPACING=1 BORDER=0>" +
230        "<TR><TD COLSPAN=6 ALIGN=left CLASS=topCal onMouseDown='MD()'>" +
231        buildCalControlMonthYear() +
232        "</TD>" +
233        "<TD ALIGN=right CLASS=topCal>"+
234        "<A CLASS=navMonYear HREF='javascript:hideCalendar()'>" +
235        dateFieldCloseSRC+"</A>&nbsp;</TD></TR>" +
236        "<TR>" +
237        "<TD COLSPAN=7 CLASS=topCal ALIGN=center><FONT SIZE=1 FACE='Arial'>"+
238        "<A CLASS=navMonYear HREF='javascript:setPreviousYear()'>"+
239        dateFieldFirstSRC+"</A>" +
240        " <A CLASS=navMonYear HREF='javascript:setPreviousMonth()'>"+
241        dateFieldPreviousSRC+"</A>" +
242        " <A CLASS=navMonYear HREF='javascript:setToday()'>"+
243        dateFieldTodaySRC+"</A>" +
244        " <A CLASS=navMonYear HREF='javascript:setNextMonth()'>"+
245        dateFieldNextSRC+"</A>"+
246        " <A CLASS=navMonYear HREF='javascript:setNextYear()'>"+
247        dateFieldLastSRC+"</A>" +
248        "</FONT></TD>" +
249        "</TR>";
250    return calDoc;
251 }
252
253
254 // CREATE THE BOTTOM CALENDAR PART
255 function buildBottomCalFrame() {       
256
257     // START CALENDAR DOCUMENT
258     var calDoc = calendarBegin;
259
260     // GET MONTH, AND YEAR FROM GLOBAL CALENDAR DATE
261     month   = calDate.getMonth();
262     year    = calDate.getFullYear();
263
264
265     // GET GLOBALLY-TRACKED DAY VALUE (PREVENTS JAVASCRIPT DATE ANOMALIES)
266     day     = calDay;
267
268     var i   = 0;
269
270     // DETERMINE THE NUMBER OF DAYS IN THE CURRENT MONTH
271     var days = getDaysInMonth();
272
273     // IF GLOBAL DAY VALUE IS > THAN DAYS IN MONTH, HIGHLIGHT LAST DAY IN MONTH
274     if (day > days) {
275         day = days;
276     }
277
278     // DETERMINE WHAT DAY OF THE WEEK THE CALENDAR STARTS ON
279     var firstOfMonth = new Date (year, month, 1);
280
281     // GET THE DAY OF THE WEEK THE FIRST DAY OF THE MONTH FALLS ON
282     var startingPos  = firstOfMonth.getDay();
283     days += startingPos;
284
285     // KEEP TRACK OF THE COLUMNS, START A NEW ROW AFTER EVERY 7 COLUMNS
286     var columnCount = 0;
287
288     // MAKE BEGINNING NON-DATE CELLS BLANK
289     for (i = 0; i < startingPos; i++) {
290
291         calDoc += blankCell;
292         columnCount++;
293     }
294
295     // SET VALUES FOR DAYS OF THE MONTH
296     var currentDay = 0;
297     var dayType    = "weekday";
298
299     // DATE CELLS CONTAIN A NUMBER
300     for (i = startingPos; i < days; i++) {
301
302         var paddingChar = "&nbsp;";
303
304         // ADJUST SPACING SO THAT ALL LINKS HAVE RELATIVELY EQUAL WIDTHS
305         if (i-startingPos+1 < 10) {
306             padding = "&nbsp;&nbsp;";
307         }
308         else {
309             padding = "&nbsp;";
310         }
311
312         // GET THE DAY CURRENTLY BEING WRITTEN
313         currentDay = i-startingPos+1;
314
315         // SET THE TYPE OF DAY, THE focusDay GENERALLY APPEARS AS A DIFFERENT COLOR
316         if (currentDay == day) {
317             dayType = "focusDay";
318         }
319         else {
320             dayType = "weekDay";
321         }
322
323         // ADD THE DAY TO THE CALENDAR STRING
324         calDoc += "<TD align=center bgcolor='lightgrey'>" +
325                   "<a class='" + dayType + "' href='javascript:returnDate(" + 
326                   currentDay + ")'>" + padding + currentDay + paddingChar + "</a></TD>";
327
328         columnCount++;
329
330         // START A NEW ROW WHEN NECESSARY
331         if (columnCount % 7 == 0) {
332             calDoc += "</TR><TR>";
333         }
334     }
335
336     // MAKE REMAINING NON-DATE CELLS BLANK
337     for (i=days; i<42; i++)  {
338
339         calDoc += blankCell;
340         columnCount++;
341
342         // START A NEW ROW WHEN NECESSARY
343         if (columnCount % 7 == 0) {
344             calDoc += "</TR>";
345             if (i<41) {
346                 calDoc += "<TR>";
347             }
348         }
349     }
350
351     // FINISH THE NEW CALENDAR PAGE
352     calDoc += calendarEnd;
353
354     // RETURN THE COMPLETED CALENDAR PAGE
355     return calDoc;
356 }
357
358
359 // SET THE CALENDAR TO TODAY'S DATE AND DISPLAY THE NEW CALENDAR
360 function setToday() {
361
362     // SET GLOBAL DATE TO TODAY'S DATE
363     calDate = new Date();
364
365     // DISPLAY THE NEW CALENDAR
366     writeCalendar();
367 }
368
369
370 // SET THE GLOBAL DATE TO THE PREVIOUS YEAR AND REDRAW THE CALENDAR
371 function setPreviousYear() {
372
373     var year  = calDate.getFullYear();
374
375     if (year > 1000) {
376         year--;
377         calDate.setFullYear(year);
378         writeCalendar();
379     }
380 }
381
382
383 // SET THE GLOBAL DATE TO THE PREVIOUS MONTH AND REDRAW THE CALENDAR
384 function setPreviousMonth() {
385
386     var year  = calDate.getFullYear();
387     var month = calDate.getMonth();
388    
389     // IF MONTH IS JANUARY, SET MONTH TO DECEMBER AND DECREMENT THE YEAR
390     if (month == 0) {
391         month = 11;
392         if (year > 1000) {
393             year--;
394             calDate.setFullYear(year);
395         }
396     }
397     else {
398         month--;
399     }
400     calDate.setMonth(month);
401     writeCalendar();
402 }
403
404
405 // SET THE GLOBAL DATE TO THE NEXT MONTH AND REDRAW THE CALENDAR
406 function setNextMonth() {
407
408     var year = calDate.getFullYear();
409
410         var month = calDate.getMonth();
411
412         // IF MONTH IS DECEMBER, SET MONTH TO JANUARY AND INCREMENT THE YEAR
413         if (month == 11) {
414             month = 0;
415             year++;
416             calDate.setFullYear(year);
417         }
418         else {
419             month++;
420         }
421         calDate.setMonth(month);
422         writeCalendar();
423 }
424
425
426 // SET THE GLOBAL DATE TO THE NEXT YEAR AND REDRAW THE CALENDAR
427 function setNextYear() {
428
429     var year  = calDate.getFullYear();
430         year++;
431         calDate.setFullYear(year);
432         writeCalendar();
433 }
434
435
436 // GET NUMBER OF DAYS IN MONTH
437 function getDaysInMonth()  {
438
439     var days;
440     var month = calDate.getMonth()+1;
441     var year  = calDate.getFullYear();
442
443     // RETURN 31 DAYS
444     if (month==1 || month==3 || month==5 || month==7 || month==8 ||
445         month==10 || month==12)  {
446         days=31;
447     }
448     // RETURN 30 DAYS
449     else if (month==4 || month==6 || month==9 || month==11) {
450         days=30;
451     }
452     // RETURN 29 DAYS
453     else if (month==2)  {
454         if (isLeapYear(year)) {
455             days=29;
456         }
457         // RETURN 28 DAYS
458         else {
459             days=28;
460         }
461     }
462     return (days);
463 }
464
465
466 // CHECK TO SEE IF YEAR IS A LEAP YEAR
467 function isLeapYear (Year) {
468
469     if (((Year % 4)==0) && ((Year % 100)!=0) || ((Year % 400)==0)) {
470         return (true);
471     }
472     else {
473         return (false);
474     }
475 }
476
477
478 // BUILD THE MONTH SELECT LIST
479 function getMonthSelect() {
480
481     // IF SET BY A PARAMETER (WRITTEN AT THE BEGINNING BY WOCalendar)
482     if (externMonths) {
483       monthArray = externMonths;
484     }
485     else {
486         monthArray = new Array('January', 'February', 'March', 'April', 
487            'May', 'June', 'July', 'August', 
488            'September', 'October', 'November', 'December');
489     }
490     return monthArray;
491 }
492
493
494 // SET DAYS OF THE WEEK DEPENDING ON LANGUAGE
495 function createWeekdayList() {
496
497     // IF SET BY A PARAMETER (WRITTEN AT THE BEGINNING BY WODateFieldScript)
498     if (externWeekdays) {
499       weekdayArray = externWeekdays;
500     }
501     else {
502         weekdayArray = new Array('Su','Mo','Tu','We','Th','Fr','Sa');
503     }
504
505     var weekdays = "<TR BGCOLOR='white'>";
506     for (i in weekdayArray) {
507         weekdays += "<TD class='heading' align=center>"
508                  + weekdayArray[i] + "</TD>";
509     }
510     weekdays += "</TR>";
511
512     return weekdays;
513 }
514
515
516 // PRE-BUILD PORTIONS OF THE CALENDAR (FOR PERFORMANCE REASONS)
517 function buildCalParts() {
518
519     // BUILD THE BLANK CELL ROWS
520     blankCell = "<TD align=center bgcolor='lightGrey'>&nbsp;&nbsp;&nbsp;</TD>";
521
522     // BUILD THE TOP PORTION OF THE CALENDAR PAGE USING CSS TO CONTROL SOME DISPLAY ELEMENTS
523     calendarBegin = createWeekdayList() + "<TR>";
524
525     // BUILD THE BOTTOM PORTION OF THE CALENDAR PAGE
526     calendarEnd = "";
527
528         // END THE TABLE AND HTML DOCUMENT
529         calendarEnd +=
530             "</TABLE></TD></TR></TABLE>";
531 }
532
533
534 // REPLACE ALL INSTANCES OF find WITH replace
535 // inString: the string you want to convert
536 // find:     the value to search for
537 // replace:  the value to substitute
538 //
539 // usage:    jsReplace(inString, find, replace);
540 // example:  jsReplace("To be or not to be", "be", "ski");
541 //           result: "To ski or not to ski"
542 //
543 function jsReplace(inString, find, replace) {
544
545     var outString = "";
546
547     if (!inString) {
548         return "";
549     }
550
551     // REPLACE ALL INSTANCES OF find WITH replace
552     if (inString.indexOf(find) != -1) {
553         // SEPARATE THE STRING INTO AN ARRAY OF STRINGS USING THE VALUE IN find
554         t = inString.split(find);
555
556         // JOIN ALL ELEMENTS OF THE ARRAY, SEPARATED BY THE VALUE IN replace
557         return (t.join(replace));
558     }
559     else {
560         return inString;
561     }
562 }
563
564
565 // JAVASCRIPT FUNCTION -- DOES NOTHING (USED FOR THE HREF IN THE CALENDAR CALL)
566 function doNothing() {
567 }
568
569
570 // ENSURE THAT VALUE IS TWO DIGITS IN LENGTH
571 function makeTwoDigit(inValue) {
572
573     var numVal = parseInt(inValue, 10);
574
575     // VALUE IS LESS THAN TWO DIGITS IN LENGTH
576     if (numVal < 10) {
577
578         // ADD A LEADING ZERO TO THE VALUE AND RETURN IT
579         return("0" + numVal);
580     }
581     else {
582         return numVal;
583     }
584 }
585
586
587 // SET FIELD VALUE TO THE DATE SELECTED AND CLOSE THE CALENDAR WINDOW
588 function returnDate(inDay)
589 {
590
591     // inDay = THE DAY THE USER CLICKED ON
592     calDate.setDate(inDay);
593
594     // SET THE DATE RETURNED TO THE USER
595     var day           = calDate.getDate();
596     var month         = calDate.getMonth()+1;
597     var year          = calDate.getFullYear();
598
599     outDate = dateFormat;
600     outDate = jsReplace(outDate,'%Y',String(year));
601     outDate = jsReplace(outDate,'%m',makeTwoDigit(month));
602     outDate = jsReplace(outDate,'%d',makeTwoDigit(day));
603
604     // SET THE VALUE OF THE FIELD THAT WAS PASSED TO THE CALENDAR
605     calDateField.value = outDate;
606
607     // CLOSE THE CALENDAR WINDOW
608     hideCalendar();
609 }