Space to separate "&&" so that all "&$var" can be made into "$var" later
[openemr.git] / library / calendar.js
blobda713cbde74255911606ef90a066156595b27e2e
1 // <script language="javascript">
2     var weekend = [0,6];
3     var weekendColor = "#e0e0e0";
4     var fontface = "Verdana";
5     var fontsize = 8;                   // in "pt" units; used with "font-size" style element
7     var gNow = new Date();
8     var ggWinContent;
9     var ggPosX = -1;
10     var ggPosY = -1;
12     Calendar.Months = ["January", "February", "March", "April", "May", "June",
13     "July", "August", "September", "October", "November", "December"];
15     // Non-Leap year Month days..
16     Calendar.DOMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
17     // Leap year Month days..
18     Calendar.lDOMonth = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
20     function Calendar(p_item, p_month, p_year, p_format) {
21         if ((p_month == null) && (p_year == null))      return;
23         if (p_month == null) {
24                 this.gMonthName = null;
25                 this.gMonth = null;
26                 this.gYearly = true;
27         } else {
28                 this.gMonthName = Calendar.get_month(p_month);
29                 this.gMonth = new Number(p_month);
30                 this.gYearly = false;
31         }
33         this.gYear = p_year;
34         this.gFormat = p_format;
35         this.gBGColor = "white";
36         this.gFGColor = "black";
37         this.gTextColor = "black";
38         this.gHeaderColor = "black";
39         this.gReturnItem = p_item;
40     }
42     Calendar.get_month = Calendar_get_month;
43     Calendar.get_daysofmonth = Calendar_get_daysofmonth;
44     Calendar.calc_month_year = Calendar_calc_month_year;
46     function Calendar_get_month(monthNo) {
47         return Calendar.Months[monthNo];
48     }
50     function Calendar_get_daysofmonth(monthNo, p_year) {
51         /* 
52         Check for leap year ..
53         1.Years evenly divisible by four are normally leap years, except for... 
54         2.Years also evenly divisible by 100 are not leap years, except for... 
55         3.Years also evenly divisible by 400 are leap years. 
56         */
57         if ((p_year % 4) == 0) {
58                 if ((p_year % 100) == 0 && (p_year % 400) != 0)
59                         return Calendar.DOMonth[monthNo];
60         
61                 return Calendar.lDOMonth[monthNo];
62         } else
63                 return Calendar.DOMonth[monthNo];
64     }
66     function Calendar_calc_month_year(p_Month, p_Year, incr) {
67         /* 
68         Will return an 1-D array with 1st element being the calculated month 
69         and second being the calculated year 
70         after applying the month increment/decrement as specified by 'incr' parameter.
71         'incr' will normally have 1/-1 to navigate thru the months.
72         */
73         var ret_arr = new Array();
74         
75         if (incr == -1) {
76                 // B A C K W A R D
77                 if (p_Month == 0) {
78                         ret_arr[0] = 11;
79                         ret_arr[1] = parseInt(p_Year) - 1;
80                 }
81                 else {
82                         ret_arr[0] = parseInt(p_Month) - 1;
83                         ret_arr[1] = parseInt(p_Year);
84                 }
85         } else if (incr == 1) {
86                 // F O R W A R D
87                 if (p_Month == 11) {
88                         ret_arr[0] = 0;
89                         ret_arr[1] = parseInt(p_Year) + 1;
90                 }
91                 else {
92                         ret_arr[0] = parseInt(p_Month) + 1;
93                         ret_arr[1] = parseInt(p_Year);
94                 }
95         }
96         
97         return ret_arr;
98     }
100     function Calendar_calc_month_year(p_Month, p_Year, incr) {
101         /* 
102         Will return an 1-D array with 1st element being the calculated month 
103         and second being the calculated year 
104         after applying the month increment/decrement as specified by 'incr' parameter.
105         'incr' will normally have 1/-1 to navigate thru the months.
106         */
107         var ret_arr = new Array();
108         
109         if (incr == -1) {
110                 // B A C K W A R D
111                 if (p_Month == 0) {
112                         ret_arr[0] = 11;
113                         ret_arr[1] = parseInt(p_Year) - 1;
114                 }
115                 else {
116                         ret_arr[0] = parseInt(p_Month) - 1;
117                         ret_arr[1] = parseInt(p_Year);
118                 }
119         } else if (incr == 1) {
120                 // F O R W A R D
121                 if (p_Month == 11) {
122                         ret_arr[0] = 0;
123                         ret_arr[1] = parseInt(p_Year) + 1;
124                 }
125                 else {
126                         ret_arr[0] = parseInt(p_Month) + 1;
127                         ret_arr[1] = parseInt(p_Year);
128                 }
129         }
130         
131         return ret_arr;
132     }
134     // This is for compatibility with Navigator 3, we have to create and discard one object before the prototype object exists.
135     new Calendar();
137     Calendar.prototype.getMonthlyCalendarCode = function() {
138         var vCode = "";
139         var vHeader_Code = "";
140         var vData_Code = "";
141         
142         // Begin Table Drawing code here..
143         vCode += ("<div align=center><TABLE BORDER=1 BGCOLOR=\"" + this.gBGColor + "\" style='font-size:" + fontsize + "pt;'>");
144         
145         vHeader_Code = this.cal_header();
146         vData_Code = this.cal_data();
147         vCode += (vHeader_Code + vData_Code);
148         
149         vCode += "</TABLE></div>";
150         
151         return vCode;
152     }
154     Calendar.prototype.show = function() {
155         var vCode = "";
157         // build content into global var ggWinContent
158         ggWinContent += ("<FONT FACE='" + fontface + "' ><B>");
159         ggWinContent += (this.gMonthName + " " + this.gYear);
160         ggWinContent += "</B><BR>";
161         
162         // Show navigation buttons
163         var prevMMYYYY = Calendar.calc_month_year(this.gMonth, this.gYear, -1);
164         var prevMM = prevMMYYYY[0];
165         var prevYYYY = prevMMYYYY[1];
167         var nextMMYYYY = Calendar.calc_month_year(this.gMonth, this.gYear, 1);
168         var nextMM = nextMMYYYY[0];
169         var nextYYYY = nextMMYYYY[1];
170         
171         ggWinContent += ("<TABLE WIDTH='100%' BORDER=1 CELLSPACING=0 CELLPADDING=0 BGCOLOR='#e0e0e0' style='font-size:" + fontsize + "pt;'><TR><TD ALIGN=center>");
172         ggWinContent += ("[<A HREF=\"javascript:void(0);\" " +
173                 "onMouseOver=\"window.status='Go back one year'; return true;\" " +
174                 "onMouseOut=\"window.status=''; return true;\" " +
175                 "onClick=\"Build(" + 
176                 "'" + this.gReturnItem + "', '" + this.gMonth + "', '" + (parseInt(this.gYear)-1) + "', '" + this.gFormat + "'" +
177                 ");" +
178                 "\">&lt;&lt;Year<\/A>]</TD><TD ALIGN=center>");
179         ggWinContent += ("[<A HREF=\"javascript:void(0);\" " +
180                 "onMouseOver=\"window.status='Go back one month'; return true;\" " +
181                 "onMouseOut=\"window.status=''; return true;\" " +
182                 "onClick=\"Build(" + 
183                 "'" + this.gReturnItem + "', '" + prevMM + "', '" + prevYYYY + "', '" + this.gFormat + "'" +
184                 ");" +
185                 "\">&lt;Mon</A>]</TD><TD ALIGN=center>");
186         ggWinContent += "       </TD><TD ALIGN=center>";
187         ggWinContent += ("[<A HREF=\"javascript:void(0);\" " +
188                 "onMouseOver=\"window.status='Go forward one month'; return true;\" " +
189                 "onMouseOut=\"window.status=''; return true;\" " +
190                 "onClick=\"Build(" + 
191                 "'" + this.gReturnItem + "', '" + nextMM + "', '" + nextYYYY + "', '" + this.gFormat + "'" +
192                 ");" +
193                 "\">Mon&gt;<\/A>]</TD><TD ALIGN=center>");
194         ggWinContent += ("[<A HREF=\"javascript:void(0);\" " +
195                 "onMouseOver=\"window.status='Go forward one year'; return true;\" " +
196                 "onMouseOut=\"window.status=''; return true;\" " +
197                 "onClick=\"Build(" + 
198                 "'" + this.gReturnItem + "', '" + this.gMonth + "', '" + (parseInt(this.gYear)+1) + "', '" + this.gFormat + "'" +
199                 ");" +
200                 "\">Year&gt;&gt;<\/A>]</TD></TR></TABLE><BR>");
202         // Get the complete calendar code for the month, and add it to the
203         //      content var
204         vCode = this.getMonthlyCalendarCode();
205         ggWinContent += vCode;
206     }
208     Calendar.prototype.showY = function() {
209         var vCode = "";
210         var i;
212         ggWinContent += "<FONT FACE='" + fontface + "' ><B>"
213         ggWinContent += ("Year : " + this.gYear);
214         ggWinContent += "</B><BR>";
216         // Show navigation buttons
217         var prevYYYY = parseInt(this.gYear) - 1;
218         var nextYYYY = parseInt(this.gYear) + 1;
219         
220         ggWinContent += ("<TABLE WIDTH='100%' BORDER=1 CELLSPACING=0 CELLPADDING=0 BGCOLOR='#e0e0e0' style='font-size:" + fontsize + "pt;'><TR><TD ALIGN=center>");
221         ggWinContent += ("[<A HREF=\"javascript:void(0);\" " +
222                 "onMouseOver=\"window.status='Go back one year'; return true;\" " +
223                 "onMouseOut=\"window.status=''; return true;\" " +
224                 "onClick=\"Build(" + 
225                 "'" + this.gReturnItem + "', null, '" + prevYYYY + "', '" + this.gFormat + "'" +
226                 ");" +
227                 "\"><<Year<\/A>]</TD><TD ALIGN=center>");
228         ggWinContent += "       </TD><TD ALIGN=center>";
229         ggWinContent += ("[<A HREF=\"javascript:void(0);\" " +
230                 "onMouseOver=\"window.status='Go forward one year'; return true;\" " +
231                 "onMouseOut=\"window.status=''; return true;\" " +
232                 "onClick=\"Build(" + 
233                 "'" + this.gReturnItem + "', null, '" + nextYYYY + "', '" + this.gFormat + "'" +
234                 ");" +
235                 "\">Year>><\/A>]</TD></TR></TABLE><BR>");
237         // Get the complete calendar code for each month.
238         // start a table and first row in the table
239         ggWinContent += ("<TABLE WIDTH='100%' BORDER=0 CELLSPACING=0 CELLPADDING=5 style='font-size:" + fontsize + "pt;'><TR>");
240         var j;
241         for (i=0; i<12; i++) {
242                 // start the table cell
243                 ggWinContent += "<TD ALIGN='center' VALIGN='top'>";
244                 this.gMonth = i;
245                 this.gMonthName = Calendar.get_month(this.gMonth);
246                 vCode = this.getMonthlyCalendarCode();
247                 ggWinContent += (this.gMonthName + "/" + this.gYear + "<BR>");
248                 ggWinContent += vCode;
249                 ggWinContent += "</TD>";
250                 if (i == 3 || i == 7) {
251                         ggWinContent += "</TR><TR>";
252                         }
254         }
256         ggWinContent += "</TR></TABLE></font><BR>";
257     }
259     Calendar.prototype.cal_header = function() {
260         var vCode = "";
261         
262         vCode = vCode + "<TR>";
263         vCode = vCode + "<TD WIDTH='14%'><FONT FACE='" + fontface + "' COLOR='" + this.gHeaderColor + "'><B>Sun</B></FONT></TD>";
264         vCode = vCode + "<TD WIDTH='14%'><FONT FACE='" + fontface + "' COLOR='" + this.gHeaderColor + "'><B>Mon</B></FONT></TD>";
265         vCode = vCode + "<TD WIDTH='14%'><FONT FACE='" + fontface + "' COLOR='" + this.gHeaderColor + "'><B>Tue</B></FONT></TD>";
266         vCode = vCode + "<TD WIDTH='14%'><FONT FACE='" + fontface + "' COLOR='" + this.gHeaderColor + "'><B>Wed</B></FONT></TD>";
267         vCode = vCode + "<TD WIDTH='14%'><FONT FACE='" + fontface + "' COLOR='" + this.gHeaderColor + "'><B>Thu</B></FONT></TD>";
268         vCode = vCode + "<TD WIDTH='14%'><FONT FACE='" + fontface + "' COLOR='" + this.gHeaderColor + "'><B>Fri</B></FONT></TD>";
269         vCode = vCode + "<TD WIDTH='16%'><FONT FACE='" + fontface + "' COLOR='" + this.gHeaderColor + "'><B>Sat</B></FONT></TD>";
270         vCode = vCode + "</TR>";
271         
272         return vCode;
273     }
275     Calendar.prototype.cal_data = function() {
276         var vDate = new Date();
277         vDate.setDate(1);
278         vDate.setMonth(this.gMonth);
279         vDate.setFullYear(this.gYear);
281         var vFirstDay=vDate.getDay();
282         var vDay=1;
283         var vLastDay=Calendar.get_daysofmonth(this.gMonth, this.gYear);
284         var vOnLastDay=0;
285         var vCode = "";
287         /*
288         Get day for the 1st of the requested month/year..
289         Place as many blank cells before the 1st day of the month as necessary. 
290         */
291         vCode = vCode + "<TR>";
292         for (i=0; i<vFirstDay; i++) {
293                 vCode = vCode + "<TD WIDTH='14%'" + this.write_weekend_string(i) + "><FONT FACE='" + fontface + "'> </FONT></TD>";
294         }
296         // Write rest of the 1st week
297         for (j=vFirstDay; j<7; j++) {
298                 vCode = vCode + "<TD WIDTH='14%'" + this.write_weekend_string(j) + "><FONT FACE='" + fontface + "'>" + 
299                         "<A HREF='javascript:void(0);' " + 
300                                 "onMouseOver=\"window.status='set date to " + this.format_data(vDay) + "'; return true;\" " +
301                                 "onMouseOut=\"window.status=' '; return true;\" " +
302                                 "onClick=\"document." + this.gReturnItem + ".value='" + 
303                                 this.format_data(vDay) + 
304                                 "';ggPosX=-1;ggPosY=-1;nd();nd();\">" + 
305                                 this.format_day(vDay) + 
306                         "</A>" + 
307                         "</FONT></TD>";
308                 vDay=vDay + 1;
309         }
310         vCode = vCode + "</TR>";
312         // Write the rest of the weeks
313         for (k=2; k<7; k++) {
314                 vCode = vCode + "<TR>";
316                 for (j=0; j<7; j++) {
317                         vCode = vCode + "<TD WIDTH='14%'" + this.write_weekend_string(j) + "><FONT FACE='" + fontface + "'>" + 
318                                 "<A HREF='javascript:void(0);' " +
319                                         "onMouseOver=\"window.status='set date to " + this.format_data(vDay) + "'; return true;\" " +
320                                         "onMouseOut=\"window.status=' '; return true;\" " +
321                                         "onClick=\"document." + this.gReturnItem + ".value='" + 
322                                         this.format_data(vDay) + 
323                                         "';window.scroll(0,ggPosY);ggPosX=-1;ggPosY=-1;nd();nd();\">" + 
324                                 this.format_day(vDay) + 
325                                 "</A>" + 
326                                 "</FONT></TD>";
327                         vDay=vDay + 1;
329                         if (vDay > vLastDay) {
330                                 vOnLastDay = 1;
331                                 break;
332                         }
333                 }
335                 if (j == 6)
336                         vCode = vCode + "</TR>";
337                 if (vOnLastDay == 1)
338                         break;
339         }
340         
341         // Fill up the rest of last week with proper blanks, so that we get proper square blocks
342         for (m=1; m<(7-j); m++) {
343                 if (this.gYearly)
344                         vCode = vCode + "<TD WIDTH='14%'" + this.write_weekend_string(j+m) + 
345                         "><FONT FACE='" + fontface + "' COLOR='gray'> </FONT></TD>";
346                 else
347                         vCode = vCode + "<TD WIDTH='14%'" + this.write_weekend_string(j+m) + 
348                         "><FONT FACE='" + fontface + "' COLOR='gray'>" + m + "</FONT></TD>";
349         }
350         
351         return vCode;
352     }
354     Calendar.prototype.format_day = function(vday) {
355         var vNowDay = gNow.getDate();
356         var vNowMonth = gNow.getMonth();
357         var vNowYear = gNow.getFullYear();
359         if (vday == vNowDay && this.gMonth == vNowMonth && this.gYear == vNowYear)
360                 return ("<FONT COLOR=\"RED\"><B>" + vday + "</B></FONT>");
361         else
362                 return (vday);
363     }
365     Calendar.prototype.write_weekend_string = function(vday) {
366         var i;
368         // Return special formatting for the weekend day.
369         for (i=0; i<weekend.length; i++) {
370                 if (vday == weekend[i])
371                         return (" BGCOLOR=\"" + weekendColor + "\"");
372         }
373         
374         return "";
375     }
377     Calendar.prototype.format_data = function(p_day) {
378         var vData;
379         var vMonth = 1 + this.gMonth;
380         vMonth = (vMonth.toString().length < 2) ? "0" + vMonth : vMonth;
381         var vMon = Calendar.get_month(this.gMonth).substr(0,3).toUpperCase();
382         var vFMon = Calendar.get_month(this.gMonth).toUpperCase();
383         var vY4 = new String(this.gYear);
384         var vY2 = new String(this.gYear.substr(2,2));
385         var vDD = (p_day.toString().length < 2) ? "0" + p_day : p_day;
387         switch (this.gFormat) {
388                 case "MM\/DD\/YYYY" :
389                         vData = vMonth + "\/" + vDD + "\/" + vY4;
390                         break;
391                 case "MM\/DD\/YY" :
392                         vData = vMonth + "\/" + vDD + "\/" + vY2;
393                         break;
394                 case "MM-DD-YYYY" :
395                         vData = vMonth + "-" + vDD + "-" + vY4;
396                         break;
397                 case "YYYY-MM-DD" :
398                         vData = vY4 + "-" + vMonth + "-" + vDD;
399                         break;
400                 case "MM-DD-YY" :
401                         vData = vMonth + "-" + vDD + "-" + vY2;
402                         break;
403                 case "DD\/MON\/YYYY" :
404                         vData = vDD + "\/" + vMon + "\/" + vY4;
405                         break;
406                 case "DD\/MON\/YY" :
407                         vData = vDD + "\/" + vMon + "\/" + vY2;
408                         break;
409                 case "DD-MON-YYYY" :
410                         vData = vDD + "-" + vMon + "-" + vY4;
411                         break;
412                 case "DD-MON-YY" :
413                         vData = vDD + "-" + vMon + "-" + vY2;
414                         break;
415                 case "DD\/MONTH\/YYYY" :
416                         vData = vDD + "\/" + vFMon + "\/" + vY4;
417                         break;
418                 case "DD\/MONTH\/YY" :
419                         vData = vDD + "\/" + vFMon + "\/" + vY2;
420                         break;
421                 case "DD-MONTH-YYYY" :
422                         vData = vDD + "-" + vFMon + "-" + vY4;
423                         break;
424                 case "DD-MONTH-YY" :
425                         vData = vDD + "-" + vFMon + "-" + vY2;
426                         break;
427                 case "DD\/MM\/YYYY" :
428                         vData = vDD + "\/" + vMonth + "\/" + vY4;
429                         break;
430                 case "DD\/MM\/YY" :
431                         vData = vDD + "\/" + vMonth + "\/" + vY2;
432                         break;
433                 case "DD-MM-YYYY" :
434                         vData = vDD + "-" + vMonth + "-" + vY4;
435                         break;
436                 case "DD-MM-YY" :
437                         vData = vDD + "-" + vMonth + "-" + vY2;
438                         break;
439                 default :
440                         vData = vMonth + "\/" + vDD + "\/" + vY4;
441         }
443         return vData;
444     }
446     function Build(p_item, p_month, p_year, p_format) {
447         gCal = new Calendar(p_item, p_month, p_year, p_format);
449         // Customize your Calendar here..
450         gCal.gBGColor="white";
451         gCal.gLinkColor="black";
452         gCal.gTextColor="black";
453         gCal.gHeaderColor="darkgreen";
455         // initialize the content string
456         ggWinContent = "";
458         // Choose appropriate show function
459         if (gCal.gYearly) {
460                 // and, since the yearly calendar is so large, override the positioning and fontsize
461                 // warning: in IE6, it appears that "select" fields on the form will still show
462                 //      through the "over" div; Note: you can set these variables as part of the onClick
463                 //      javascript code before you call the show_yearly_calendar function
464                 if (ggPosX == -1) ggPosX = 10;
465                 if (ggPosY == -1) ggPosY = 10;
466                 if (fontsize == 8) fontsize = 6;
467                 // generate the calendar
468                 gCal.showY();
469                 }
470         else {
471                 gCal.show();
472                 }
474         // if this is the first calendar popup, use autopositioning with an offset
475         if (ggPosX == -1 && ggPosY == -1) {
476                 overlib(ggWinContent, AUTOSTATUSCAP, STICKY, CLOSECLICK, CSSSTYLE,
477                         TEXTSIZEUNIT, "pt", TEXTSIZE, 8, CAPTIONSIZEUNIT, "pt", CAPTIONSIZE, 8, CLOSESIZEUNIT, "pt", CLOSESIZE, 8,
478                         CAPTION, "Select a date", OFFSETX, 20, OFFSETY, -20);
479                 // save where the 'over' div ended up; we want to stay in the same place if the user
480                 //      clicks on one of the year or month navigation links
481                 if ( (ns4) || (ie4) ) {
482                         ggPosX = parseInt(over.left);
483                         ggPosY = parseInt(over.top);
484                         } else if (ns6) {
485                         ggPosX = parseInt(over.style.left);
486                         ggPosY = parseInt(over.style.top);
487                         }
488                 }
489         else {
490                 // we have a saved X & Y position, so use those with the FIXX and FIXY options
491                 overlib(ggWinContent, AUTOSTATUSCAP, STICKY, CLOSECLICK, CSSSTYLE,
492                         TEXTSIZEUNIT, "pt", TEXTSIZE, 8, CAPTIONSIZEUNIT, "pt", CAPTIONSIZE, 8, CLOSESIZEUNIT, "pt", CLOSESIZE, 8,
493                         CAPTION, "Select a date", FIXX, ggPosX, FIXY, ggPosY);
494                 }
495         window.scroll(ggPosX, ggPosY);
496     }
498     function show_calendar() {
499         /* 
500                 p_month : 0-11 for Jan-Dec; 12 for All Months.
501                 p_year  : 4-digit year
502                 p_format: Date format (mm/dd/yyyy, dd/mm/yy, ...)
503                 p_item  : Return Item.
504         */
506         p_item = arguments[0];
507         if (arguments[1] == null)
508                 p_month = new String(gNow.getMonth());
509         else
510                 p_month = arguments[1];
511         if (arguments[2] == "" || arguments[2] == null)
512                 p_year = new String(gNow.getFullYear().toString());
513         else
514                 p_year = arguments[2];
515         if (arguments[3] == null)
516                 p_format = "YYYY-MM-DD";
517         else
518                 p_format = arguments[3];
520         Build(p_item, p_month, p_year, p_format);
521     }
522     /*
523     Yearly Calendar Code Starts here
524     */
525     function show_yearly_calendar() {
526         // Load the defaults..
527         //if (p_year == null || p_year == "")
528         //      p_year = new String(gNow.getFullYear().toString());
529         //if (p_format == null || p_format == "")
530         //      p_format = "YYYY-MM-DD";
532         p_item = arguments[0];
533         if (arguments[1] == "" || arguments[1] == null)
534                 p_year = new String(gNow.getFullYear().toString());
535         else
536                 p_year = arguments[1];
537         if (arguments[2] == null)
538                 p_format = "YYYY-MM-DD";
539         else
540                 p_format = arguments[2];
542         Build(p_item, null, p_year, p_format);
543     }
544 // </SCRIPT>