1 /* JavaScript for SOGoCalendar */
5 var listFilter = 'view_today';
7 var listOfSelection = null;
8 var selectedCalendarCell;
10 var showCompletedTasks = 0;
13 var currentView = "weekview";
15 var cachedDateSelectors = new Array();
17 var contactSelectorAction = 'calendars-contacts';
19 var eventsToDelete = new Array();
20 var ownersOfEventsToDelete = new Array();
22 var usersRightsWindowHeight = 250;
23 var usersRightsWindowWidth = 502;
25 function newEvent(sender, type) {
31 if (sender.parentNode.getAttribute("id") != "toolbar"
32 && currentView == "multicolumndayview" && type == "event")
33 user = sender.parentNode.parentNode.getAttribute("user");
35 var hour = sender.hour;
37 hour = sender.getAttribute("hour");
38 var urlstr = UserFolderURL + "../" + user + "/Calendar/new" + type;
39 var params = new Array();
41 params.push("day=" + day);
43 params.push("hm=" + hour);
44 if (params.length > 0)
45 urlstr += "?" + params.join("&");
47 window.open(urlstr, "", "width=490,height=470,resizable=0");
49 return false; /* stop following the link */
52 function onMenuNewEventClick(event) {
53 newEvent(this, "event");
56 function onMenuNewTaskClick(event) {
57 newEvent(this, "task");
60 function _editEventId(id, owner) {
63 urlBase = UserFolderURL + "../" + owner + "/";
64 urlBase += "Calendar/"
66 var urlstr = urlBase + id + "/edit";
67 var targetname = "SOGo_edit_" + id;
68 var win = window.open(urlstr, "_blank",
69 "width=490,height=470,resizable=0");
73 function editEvent() {
74 if (listOfSelection) {
75 var nodes = listOfSelection.getSelectedRows();
77 for (var i = 0; i < nodes.length; i++)
78 _editEventId(nodes[i].getAttribute("id"),
80 } else if (selectedCalendarCell) {
81 _editEventId(selectedCalendarCell[0].cname,
82 selectedCalendarCell[0].owner);
85 return false; /* stop following the link */
88 function _batchDeleteEvents() {
89 var events = eventsToDelete.shift();
90 var owner = ownersOfEventsToDelete.shift();
91 var urlstr = (UserFolderURL + "../" + owner + "/Calendar/batchDelete?ids="
93 document.deleteEventAjaxRequest = triggerAjaxRequest(urlstr,
98 function deleteEvent() {
99 if (listOfSelection) {
100 var nodes = listOfSelection.getSelectedRows();
102 if (nodes.length > 0) {
104 if (listOfSelection == $("tasksList"))
105 label = labels["taskDeleteConfirmation"].decodeEntities();
107 label = labels["eventDeleteConfirmation"].decodeEntities();
109 if (confirm(label)) {
110 if (document.deleteEventAjaxRequest) {
111 document.deleteEventAjaxRequest.aborted = true;
112 document.deleteEventAjaxRequest.abort();
114 var sortedNodes = new Array();
115 var owners = new Array();
117 for (var i = 0; i < nodes.length; i++) {
118 var owner = nodes[i].owner;
119 if (!sortedNodes[owner]) {
120 sortedNodes[owner] = new Array();
123 sortedNodes[owner].push(nodes[i].cname);
125 for (var i = 0; i < owners.length; i++) {
126 ownersOfEventsToDelete.push(owners[i]);
127 eventsToDelete.push(sortedNodes[owners[i]]);
129 _batchDeleteEvents();
133 else if (selectedCalendarCell) {
134 var label = labels["eventDeleteConfirmation"].decodeEntities();
135 if (confirm(label)) {
136 if (document.deleteEventAjaxRequest) {
137 document.deleteEventAjaxRequest.aborted = true;
138 document.deleteEventAjaxRequest.abort();
140 eventsToDelete.push([selectedCalendarCell[0].cname]);
141 ownersOfEventsToDelete.push(selectedCalendarCell[0].owner);
142 _batchDeleteEvents();
146 window.alert("no selection");
151 function modifyEvent(sender, modification) {
152 var currentLocation = '' + window.location;
153 var arr = currentLocation.split("/");
154 arr[arr.length-1] = modification;
156 document.modifyEventAjaxRequest = triggerAjaxRequest(arr.join("/"),
163 function closeInvitationWindow() {
164 var closeDiv = document.createElement("div");
165 closeDiv.addClassName("javascriptPopupBackground");
166 var closePseudoWin = document.createElement("div");
167 closePseudoWin.addClassName("javascriptMessagePseudoTopWindow");
168 closePseudoWin.style.top = "0px;";
169 closePseudoWin.style.left = "0px;";
170 closePseudoWin.style.right = "0px;";
171 closePseudoWin.appendChild(document.createTextNode(labels["closeThisWindowMessage"].decodeEntities()));
172 document.body.appendChild(closeDiv);
173 document.body.appendChild(closePseudoWin);
176 function modifyEventCallback(http) {
177 if (http.readyState == 4) {
178 if (http.status == 200) {
179 var mailInvitation = queryParameters["mail-invitation"];
180 if (mailInvitation && mailInvitation.toLowerCase() == "yes")
181 closeInvitationWindow();
183 window.opener.setTimeout("refreshEventsAndDisplay();", 100);
184 window.setTimeout("window.close();", 100);
188 // log("showing alert...");
189 window.alert(labels["eventPartStatModificationError"]);
191 document.modifyEventAjaxRequest = null;
195 function deleteEventCallback(http) {
196 if (http.readyState == 4
197 && http.status == 200) {
198 var nodes = http.callbackData;
199 for (var i = 0; i < nodes.length; i++) {
200 var node = $(nodes[i]);
202 node.parentNode.removeChild(node);
204 if (eventsToDelete.length)
205 _batchDeleteEvents();
207 document.deleteEventAjaxRequest = null;
210 changeCalendarDisplay();
214 log ("deleteEventCallback Ajax error");
217 function editDoubleClickedEvent(event) {
218 _editEventId(this.cname, this.owner);
220 preventDefault(event);
221 event.cancelBubble = true;
224 function onSelectAll() {
225 var list = $("eventsList");
226 list.selectRowsMatchingClass("eventRow");
231 function onDaySelect(node) {
232 var day = node.getAttribute('day');
233 var needRefresh = (listFilter == 'view_selectedday'
234 && day != currentDay);
236 var td = $(node).getParentWithTagName("td");
237 var table = $(td).getParentWithTagName("table");
239 // log ("table.selected: " + table.selected);
241 if (document.selectedDate)
242 document.selectedDate.deselect();
245 document.selectedDate = td;
247 changeCalendarDisplay( { "day": day } );
254 function onDateSelectorGotoMonth(event) {
255 var day = this.getAttribute("date");
257 changeDateSelectorDisplay(day, true);
262 function onCalendarGotoDay(node) {
263 var day = node.getAttribute("date");
265 changeDateSelectorDisplay(day);
266 changeCalendarDisplay( { "day": day } );
271 function gotoToday() {
272 changeDateSelectorDisplay('');
273 changeCalendarDisplay();
278 function setDateSelectorContent(content) {
279 var div = $("dateSelectorView");
281 div.innerHTML = content;
282 if (currentDay.length > 0)
283 restoreCurrentDaySelection(div);
285 initDateSelectorEvents();
288 function dateSelectorCallback(http) {
289 if (http.readyState == 4
290 && http.status == 200) {
291 document.dateSelectorAjaxRequest = null;
292 var content = http.responseText;
293 setDateSelectorContent(content);
294 cachedDateSelectors[http.callbackData] = content;
297 log ("dateSelectorCallback Ajax error");
300 function eventsListCallback(http) {
301 if (http.readyState == 4
302 && http.status == 200) {
303 var div = $("eventsListView");
305 document.eventsListAjaxRequest = null;
306 var table = $("eventsList").tBodies[0];
307 var params = parseQueryParameters(http.callbackData);
308 sortKey = params["sort"];
309 sortOrder = params["desc"];
310 configureSortableTableHeaders();
312 var data = http.responseText.evalJSON(true);
313 for (var i = 0; i < data.length; i++) {
314 var row = document.createElement("tr");
315 table.appendChild(row);
316 $(row).addClassName("eventRow");
317 row.setAttribute("id", escape(data[i][0]));
318 row.cname = escape(data[i][0]);
319 row.owner = data[i][1];
321 var startDate = new Date();
322 startDate.setTime(data[i][4] * 1000);
323 row.day = startDate.getDayString();
324 row.hour = startDate.getHourString();
325 Event.observe(row, "click",
326 onEventClick.bindAsEventListener(row));
327 Event.observe(row, "dblclick",
328 editDoubleClickedEvent.bindAsEventListener(row));
329 Event.observe(row, "contextmenu",
330 onEventContextMenu.bindAsEventListener(row));
332 var td = document.createElement("td");
334 Event.observe(td, "mousedown", listRowMouseDownHandler, true);
335 td.appendChild(document.createTextNode(data[i][3]));
337 td = document.createElement("td");
339 Event.observe(td, "mousedown", listRowMouseDownHandler, true);
340 td.appendChild(document.createTextNode(data[i][8]));
342 td = document.createElement("td");
344 Event.observe(td, "mousedown", listRowMouseDownHandler, true);
345 td.appendChild(document.createTextNode(data[i][9]));
347 td = document.createElement("td");
349 Event.observe(td, "mousedown", listRowMouseDownHandler, true);
350 td.appendChild(document.createTextNode(data[i][6]));
354 log ("eventsListCallback Ajax error");
357 function tasksListCallback(http) {
358 var div = $("tasksListView");
360 if (http.readyState == 4
361 && http.status == 200) {
362 document.tasksListAjaxRequest = null;
363 var list = $("tasksList");
364 var data = http.responseText.evalJSON(true);
366 for (var i = 0; i < data.length; i++) {
367 //log(i + " = " + data[i][3]);
368 var listItem = document.createElement("li");
369 list.appendChild(listItem);
370 Event.observe(listItem, "mousedown", listRowMouseDownHandler); // causes problem with Safari
371 Event.observe(listItem, "click", onRowClick);
372 Event.observe(listItem, "dblclick", editDoubleClickedEvent.bindAsEventListener(listItem));
373 listItem.setAttribute("id", data[i][0]);
374 $(listItem).addClassName(data[i][5]);
375 var owner = data[i][1];
376 listItem.owner = owner;
377 $(listItem).addClassName("ownerIs" + owner);
378 listItem.cname = escape(data[i][0]);
379 var input = document.createElement("input");
380 input.setAttribute("type", "checkbox");
381 listItem.appendChild(input);
382 Event.observe(input, "click", updateTaskStatus.bindAsEventListener(input), true);
383 input.setAttribute("value", "1");
385 input.setAttribute("checked", "checked");
386 $(input).addClassName("checkBox");
387 listItem.appendChild(document.createTextNode(data[i][3]));
390 list.scrollTop = list.previousScroll;
392 if (http.callbackData) {
393 var selectedNodesId = http.callbackData;
394 for (var i = 0; i < selectedNodesId.length; i++) {
395 // log(selectedNodesId[i] + " (" + i + ") is selected");
396 $(selectedNodesId[i]).select();
400 log ("tasksListCallback: no data");
403 log ("tasksListCallback Ajax error");
406 function restoreCurrentDaySelection(div) {
407 var elements = $(div).getElementsByTagName("a");
410 while (!day && i < elements.length)
412 day = elements[i].day;
417 && day.substr(0, 6) == currentDay.substr(0, 6)) {
418 for (i = 0; i < elements.length; i++) {
419 day = elements[i].day;
420 if (day && day == currentDay) {
421 var td = $(elements[i]).getParentWithTagName("td");
422 if (document.selectedDate)
423 document.selectedDate.deselect();
425 document.selectedDate = td;
431 function changeDateSelectorDisplay(day, keepCurrentDay) {
432 var url = ApplicationBaseURL + "dateselector";
434 url += "?day=" + day;
436 if (day != currentDay) {
440 var month = day.substr(0, 6);
441 if (cachedDateSelectors[month]) {
442 // log ("restoring cached selector for month: " + month);
443 setDateSelectorContent(cachedDateSelectors[month]);
446 // log ("loading selector for month: " + month);
447 if (document.dateSelectorAjaxRequest) {
448 document.dateSelectorAjaxRequest.aborted = true;
449 document.dateSelectorAjaxRequest.abort();
451 document.dateSelectorAjaxRequest
452 = triggerAjaxRequest(url,
453 dateSelectorCallback,
459 function changeCalendarDisplay(time, newView) {
460 var url = ApplicationBaseURL + ((newView) ? newView : currentView);
462 selectedCalendarCell = null;
474 url += "?day=" + day;
477 // log ("switching to view: " + newView);
478 // log ("changeCalendarDisplay: " + url);
480 if (document.dayDisplayAjaxRequest) {
481 // log ("aborting day ajaxrq");
482 document.dayDisplayAjaxRequest.aborted = true;
483 document.dayDisplayAjaxRequest.abort();
485 document.dayDisplayAjaxRequest
486 = triggerAjaxRequest(url, calendarDisplayCallback,
487 { "view": newView, "day": day, "hour": hour });
492 function _ensureView(view) {
493 if (currentView != view)
494 changeCalendarDisplay(null, view);
499 function onDayOverview() {
500 return _ensureView("dayview");
503 function onMulticolumnDayOverview() {
504 return _ensureView("multicolumndayview");
507 function onWeekOverview() {
508 return _ensureView("weekview");
511 function onMonthOverview() {
512 return _ensureView("monthview");
515 function scrollDayView(hour) {
518 if (hour.length == 3)
519 rowNumber = parseInt(hour.substr(0, 1));
521 if (hour.substr(0, 1) == "0")
522 rowNumber = parseInt(hour.substr(1, 1));
524 rowNumber = parseInt(hour.substr(0, 2));
529 var daysView = $("daysView");
531 $(daysView.childNodesWithTag("div")[0]).childNodesWithTag("div");
532 if (hours.length > 0)
533 daysView.scrollTop = hours[rowNumber].offsetTop;
536 function onClickableCellsDblClick(event) {
537 newEvent(this, 'event');
539 event.cancelBubble = true;
540 event.returnValue = false;
543 function refreshCalendarEvents() {
544 var todayDate = new Date();
547 if (currentView == "dayview") {
551 sd = todayDate.getDayString();
554 else if (currentView == "weekview") {
557 startDate = currentDay.asDate();
559 startDate = todayDate;
560 startDate = startDate.beginOfWeek();
561 sd = startDate.getDayString();
562 var endDate = new Date();
563 endDate.setTime(startDate.getTime());
565 ed = endDate.getDayString();
570 monthDate = currentDay.asDate();
572 monthDate = todayDate;
573 monthDate.setDate(1);
574 sd = monthDate.beginOfWeek().getDayString();
576 var lastMonthDate = new Date();
577 lastMonthDate.setTime(monthDate.getTime());
578 lastMonthDate.setMonth(monthDate.getMonth() + 1);
579 lastMonthDate.addDays(-1);
580 ed = lastMonthDate.endOfWeek().getDayString();
582 if (document.refreshCalendarEventsAjaxRequest) {
583 document.refreshCalendarEventsAjaxRequest.aborted = true;
584 document.refreshCalendarEventsAjaxRequest.abort();
586 var url = ApplicationBaseURL + "eventslist?sd=" + sd + "&ed=" + ed;
587 document.refreshCalendarEventsAjaxRequest
588 = triggerAjaxRequest(url, refreshCalendarEventsCallback,
589 {"startDate": sd, "endDate": ed});
592 function refreshCalendarEventsCallback(http) {
593 if (http.readyState == 4
594 && http.status == 200) {
595 var data = http.responseText.evalJSON(true);
596 // log("refresh calendar events: " + data.length);
597 for (var i = 0; i < data.length; i++)
598 drawCalendarEvent(data[i],
599 http.callbackData["startDate"],
600 http.callbackData["endDate"]);
603 log("AJAX error when refreshing calendar events");
606 function drawCalendarEvent(eventData, sd, ed) {
607 var viewStartDate = sd.asDate();
608 var viewEndDate = ed.asDate();
610 var startDate = new Date();
611 startDate.setTime(eventData[4] * 1000);
612 var endDate = new Date();
613 endDate.setTime(eventData[5] * 1000);
615 var days = startDate.daysUpTo(endDate);
617 var divs = new Array();
620 if (currentView == "monthview"
621 && (eventData[7] == 0))
622 title = startDate.getDisplayHoursString() + " " + eventData[3];
624 title = eventData[3];
626 // log("title: " + title);
627 // log("viewS: " + viewStartDate);
628 var startHour = null;
631 var siblings = new Array();
632 for (var i = 0; i < days.length; i++)
633 if (days[i].earlierDate(viewStartDate) == viewStartDate
634 && days[i].laterDate(viewEndDate) == viewEndDate) {
637 // log("day: " + days[i]);
639 var quarters = (startDate.getHours() * 4
640 + Math.floor(startDate.getMinutes() / 15));
642 startHour = startDate.getDisplayHoursString();
643 endHour = endDate.getDisplayHoursString();
650 if (i == days.length - 1) {
651 var quarters = (endDate.getHours() * 4
652 + Math.ceil(endDate.getMinutes() / 15));
657 lasts = ends - starts;
661 var eventDiv = newEventDIV(eventData[0], eventData[1], starts, lasts,
663 siblings.push(eventDiv);
664 eventDiv.siblings = siblings;
665 var dayString = days[i].getDayString();
666 // log("day: " + dayString);
667 var parentDiv = null;
668 if (currentView == "monthview") {
669 var dayDivs = $("monthDaysView").childNodesWithTag("div");
671 while (!parentDiv && j < dayDivs.length) {
672 if (dayDivs[j].getAttribute("day") == dayString)
673 parentDiv = dayDivs[j];
679 if (eventData[7] == 0) {
680 var daysView = $("daysView");
681 var eventsDiv = $(daysView).childNodesWithTag("div")[1];
682 var dayDivs = $(eventsDiv).childNodesWithTag("div");
684 while (!parentDiv && j < dayDivs.length) {
685 if (dayDivs[j].getAttribute("day") == dayString)
686 parentDiv = dayDivs[j].childNodesWithTag("div")[0];
692 var header = $("calendarHeader");
693 var daysDiv = $(header).childNodesWithTag("div")[1];
694 var dayDivs = $(daysDiv).childNodesWithTag("div");
696 while (!parentDiv && j < dayDivs.length) {
697 if (dayDivs[j].getAttribute("day") == dayString)
698 parentDiv = dayDivs[j];
705 parentDiv.appendChild(eventDiv);
709 function newEventDIV(cname, owner, starts, lasts,
710 startHour, endHour, title) {
711 var eventDiv = document.createElement("div");
712 eventDiv.cname = escape(cname);
713 eventDiv.owner = owner;
714 $(eventDiv).addClassName("event");
715 $(eventDiv).addClassName("starts" + starts);
716 $(eventDiv).addClassName("lasts" + lasts);
717 for (var i = 1; i < 5; i++) {
718 var shadowDiv = document.createElement("div");
719 eventDiv.appendChild(shadowDiv);
720 $(shadowDiv).addClassName("shadow");
721 $(shadowDiv).addClassName("shadow" + i);
723 var innerDiv = document.createElement("div");
724 eventDiv.appendChild(innerDiv);
725 $(innerDiv).addClassName("eventInside");
726 $(innerDiv).addClassName("ownerIs" + owner);
728 var gradientDiv = document.createElement("div");
729 innerDiv.appendChild(gradientDiv);
730 $(gradientDiv).addClassName("gradient");
731 var gradientImg = document.createElement("img");
732 gradientDiv.appendChild(gradientImg);
733 gradientImg.src = ResourcesURL + "/event-gradient.png";
735 var textDiv = document.createElement("div");
736 innerDiv.appendChild(textDiv);
737 $(textDiv).addClassName("text");
739 var headerSpan = document.createElement("span");
740 textDiv.appendChild(headerSpan);
741 $(headerSpan).addClassName("eventHeader");
742 headerSpan.appendChild(document.createTextNode(startHour + " - "
744 textDiv.appendChild(document.createElement("br"));
746 textDiv.appendChild(document.createTextNode(title));
748 Event.observe(eventDiv, "mousedown", listRowMouseDownHandler);
749 Event.observe(eventDiv, "click",
750 onCalendarSelectEvent.bindAsEventListener(eventDiv));
751 Event.observe(eventDiv, "dblclick",
752 editDoubleClickedEvent.bindAsEventListener(eventDiv));
757 function calendarDisplayCallback(http) {
758 var div = $("calendarView");
760 if (http.readyState == 4
761 && http.status == 200) {
762 document.dayDisplayAjaxRequest = null;
763 div.innerHTML = http.responseText;
764 if (http.callbackData["view"])
765 currentView = http.callbackData["view"];
766 if (http.callbackData["day"])
767 currentDay = http.callbackData["day"];
770 if (http.callbackData["hour"])
771 hour = http.callbackData["hour"];
773 if (currentView == "monthview")
774 contentView = $("calendarContent");
777 contentView = $("daysView");
779 refreshCalendarEvents();
780 var days = document.getElementsByClassName("day", contentView);
781 if (currentView == "monthview")
782 for (var i = 0; i < days.length; i++) {
783 Event.observe(days[i], "click", onCalendarSelectDay.bindAsEventListener(days[i]));
784 Event.observe(days[i], "dblclick", onClickableCellsDblClick.bindAsEventListener(days[i]));
787 var headerDivs = $("calendarHeader").childNodesWithTag("div");
788 var headerDaysLabels = document.getElementsByClassName("day", headerDivs[0]);
789 var headerDays = document.getElementsByClassName("day", headerDivs[1]);
790 for (var i = 0; i < days.length; i++) {
791 headerDays[i].hour = "allday";
792 Event.observe(headerDaysLabels[i], "mousedown", listRowMouseDownHandler);
793 Event.observe(headerDays[i], "click",
794 onCalendarSelectDay.bindAsEventListener(days[i]));
795 Event.observe(headerDays[i], "dblclick",
796 onClickableCellsDblClick.bindAsEventListener(headerDays[i]));
797 Event.observe(days[i], "click",
798 onCalendarSelectDay.bindAsEventListener(days[i]));
799 var clickableCells = document.getElementsByClassName("clickableHourCell",
801 for (var j = 0; j < clickableCells.length; j++)
802 Event.observe(clickableCells[j], "dblclick",
803 onClickableCellsDblClick.bindAsEventListener(clickableCells[j]));
808 log ("calendarDisplayCallback Ajax error (" + http.readyState + "/" + http.status + ")");
811 function assignCalendar(name) {
812 if (typeof(skycalendar) != "undefined") {
815 node.calendar = new skycalendar(node);
816 node.calendar.setCalendarPage(ResourcesURL + "/skycalendar.html");
817 var dateFormat = node.getAttribute("dateFormat");
819 node.calendar.setDateFormat(dateFormat);
823 function popupCalendar(node) {
824 var nodeId = node.getAttribute("inputId");
825 var input = $(nodeId);
826 input.calendar.popup();
831 function onEventContextMenu(event) {
832 var topNode = $("eventsList");
835 var menu = $("eventsListMenu");
837 Event.observe(menu, "hideMenu", onEventContextMenuHide);
838 popupMenu(event, "eventsListMenu", this);
840 var topNode = $("eventsList");
841 var selectedNodes = topNode.getSelectedRows();
842 topNode.menuSelectedRows = selectedNodes;
843 for (var i = 0; i < selectedNodes.length; i++)
844 selectedNodes[i].deselect();
846 topNode.menuSelectedEntry = this;
850 function onEventContextMenuHide(event) {
851 var topNode = $("eventsList");
853 if (topNode.menuSelectedEntry) {
854 topNode.menuSelectedEntry.deselect();
855 topNode.menuSelectedEntry = null;
857 if (topNode.menuSelectedRows) {
858 var nodeIds = topNode.menuSelectedRows;
859 for (var i = 0; i < nodeIds.length; i++) {
860 var node = $(nodeIds[i]);
863 topNode.menuSelectedRows = null;
867 function onEventsSelectionChange() {
868 listOfSelection = this;
869 this.removeClassName("_unfocused");
870 $("tasksList").addClassName("_unfocused");
873 function onTasksSelectionChange() {
874 listOfSelection = this;
875 this.removeClassName("_unfocused");
876 $("eventsList").addClassName("_unfocused");
879 function _loadEventHref(href) {
880 if (document.eventsListAjaxRequest) {
881 document.eventsListAjaxRequest.aborted = true;
882 document.eventsListAjaxRequest.abort();
884 var url = ApplicationBaseURL + href;
885 document.eventsListAjaxRequest
886 = triggerAjaxRequest(url, eventsListCallback, href);
888 var table = $("eventsList").tBodies[0];
889 while (table.rows.length > 1)
890 table.removeChild(table.rows[1]);
895 function _loadTasksHref(href) {
896 if (document.tasksListAjaxRequest) {
897 document.tasksListAjaxRequest.aborted = true;
898 document.tasksListAjaxRequest.abort();
900 url = ApplicationBaseURL + href;
902 var tasksList = $("tasksList");
905 selectedIds = tasksList.getSelectedNodesId();
908 document.tasksListAjaxRequest
909 = triggerAjaxRequest(url, tasksListCallback, selectedIds);
911 tasksList.previousScroll = tasksList.scrollTop;
912 while (tasksList.childNodes.length)
913 tasksList.removeChild(tasksList.childNodes[0]);
918 function onHeaderClick(event) {
919 // log("onHeaderClick: " + this.link);
920 _loadEventHref(this.link);
922 preventDefault(event);
925 function refreshEvents() {
926 return _loadEventHref("eventslist?desc=" + sortOrder
928 + "&day=" + currentDay
929 + "&filterpopup=" + listFilter);
932 function refreshTasks() {
933 return _loadTasksHref("taskslist?show-completed=" + showCompletedTasks);
936 function refreshEventsAndDisplay() {
938 changeCalendarDisplay();
941 function onListFilterChange() {
942 var node = $("filterpopup");
944 listFilter = node.value;
945 // log ("listFilter = " + listFilter);
947 return refreshEvents();
950 function onEventClick(event) {
952 var hour = this.hour;
954 changeCalendarDisplay( { "day": day, "hour": hour} );
955 changeDateSelectorDisplay(day);
957 return onRowClick(event);
960 function selectMonthInMenu(menu, month) {
961 var entries = menu.childNodes[1].childNodesWithTag("LI");
962 for (i = 0; i < entries.length; i++) {
963 var entry = entries[i];
964 var entryMonth = entry.getAttribute("month");
965 if (entryMonth == month)
966 entry.addClassName("currentMonth");
968 entry.removeClassName("currentMonth");
972 function selectYearInMenu(menu, month) {
973 var entries = menu.childNodes[1].childNodes;
974 for (i = 0; i < entries.length; i++) {
975 var entry = entries[i];
976 if (entry instanceof HTMLLIElement) {
977 var entryMonth = entry.innerHTML;
978 if (entryMonth == month)
979 entry.addClassName("currentMonth");
981 entry.removeClassName("currentMonth");
986 function popupMonthMenu(event) {
987 if (event.button == 0) {
988 var id = this.getAttribute("id");
989 if (id == "monthLabel")
990 menuId = "monthListMenu";
992 menuId = "yearListMenu";
994 var popup = $(menuId);
995 if (id == "monthLabel")
996 selectMonthInMenu(popup, this.getAttribute("month"));
998 selectYearInMenu(popup, this.innerHTML);
1000 popupToolbarMenu(this, menuId);
1005 function onMonthMenuItemClick(event) {
1006 var month = '' + this.getAttribute("month");
1007 var year = '' + $("yearLabel").innerHTML;
1009 changeDateSelectorDisplay(year + month + "01", true);
1012 function onYearMenuItemClick(event) {
1013 var month = '' + $("monthLabel").getAttribute("month");;
1014 var year = '' + this.innerHTML;
1016 changeDateSelectorDisplay(year + month + "01", true);
1019 function onSearchFormSubmit() {
1020 log ("search not implemented");
1025 function onCalendarSelectEvent() {
1026 var list = $("eventsList");
1029 if (selectedCalendarCell)
1030 for (var i = 0; i < selectedCalendarCell.length; i++)
1031 selectedCalendarCell[i].deselect();
1033 for (var i = 0; i < this.siblings.length; i++)
1034 this.siblings[i].select();
1035 selectedCalendarCell = this.siblings;
1036 var row = $(this.cname);
1038 var div = row.parentNode.parentNode.parentNode;
1039 div.scrollTop = row.offsetTop - (div.offsetHeight / 2);
1044 function onCalendarSelectDay(event) {
1046 if (currentView == "multicolumndayview")
1047 day = this.getAttribute("day");
1049 day = this.getAttribute("day");
1050 var needRefresh = (listFilter == 'view_selectedday'
1051 && day != currentDay);
1053 if (currentView == 'weekview')
1054 changeWeekCalendarDisplayOfSelectedDay(this);
1055 else if (currentView == 'monthview')
1056 changeMonthCalendarDisplayOfSelectedDay(this);
1057 changeDateSelectorDisplay(day);
1059 if (listOfSelection) {
1060 listOfSelection.addClassName("_unfocused");
1061 listOfSelection = null;
1068 function changeWeekCalendarDisplayOfSelectedDay(node) {
1069 var days = document.getElementsByClassName("day", node.parentNode);
1070 var headerDiv = $("calendarHeader").childNodesWithTag("div")[1];
1071 var headerDays = document.getElementsByClassName("day", headerDiv);
1073 // log ("days: " + days.length + "; headerDays: " + headerDays.length);
1074 for (var i = 0; i < days.length; i++)
1075 if (days[i] != node) {
1076 // log("unselect day : " + i);
1077 headerDays[i].removeClassName("selectedDay");
1078 days[i].removeClassName("selectedDay");
1081 // log("selected day : " + i);
1082 headerDays[i].addClassName("selectedDay");
1083 days[i].addClassName("selectedDay");
1087 function findMonthCalendarSelectedCell(daysContainer) {
1091 while (!found && i < daysContainer.childNodes.length) {
1092 var currentNode = daysContainer.childNodes[i];
1093 if (currentNode.tagName == 'DIV'
1094 && currentNode.hasClassName("selectedDay")) {
1095 daysContainer.selectedCell = currentNode;
1103 function changeMonthCalendarDisplayOfSelectedDay(node) {
1104 var daysContainer = node.parentNode;
1105 if (!daysContainer.selectedCell)
1106 findMonthCalendarSelectedCell(daysContainer);
1108 if (daysContainer.selectedCell)
1109 daysContainer.selectedCell.removeClassName("selectedDay");
1110 daysContainer.selectedCell = node;
1111 node.addClassName("selectedDay");
1114 function onShowCompletedTasks(event) {
1115 showCompletedTasks = (this.checked ? 1 : 0);
1117 return refreshTasks();
1120 function updateTaskStatus(event) {
1121 var taskId = this.parentNode.getAttribute("id");
1122 var taskOwner = this.parentNode.owner;
1123 var newStatus = (this.checked ? 1 : 0);
1124 var http = createHTTPClient();
1127 newStatus = (newStatus ? 0 : 1);
1128 //log("update task status: " + taskId + " to " + this.checked);
1129 event.cancelBubble = true;
1131 url = (UserFolderURL + "../" + taskOwner
1132 + "/Calendar/" + taskId
1133 + "/changeStatus?status=" + newStatus);
1136 // log ("url: " + url);
1137 // TODO: add parameter to signal that we are only interested in OK
1138 http.open("POST", url, false /* not async */);
1141 if (http.status == 200)
1144 log ("no http client?");
1149 function updateCalendarStatus(event) {
1150 var list = new Array();
1152 var nodes = $("calendarList").childNodesWithTag("li");
1153 for (var i = 0; i < nodes.length; i++) {
1154 var input = $(nodes[i]).childNodesWithTag("input")[0];
1155 if (input.checked) {
1156 var folderId = nodes[i].getAttribute("id");
1157 var elems = folderId.split(":");
1158 if (elems.length > 1)
1159 list.push(elems[0]);
1161 list.push(UserLogin);
1166 list.push(UserLogin);
1167 nodes[0].childNodesWithTag("input")[0].checked = true;
1169 // ApplicationBaseURL = (UserFolderURL + "Groups/_custom_"
1170 // + list.join(",") + "/Calendar/");
1173 var folderID = this.parentNode.getAttribute("id");
1174 var urlstr = URLForFolderID(folderID);
1176 urlstr += "/activateFolder";
1178 urlstr += "/deactivateFolder";
1179 //log("updateCalendarStatus: ajax request = " + urlstr + ", folderID = " + folderID);
1180 triggerAjaxRequest(urlstr, calendarStatusCallback, folderID);
1183 updateCalendarsList();
1186 changeCalendarDisplay();
1192 function calendarStatusCallback(http) {
1193 if (http.readyState == 4) {
1194 if (isHttpStatus204(http.status)) {
1197 changeCalendarDisplay();
1200 var folder = $(http.callbackData);
1201 var input = folder.childNodesWithTag("input")[0];
1202 input.checked = (!input.checked);
1206 log("calendarStatusCallback Ajax error");
1209 function calendarEntryCallback(http) {
1210 if (http.readyState == 4) {
1211 var denied = !isHttpStatus204(http.status);
1212 var entry = $(http.callbackData);
1214 entry.addClassName("denied");
1216 entry.removeClassName("denied");
1220 function updateCalendarsList(method) {
1221 var list = $("calendarList").childNodesWithTag("li");
1222 for (var i = 0; i < list.length; i++) {
1223 var folderID = list[i].getAttribute("id");
1224 var url = URLForFolderID(folderID) + "/canAccessContent";
1225 triggerAjaxRequest(url, calendarEntryCallback, folderID);
1229 function addContact(tag, fullContactName, contactId, contactName, contactEmail) {
1230 var uids = $("uixselector-calendarsList-uidList");
1231 // log("addContact");
1234 var re = new RegExp("(^|,)" + contactId + "($|,)");
1236 if (!re.test(uids.value))
1238 if (uids.value.length > 0)
1239 uids.value += ',' + contactId;
1241 uids.value = contactId;
1242 var names = $("calendarList");
1243 var listElems = names.childNodesWithTag("li");
1244 var colorDef = indexColor(listElems.length);
1245 names.appendChild(userCalendarEntry(contactId, colorDef));
1253 function validateBrowseURL(input) {
1254 var button = $("browseURLBtn");
1256 if (input.value.length) {
1257 if (!button.enabled)
1258 enableAnchor(button);
1259 } else if (!button.disabled)
1260 disableAnchor(button);
1263 function browseURL(anchor, event) {
1264 if (event.button == 0) {
1265 var input = $("url");
1266 var url = input.value;
1268 window.open(url, '_blank');
1274 function getMenus() {
1277 var dateMenu = new Array();
1278 for (var i = 0; i < 12; i++)
1279 dateMenu.push(onMonthMenuItemClick);
1280 menus["monthListMenu"] = dateMenu;
1282 dateMenu = new Array();
1283 for (var i = 0; i < 11; i++)
1284 dateMenu.push(onYearMenuItemClick);
1285 menus["yearListMenu"] = dateMenu;
1287 menus["eventsListMenu"] = new Array(onMenuNewEventClick, "-",
1289 editEvent, deleteEvent, "-",
1292 menus["calendarsMenu"] = new Array(null, null, "-", null, null, "-",
1293 null, "-", onMenuSharing);
1294 menus["searchMenu"] = new Array(setSearchCriteria);
1299 function onMenuSharing(event) {
1300 var folders = $("calendarList");
1301 var selected = folders.getSelectedNodes()[0];
1302 /* FIXME: activation of the context menu should preferable select the entry
1303 above which the event has occured */
1305 var folderID = selected.getAttribute("id");
1306 var urlstr = URLForFolderID(folderID) + "/acls";
1308 openAclWindow(urlstr);
1312 function configureDragHandles() {
1313 var handle = $("verticalDragHandle");
1315 handle.addInterface(SOGoDragHandlesInterface);
1316 handle.leftBlock=$("leftPanel");
1317 handle.rightBlock=$("rightPanel");
1320 handle = $("rightDragHandle");
1322 handle.addInterface(SOGoDragHandlesInterface);
1323 handle.upperBlock=$("eventsListView");
1324 handle.lowerBlock=$("calendarView");
1328 function initCalendarSelector() {
1329 var selector = $("calendarSelector");
1330 updateCalendarStatus();
1331 selector.changeNotification = updateCalendarsList;
1333 var list = $("calendarList").childNodesWithTag("li");
1334 for (var i = 0; i < list.length; i++) {
1335 var input = list[i].childNodesWithTag("input")[0];
1336 Event.observe(input, "click", updateCalendarStatus.bindAsEventListener(input)); // not registered in IE?
1337 //Event.observe(list[i], "mousedown", listRowMouseDownHandler, true); // problem with Safari
1338 Event.observe(list[i], "click", onRowClick);
1341 var links = $("calendarSelectorButtons").childNodesWithTag("a");
1342 Event.observe(links[0], "click", onCalendarAdd);
1343 Event.observe(links[1], "click", onCalendarRemove);
1346 function onCalendarAdd(event) {
1347 openUserFolderSelector(onFolderSubscribeCB, "calendar");
1349 preventDefault(event);
1352 function appendCalendar(folderName, folder) {
1353 var calendarList = $("calendarList");
1354 var lis = calendarList.childNodesWithTag("li");
1355 var color = indexColor(lis.length);
1356 //log ("color: " + color);
1358 var li = document.createElement("li");
1359 calendarList.appendChild(li);
1361 var checkBox = document.createElement("input");
1362 checkBox.setAttribute("type", "checkbox");
1363 li.appendChild(checkBox);
1365 li.appendChild(document.createTextNode(" "));
1367 var colorBox = document.createElement("div");
1368 li.appendChild(colorBox);
1369 li.appendChild(document.createTextNode(" " + folderName));
1370 colorBox.appendChild(document.createTextNode("OO"));
1372 li.setAttribute("id", folder);
1373 Event.observe(li, "mousedown", listRowMouseDownHandler);
1374 Event.observe(li, "click", onRowClick);
1375 $(checkBox).addClassName("checkBox");
1377 Event.observe(checkBox, "click", updateCalendarStatus.bindAsEventListener(checkBox));
1379 $(colorBox).addClassName("colorBox");
1381 $(colorBox).setStyle({ color: color,
1382 backgroundColor: color });
1385 var contactId = folder.split(":")[0];
1386 var url = URLForFolderID(folder) + "/canAccessContent";
1387 triggerAjaxRequest(url, calendarEntryCallback, folder);
1389 if (!document.styleSheets) return;
1390 var theRules = new Array();
1391 var lastSheet = document.styleSheets[document.styleSheets.length - 1];
1392 if (lastSheet.insertRule) { // Mozilla
1393 lastSheet.insertRule('.ownerIs' + contactId + ' {'
1394 + ' background-color: '
1396 + ' !important; }', 0);
1399 lastSheet.addRule('.ownerIs' + contactId,
1400 ' background-color: '
1402 + ' !important; }');
1406 function onFolderSubscribeCB(folderData) {
1407 var folder = $(folderData["folder"]);
1409 appendCalendar(folderData["folderName"], folderData["folder"]);
1412 function onFolderUnsubscribeCB(folderId) {
1413 var node = $(folderId);
1414 node.parentNode.removeChild(node);
1417 function onCalendarRemove(event) {
1418 var nodes = $("calendarList").getSelectedNodes();
1419 if (nodes.length > 0) {
1420 nodes[0].deselect();
1421 var folderId = nodes[0].getAttribute("id");
1422 var folderIdElements = folderId.split(":");
1423 if (folderIdElements.length > 1) {
1424 unsubscribeFromFolder(folderId, onFolderUnsubscribeCB, folderId);
1428 preventDefault(event);
1431 function configureLists() {
1432 var list = $("tasksList");
1433 list.multiselect = true;
1434 Event.observe(list, "mousedown",
1435 onTasksSelectionChange.bindAsEventListener(list));
1437 var input = $("showHideCompletedTasks");
1438 Event.observe(input, "click",
1439 onShowCompletedTasks.bindAsEventListener(input));
1441 list = $("eventsList");
1442 list.multiselect = true;
1443 Event.observe(list, "mousedown",
1444 onEventsSelectionChange.bindAsEventListener(list));
1445 var div = list.parentNode;
1446 Event.observe(div, "contextmenu",
1447 onEventContextMenu.bindAsEventListener(div));
1450 function initDateSelectorEvents() {
1451 var arrow = $("rightArrow");
1452 Event.observe(arrow, "click",
1453 onDateSelectorGotoMonth.bindAsEventListener(arrow));
1454 arrow = $("leftArrow");
1455 Event.observe(arrow, "click",
1456 onDateSelectorGotoMonth.bindAsEventListener(arrow));
1458 var menuButton = $("monthLabel");
1459 Event.observe(menuButton, "click",
1460 popupMonthMenu.bindAsEventListener(menuButton));
1461 menuButton = $("yearLabel");
1462 Event.observe(menuButton, "click",
1463 popupMonthMenu.bindAsEventListener(menuButton));
1466 function initCalendars() {
1467 if (!document.body.hasClassName("popup")) {
1468 initDateSelectorEvents();
1469 initCalendarSelector();
1470 configureSearchField();
1472 var selector = $("calendarSelector");
1474 selector.attachMenu("calendarsMenu");
1478 addEvent(window, 'load', initCalendars);