source: trunk/FACT++/www/shift/calendar.js@ 13694

Last change on this file since 13694 was 13687, checked in by tbretz, 13 years ago
Implemented a mark for an attached comment, display comment in tooltip.
File size: 24.5 KB
Line 
1/**********************************************************************
2* Calendar JavaScript [DOM] v3.11 by Michael Loesler *
3************************************************************************
4* Copyright (C) 2005-09 by Michael Loesler, http//derletztekick.com *
5* *
6* *
7* This program is free software; you can redistribute it and/or modify *
8* it under the terms of the GNU General Public License as published by *
9* the Free Software Foundation; either version 3 of the License, or *
10* (at your option) any later version. *
11* *
12* This program is distributed in the hope that it will be useful, *
13* but WITHOUT ANY WARRANTY; without even the implied warranty of *
14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15* GNU General Public License for more details. *
16* *
17* You should have received a copy of the GNU General Public License *
18* along with this program; if not, see <http://www.gnu.org/licenses/> *
19* or write to the *
20* Free Software Foundation, Inc., *
21* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22* *
23 **********************************************************************/
24/*
25function logout()
26{
27 var xmlHttp = new XMLHttpRequest();
28 xmlHttp.open('POST', "calendar.php?logout=1", true);
29 xmlHttp.onload = function ()
30 {
31 if (xmlHttp.status!=200)
32 {
33 alert("ERROR - HTTP request: "+xmlHttp.statusText+" ["+xmlHttp.status+"]");
34 return;
35 }
36
37 alert("Logout successful!");
38 };
39
40 xmlHttp.send();
41}
42*/
43function resize()
44{
45 var table = document.getElementById("table");
46
47 var W = window.innerWidth;
48 var H = window.innerHeight;
49
50 table.style.width =W+"px";
51 table.style.height=H+"px";
52}
53
54var institutes= ["User", "EPFL", "ETHZ", "ISDC", "UNIDO", "UNIGE", "UNIWUE" ];
55
56function CalendarJS()
57{
58 this.now = new Date();
59 this.dayname = ["Mo","Tu","We","Th","Fr","Sa","So"];
60 this.monthname = ["January","February","March","April","May","June","July","August","September","October","November","December"];
61 this.tooltip = ["previous month","next month","current date","last year","next year"];
62 this.monthCell = document.createElement("th");
63 this.tableHead = null;
64 this.tableFoot = null;
65 this.parEl = null;
66
67 this.init = function( id, initDate )
68 {
69 this.now = initDate ? initDate : new Date();
70 this.date = this.now.getDate();
71 this.month = this.mm = this.now.getMonth();
72 this.year = this.yy = this.now.getFullYear();
73 this.monthCell.appendChild(document.createTextNode( this.monthname[this.mm]+"\u00a0"+this.yy ));
74
75 this.tableHead = this.createTableHead();
76 this.tableFoot = this.createTableFoot();
77
78 this.parEl = document.getElementById( id );
79 this.show();
80
81 if (!initDate)
82 this.checkDate();
83 };
84
85 this.checkDate = function()
86 {
87 var self = this;
88 var today = new Date();
89
90 if (this.date != today.getDate())
91 {
92 this.tableHead = this.createTableHead();
93 this.tableFoot = this.createTableFoot();
94
95 this.date = today.getDate();
96 if (this.mm == this.month && this.yy == this.year)
97 this.switchMonth("current");
98
99 this.month = today.getMonth();
100 if (this.mm == this.month && this.yy == this.year)
101 this.switchMonth("current");
102
103 this.year = today.getFullYear();
104 if (this.mm == this.month && this.yy == this.year)
105 this.switchMonth("current");
106 }
107 window.setTimeout(function() { self.checkDate(); }, Math.abs(new Date(this.year, this.month, this.date, 24, 0, 0)-this.now));
108 },
109
110 this.removeElements = function( Obj )
111 {
112 while( Obj.childNodes.length > 0)
113 Obj.removeChild(Obj.lastChild);
114
115 return Obj;
116 };
117
118 this.show = function()
119 {
120 this.parEl = this.removeElements( this.parEl );
121 this.monthCell.firstChild.replaceData(0, this.monthCell.firstChild.nodeValue.length, this.monthname[this.mm]+"\u00a0"+this.yy);
122
123 var table = document.createElement("table");
124 table.id = "table";
125
126 this.parEl.appendChild( table );
127
128 table.appendChild( this.tableHead );
129 table.appendChild( this.tableFoot );
130
131 table.appendChild( this.createTableBody(window.innerHeight-table.offsetHeight) );
132
133 resize();
134 };
135
136 this.createTableFoot = function()
137 {
138 var tfoot = document.createElement("tfoot");
139
140 var tr = document.createElement("tr");
141 var td = document.createElement("td");
142 td.height = "1%";
143 td.colSpan = 7;
144 td.style.padding="3px 3px";
145 tfoot.appendChild(tr);
146 tr.appendChild(td);
147 var table = document.createElement("table");
148 table.width="100%";
149 td.appendChild(table);
150 tr = document.createElement("tr");
151 table.appendChild(tr);
152 for (var i=0; i<institutes.length; i++)
153 {
154 td = document.createElement("td");
155 td.width=100/institutes.length+"%";
156 td.setAttribute("style", "text-align:center;font-size:1em;border:solid #112A5D 2px;padding:3px 3px;");
157 td.changeUser = this.changeUser;
158 td.onclick = function(e) { this.changeUser(); }
159 td.appendChild(document.createTextNode(institutes[i]));
160 tr.appendChild(td);
161
162 if (i==0)
163 td.style.backgroundColor = "yellow";
164 }
165 document.getElementById("body").setAttribute("data-user", institutes[0]);
166
167
168 tr = document.createElement("tr");
169 td = document.createElement("td");
170 td.colSpan = 7;
171 td.style.paddingLeft = "0px";
172 td.style.paddingTop = "0px";
173 td.height = "1%";
174 var form = document.createElement("form");
175 var input = document.createElement("textarea");
176 input.overflow = "auto";
177 input.wrap = "virtual";
178 input.id = "comment";
179 input.value = "enter comment here";
180 input.style.color = "#888";
181 input.style.width = "100%";
182 input.rows = 5;
183 input.title = "Enter a comment. Click somewhere in the calender to store the comment.";
184 input.onchange = function() { pushComment(); };
185 input.onfocus = function() { if (input.value=="enter comment here" && input.style.color!="black") input.value=""; input.style.color="black"; };
186 input.onblur = function() { input.style.color="#888"; if (input.value=="") input.value="enter comment here"; };
187 form.appendChild(input);
188 td.appendChild( form );
189 tr.appendChild( td );
190 tfoot.appendChild(tr);
191
192 tr = document.createElement("tr");
193 td = this.getCell( "td", "logout", "calendar_week");
194 td.onclick = function(e) { logout(); }
195 td.height="1%";
196 td.colSpan = 1;
197 tr.appendChild( td );
198
199 var td = document.createElement("td");
200 td.height="1%";
201 td.colSpan = 5;
202 td.style.textAlign="center";
203 var a = document.createElement("a");
204 a.href = "overview.png";
205 a.appendChild(document.createTextNode("click here for help"));
206 td.appendChild(a);
207 tr.appendChild( td );
208
209 td = this.getCell( "td", this.timeTrigger(), "clock" );
210 td.colSpan = 1;
211 td.height="1%";
212 tr.appendChild( td );
213 tfoot.appendChild( tr );
214
215 var self = this;
216 window.setInterval(function() { td.firstChild.nodeValue = self.timeTrigger(); }, 500);
217 return tfoot;
218 }
219
220 this.createTableHead = function()
221 {
222 var thead = document.createElement("thead");
223 thead.style.height="1%";
224 var tr = document.createElement("tr");
225 var th = this.getCell( "th", "\u00AB", "prev_month" );
226
227 th.rowSpan = 2;
228 th.Instanz = this;
229 th.onclick = function() { this.Instanz.switchMonth("prev"); };
230 th.title = this.tooltip[0];
231
232 try { th.style.cursor = "pointer"; } catch(e){ th.style.cursor = "hand"; }
233 tr.appendChild( th );
234
235 this.monthCell.Instanz = this;
236 this.monthCell.rowSpan = 2;
237 this.monthCell.colSpan = 4;
238 this.monthCell.onclick = function() { this.Instanz.switchMonth("current"); };
239 this.monthCell.title = this.tooltip[2];
240
241 try { this.monthCell.style.cursor = "pointer"; } catch(e){ this.monthCell.style.cursor = "hand"; }
242 tr.appendChild( this.monthCell );
243
244 th = this.getCell( "th", "\u00BB", "next_month" );
245 th.rowSpan = 2;
246 th.Instanz = this;
247 th.onclick = function() { this.Instanz.switchMonth("next"); };
248 th.title = this.tooltip[1];
249
250 try { th.style.cursor = "pointer"; } catch(e){ th.style.cursor = "hand"; }
251 tr.appendChild( th );
252
253 th = this.getCell( "th", "\u02c4", "prev_year" );
254 th.Instanz = this;
255 th.onclick = function() { this.Instanz.switchMonth("prev_year"); };
256 th.title = this.tooltip[3];
257
258 try { th.style.cursor = "pointer"; } catch(e){ th.style.cursor = "hand"; }
259 tr.appendChild( th );
260
261 thead.appendChild( tr );
262
263 tr = document.createElement("tr");
264 th = this.getCell( "th", "\u02c5", "next_year" );
265 th.Instanz = this;
266 th.onclick = function() { this.Instanz.switchMonth("next_year"); };
267 th.title = this.tooltip[4];
268
269 try { th.style.cursor = "pointer"; } catch(e){ th.style.cursor = "hand"; }
270 tr.appendChild( th );
271
272 thead.appendChild( tr );
273
274 tr = document.createElement('tr');
275 for (var i=0; i<this.dayname.length; i++)
276 {
277 var th = this.getCell("th", this.dayname[i], "weekday" );
278 th.width=100/7+"%";
279 tr.appendChild( th );
280 }
281
282 thead.appendChild( tr );
283
284 return thead;
285 },
286
287 this.createTableBody = function(height)
288 {
289 var dayspermonth = [31,28,31,30,31,30,31,31,30,31,30,31];
290 var sevendaysaweek = 0;
291 var begin = new Date(this.yy, this.mm, 1);
292 var firstday = begin.getDay()-1;
293 if (firstday < 0)
294 firstday = 6;
295 if ((this.yy%4==0) && ((this.yy%100!=0) || (this.yy%400==0)))
296 dayspermonth[1] = 29;
297
298 var tbody = document.createElement("tbody");
299 var tr = document.createElement('tr');
300
301 tbody.height="100%";
302
303 var height="";//"20%";//100/8+"%";
304
305 if (firstday == 0)
306 {
307 for (var i=0; i<this.dayname.length; i++)
308 {
309 var prevMonth = (this.mm == 0)?11:this.mm-1;
310 var td = this.getCell( "td", dayspermonth[prevMonth]-6+i, "last_month" );
311 td.style.height=height;
312 tr.appendChild( td );
313 }
314 tbody.appendChild( tr );
315 tr = document.createElement('tr');
316 }
317
318 for (var i=0; i<firstday; i++, sevendaysaweek++)
319 {
320 var prevMonth = (this.mm == 0)?11:this.mm-1;
321 var td = this.getCell( "td", dayspermonth[prevMonth]-firstday+i+1, "last_month" );
322 td.style.height=height;
323 tr.appendChild( td );
324 }
325
326 for (var i=1; i<=dayspermonth[this.mm]; i++, sevendaysaweek++)
327 {
328 if (this.dayname.length == sevendaysaweek)
329 {
330 tbody.appendChild( tr );
331 tr = document.createElement('tr');
332 sevendaysaweek = 0;
333 }
334
335 var td = null;
336 if (i==this.date && this.mm==this.month && this.yy==this.year && (sevendaysaweek == 5 || sevendaysaweek == 6))
337 td = this.getCell( "td", i, "today weekend" );
338 else
339 if (i==this.date && this.mm==this.month && this.yy==this.year)
340 td = this.getCell( "td", i, "today" );
341 else
342 if (sevendaysaweek == 5 || sevendaysaweek == 6)
343 td = this.getCell( "td", i, "weekend" );
344 else
345 td = this.getCell( "td", i, null);
346
347 td.setDate = this.setDate;
348 td.chooseDate = this.chooseDate;
349 td.dd = i;
350 td.mm = this.mm;
351 td.yy = this.yy;
352 td.id = this.mm+"-"+i;
353 td.title = "Click to select this date.";
354
355 td.style.height=height;
356
357 td.onclick = function(e) {
358 this.chooseDate();
359 };
360
361 var sp = document.createElement("span");
362 sp.appendChild(document.createTextNode("*"));
363 sp.style.color="darkred";
364 sp.style.display="none";
365 td.appendChild(sp);
366
367 tr.appendChild( td );
368 }
369
370 var daysNextMonth = 1;
371 for (var i=sevendaysaweek; i<this.dayname.length; i++)
372 tr.appendChild( this.getCell( "td", daysNextMonth++, "next_month" ) );
373
374 tbody.appendChild( tr );
375
376 while (tbody.getElementsByTagName("tr").length<6) {
377 tr = document.createElement('tr');
378 for (var i=0; i<this.dayname.length; i++)
379 {
380 var td = this.getCell( "td", daysNextMonth++, "next_month" );
381 td.style.height=height;
382 tr.appendChild( td );
383 }
384 tbody.appendChild( tr );
385 }
386
387 requestAll(this.yy, this.mm);
388 requestAllComments(this.yy, this.mm);
389 if (this.year==this.yy && this.month==this.mm)
390 requestComment(this.year, this.month, this.date);
391 else
392 {
393 var c = document.getElementById("comment");
394 c.color="#888";
395 c.value="enter comment here";
396 }
397
398 return tbody;
399 };
400
401 this.getCalendarWeek = function(j,m,t)
402 {
403 var cwDate = this.now;
404 if (!t)
405 {
406 j = cwDate.getFullYear();
407 m = cwDate.getMonth();
408 t = cwDate.getDate();
409 }
410 cwDate = new Date(j,m,t);
411
412 var doDat = new Date(cwDate.getTime() + (3-((cwDate.getDay()+6) % 7)) * 86400000);
413 cwYear = doDat.getFullYear();
414
415 var doCW = new Date(new Date(cwYear,0,4).getTime() + (3-((new Date(cwYear,0,4).getDay()+6) % 7)) * 86400000);
416 cw = Math.floor(1.5+(doDat.getTime()-doCW.getTime())/86400000/7);
417 return cw;
418 };
419
420 function request(td)
421 {
422 var user = document.getElementById("body").getAttribute("data-user");
423 var uri = "calendar.php?toggle&y="+td.yy+"&m="+td.mm+"&d="+td.dd;
424 if (user!="User")
425 uri += "&u="+user;
426
427 var xmlHttp = new XMLHttpRequest();
428 xmlHttp.open('POST', uri, true);
429 xmlHttp.onload = function ()
430 {
431 if (xmlHttp.status!=200)
432 {
433 alert("ERROR - HTTP request: "+xmlHttp.statusText+" ["+xmlHttp.status+"]");
434 return;
435 }
436
437 var lines = xmlHttp.responseText.split('\n');
438 if (lines.length==0)
439 return;
440
441 while (td.childNodes.length>2)
442 td.removeChild(td.lastChild);
443
444 for (var i=0; i<lines.length; i++)
445 {
446 var x = lines[i].split('\t');
447 if (x.length!=2)
448 continue;
449
450 var div = document.createElement("div");
451 div.style.fontWeight="normal";
452 div.appendChild(document.createTextNode(x[1]));
453 td.appendChild(div);
454
455 for (var j=0; j<institutes.length; j++)
456 if (x[1]==institutes[j])
457 {
458 div.className += " institute";
459 break;
460 }
461 }
462
463 if (td.childNodes.length>2)
464 td.className += " enabled";
465 else
466 td.className = td.className.replace(/enabled/g, "");
467 };
468
469 xmlHttp.send();
470 }
471
472 function logout()
473 {
474 var xmlHttp = new XMLHttpRequest();
475 xmlHttp.open('POST', "calendar.php?logout", true);
476 xmlHttp.onload = function ()
477 {
478 if (xmlHttp.status!=200)
479 {
480 alert("ERROR - HTTP request: "+xmlHttp.statusText+" ["+xmlHttp.status+"]");
481 return;
482 }
483 };
484
485 xmlHttp.send();
486 }
487
488 function pushComment()
489 {
490 var c = document.getElementById("comment");
491
492 var y = c.getAttribute("data-y");
493 var m = c.getAttribute("data-m");
494 var d = c.getAttribute("data-d");
495 var v = c.value;
496
497 var uri = "calendar.php?y="+y+"&m="+m+"&d="+d+"&c="+encodeURIComponent(v);
498
499 var xmlHttp = new XMLHttpRequest();
500 xmlHttp.open('POST', uri, true);
501 xmlHttp.onload = function()
502 {
503 if (xmlHttp.status!=200)
504 {
505 alert("ERROR - HTTP request: "+xmlHttp.statusText+" ["+xmlHttp.status+"]");
506 return;
507 }
508
509 alert("Comment inserted successfully.");
510
511 var td = document.getElementById(m+"-"+d);
512 alert(td.childNodes[1]+"/"+v);
513 if (v=="")
514 {
515 td.childNodes[1].style.display="none";
516 td.title="Click to select this date.";
517 }
518 else
519 {
520 td.childNodes[1].style.display="";
521 td.title=v;
522 }
523
524 };
525
526 xmlHttp.send();
527 }
528
529 function requestComment(yy, mm, dd)
530 {
531 var c = document.getElementById("comment");
532
533 var y = c.getAttribute("data-y");
534 var m = c.getAttribute("data-m");
535 var d = c.getAttribute("data-d");
536
537 if (y==yy && m==mm && d==dd)
538 return;
539
540 var uri = "calendar.php?comment&y="+yy+"&m="+mm+"&d="+dd;
541 var xmlHttp = new XMLHttpRequest();
542 xmlHttp.open('POST', uri, true);
543 xmlHttp.onload = function ()
544 {
545 if (xmlHttp.status!=200)
546 {
547 alert("ERROR - HTTP request: "+xmlHttp.statusText+" ["+xmlHttp.status+"]");
548 return;
549 }
550
551 var td = document.getElementById(mm+"-"+dd);
552
553 c.color="#888";
554 if (xmlHttp.responseText=="")
555 {
556 c.value="enter comment here";
557 td.childNodes[1].style.display="none";
558 td.title="";
559 }
560 else
561 {
562 c.value = xmlHttp.responseText;
563 td.childNodes[1].style.display="";
564 td.title=xmlHttp.responseText;
565 }
566
567 c.setAttribute("data-y", yy);
568 c.setAttribute("data-m", mm);
569 c.setAttribute("data-d", dd);
570 };
571
572 xmlHttp.send();
573 }
574
575 function requestAll(yy, mm)
576 {
577 var uri = "calendar.php?y="+yy+"&m="+mm;
578 var xmlHttp = new XMLHttpRequest();
579 xmlHttp.open('POST', uri, true);
580 xmlHttp.onload = function ()
581 {
582 if (xmlHttp.status!=200)
583 {
584 alert("ERROR - HTTP request: "+xmlHttp.statusText+" ["+xmlHttp.status+"]");
585 return;
586 }
587
588 var lines = xmlHttp.responseText.split('\n');
589 if (lines.length==0)
590 return;
591
592 for (var i=0; i<lines.length; i++)
593 {
594 var x = lines[i].split('\t');
595 if (x.length!=2)
596 continue;
597
598 var td = document.getElementById(mm+"-"+x[0]);
599
600 var div = document.createElement("div");
601 div.style.fontWeight="normal";
602 div.appendChild(document.createTextNode(x[1]));
603 td.appendChild(div);
604
605 for (var j=0; j<institutes.length; j++)
606 if (x[1]==institutes[j])
607 {
608 div.className += " institute";
609 break;
610 }
611
612 td.className += " enabled";
613 }
614 };
615
616 xmlHttp.send();
617 }
618
619 function requestAllComments(yy, mm)
620 {
621 var uri = "calendar.php?comment&y="+yy+"&m="+mm;
622 var xmlHttp = new XMLHttpRequest();
623 xmlHttp.open('POST', uri, true);
624 xmlHttp.onload = function ()
625 {
626 if (xmlHttp.status!=200)
627 {
628 alert("ERROR - HTTP request: "+xmlHttp.statusText+" ["+xmlHttp.status+"]");
629 return;
630 }
631
632 if (xmlHttp.responseText<4)
633 return;
634
635 var pos = 6;
636
637 while (pos<xmlHttp.responseText.length)
638 {
639 var len = parseInt(xmlHttp.responseText.substr(pos-6, 4), 10);
640 var dd = parseInt(xmlHttp.responseText.substr(pos-2, 2), 10);
641 var com = xmlHttp.responseText.substr(pos, len);
642 pos += len+6;
643
644 if (com!="")
645 {
646 var td = document.getElementById(mm+"-"+dd);
647 td.childNodes[1].style.display="";
648 td.title=com;
649 }
650 }
651 };
652
653 xmlHttp.send();
654 }
655
656 this.setDate = function()
657 {
658 request(this);
659 };
660
661 this.changeUser = function()
662 {
663 var sib = this.nextSibling;
664 while (sib)
665 {
666 sib.style.backgroundColor = "";
667 sib = sib.nextSibling;
668 }
669
670 sib = this.previousSibling;
671 while (sib)
672 {
673 sib.style.backgroundColor = "";
674 sib = sib.previousSibling;
675 }
676
677 this.style.backgroundColor = "yellow";
678
679 document.getElementById("body").setAttribute("data-user", this.firstChild.textContent);
680 };
681
682 this.chooseDate = function()
683 {
684 while (document.getElementsByClassName("choosen")[0])
685 {
686 var e = document.getElementsByClassName("choosen")[0];
687 e.title = "Click to select this date.";
688 e.className = e.className.replace(/choosen/g, "");
689 e.onclick = function() {
690 this.chooseDate();
691 };
692 }
693
694 this.className += " choosen";
695 this.title = "Click again to add or remove your name.";
696
697 requestComment(this.yy, this.mm, this.dd);
698
699 this.onclick = function() {
700 this.setDate();
701 };
702 };
703
704 this.timeTrigger = function()
705 {
706 var now = new Date();
707 var ss = (now.getSeconds()<10)?"0"+now.getSeconds():now.getSeconds();
708 var mm = (now.getMinutes()<10)?"0"+now.getMinutes():now.getMinutes();
709 var hh = (now.getHours() <10)?"0"+now.getHours() :now.getHours();
710
711 var kw = "KW\u00a0" + this.getCalendarWeek(this.year, this.month, this.date);
712 var str = hh+":"+mm+":"+ss+"\u00a0["+kw+"]";
713 return str;
714 };
715
716 this.getCell = function(tag, str, cssClass)
717 {
718 var El = document.createElement( tag );
719 El.appendChild(document.createTextNode( str ));
720 if (cssClass != null)
721 El.className = cssClass;
722 return El;
723 },
724
725 this.switchMonth = function( s )
726 {
727 switch (s)
728 {
729 case "prev":
730 this.yy = (this.mm == 0) ? this.yy-1 : this.yy;
731 this.mm = (this.mm == 0) ? 11 : this.mm-1;
732 break;
733
734 case "next":
735 this.yy = (this.mm == 11) ? this.yy+1 : this.yy;
736 this.mm = (this.mm == 11) ? 0 : this.mm+1;
737 break;
738
739 case "prev_year":
740 this.yy = this.yy-1;
741 break;
742
743 case "next_year":
744 this.yy = this.yy+1;
745 break;
746
747 case "current":
748 this.yy = this.year;
749 this.mm = this.month;
750 break;
751 }
752 this.show();
753 }
754}
755
756var DOMContentLoaded = false;
757function addContentLoadListener (func)
758{
759 if (document.addEventListener)
760 {
761 var DOMContentLoadFunction = function ()
762 {
763 window.DOMContentLoaded = true;
764 func();
765 };
766
767 document.addEventListener("DOMContentLoaded", DOMContentLoadFunction, false);
768 }
769
770 var oldfunc = (window.onload || new Function());
771
772 window.onload = function ()
773 {
774 if (!window.DOMContentLoaded)
775 {
776 oldfunc();
777 func();
778 }
779 };
780}
781
782addContentLoadListener( function() {
783new CalendarJS().init("calendar");
784//new CalendarJS().init("calendar", new Date(2009, 1, 15));
785} );
Note: See TracBrowser for help on using the repository browser.