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 if (queryParameters["mail-invitation"].toLowerCase() == "yes")
180 closeInvitationWindow();
182 window.opener.setTimeout("refreshEventsAndDisplay();", 100);
183 window.setTimeout("window.close();", 100);
187 // log("showing alert...");
188 window.alert(labels["eventPartStatModificationError"]);
190 document.modifyEventAjaxRequest = null;
194 function deleteEventCallback(http) {
195 if (http.readyState == 4
196 && http.status == 200) {
197 var nodes = http.callbackData;
198 for (var i = 0; i < nodes.length; i++) {
199 var node = $(nodes[i]);
201 node.parentNode.removeChild(node);
203 if (eventsToDelete.length)
204 _batchDeleteEvents();
206 document.deleteEventAjaxRequest = null;
209 changeCalendarDisplay();
213 log ("deleteEventCallback Ajax error");
216 function editDoubleClickedEvent(event) {
217 _editEventId(this.cname, this.owner);
219 preventDefault(event);
220 event.cancelBubble = true;
223 function onSelectAll() {
224 var list = $("eventsList");
225 list.selectRowsMatchingClass("eventRow");
230 function onDaySelect(node) {
231 var day = node.getAttribute('day');
232 var needRefresh = (listFilter == 'view_selectedday'
233 && day != currentDay);
235 var td = $(node).getParentWithTagName("td");
236 var table = $(td).getParentWithTagName("table");
238 // log ("table.selected: " + table.selected);
240 if (document.selectedDate)
241 document.selectedDate.deselect();
244 document.selectedDate = td;
246 changeCalendarDisplay( { "day": day } );
253 function onDateSelectorGotoMonth(event) {
254 var day = this.getAttribute("date");
256 changeDateSelectorDisplay(day, true);
261 function onCalendarGotoDay(node) {
262 var day = node.getAttribute("date");
264 changeDateSelectorDisplay(day);
265 changeCalendarDisplay( { "day": day } );
270 function gotoToday() {
271 changeDateSelectorDisplay('');
272 changeCalendarDisplay();
277 function setDateSelectorContent(content) {
278 var div = $("dateSelectorView");
280 div.innerHTML = content;
281 if (currentDay.length > 0)
282 restoreCurrentDaySelection(div);
284 initDateSelectorEvents();
287 function dateSelectorCallback(http) {
288 if (http.readyState == 4
289 && http.status == 200) {
290 document.dateSelectorAjaxRequest = null;
291 var content = http.responseText;
292 setDateSelectorContent(content);
293 cachedDateSelectors[http.callbackData] = content;
296 log ("dateSelectorCallback Ajax error");
299 function eventsListCallback(http) {
300 if (http.readyState == 4
301 && http.status == 200) {
302 var div = $("eventsListView");
304 document.eventsListAjaxRequest = null;
305 var table = $("eventsList").tBodies[0];
306 var params = parseQueryParameters(http.callbackData);
307 sortKey = params["sort"];
308 sortOrder = params["desc"];
309 configureSortableTableHeaders();
311 var data = http.responseText.evalJSON(true);
312 for (var i = 0; i < data.length; i++) {
313 var row = document.createElement("tr");
314 table.appendChild(row);
315 $(row).addClassName("eventRow");
316 row.setAttribute("id", data[i][0]);
317 row.cname = data[i][0];
318 row.owner = data[i][1];
320 var startDate = new Date();
321 startDate.setTime(data[i][4] * 1000);
322 row.day = startDate.getDayString();
323 row.hour = startDate.getHourString();
324 Event.observe(row, "click",
325 onEventClick.bindAsEventListener(row));
326 Event.observe(row, "dblclick",
327 editDoubleClickedEvent.bindAsEventListener(row));
328 Event.observe(row, "contextmenu",
329 onEventContextMenu.bindAsEventListener(row));
331 var td = document.createElement("td");
333 Event.observe(td, "mousedown", listRowMouseDownHandler, true);
334 td.appendChild(document.createTextNode(data[i][3]));
336 td = document.createElement("td");
338 Event.observe(td, "mousedown", listRowMouseDownHandler, true);
339 td.appendChild(document.createTextNode(data[i][8]));
341 td = document.createElement("td");
343 Event.observe(td, "mousedown", listRowMouseDownHandler, true);
344 td.appendChild(document.createTextNode(data[i][9]));
346 td = document.createElement("td");
348 Event.observe(td, "mousedown", listRowMouseDownHandler, true);
349 td.appendChild(document.createTextNode(data[i][6]));
353 log ("eventsListCallback Ajax error");
356 function tasksListCallback(http) {
357 var div = $("tasksListView");
359 if (http.readyState == 4
360 && http.status == 200) {
361 document.tasksListAjaxRequest = null;
362 var list = $("tasksList");
363 var data = http.responseText.evalJSON(true);
365 for (var i = 0; i < data.length; i++) {
366 //log(i + " = " + data[i][3]);
367 var listItem = document.createElement("li");
368 list.appendChild(listItem);
369 Event.observe(listItem, "mousedown", listRowMouseDownHandler); // causes problem with Safari
370 Event.observe(listItem, "click", onRowClick);
371 Event.observe(listItem, "dblclick", editDoubleClickedEvent.bindAsEventListener(listItem));
372 listItem.setAttribute("id", data[i][0]);
373 $(listItem).addClassName(data[i][5]);
374 var owner = data[i][1];
375 listItem.owner = owner;
376 $(listItem).addClassName("ownerIs" + owner);
377 listItem.cname = data[i][0];
378 var input = document.createElement("input");
379 input.setAttribute("type", "checkbox");
380 listItem.appendChild(input);
381 Event.observe(input, "click", updateTaskStatus.bindAsEventListener(input), true);
382 input.setAttribute("value", "1");
384 input.setAttribute("checked", "checked");
385 $(input).addClassName("checkBox");
386 listItem.appendChild(document.createTextNode(data[i][3]));
389 list.scrollTop = list.previousScroll;
391 if (http.callbackData) {
392 var selectedNodesId = http.callbackData;
393 for (var i = 0; i < selectedNodesId.length; i++) {
394 // log(selectedNodesId[i] + " (" + i + ") is selected");
395 $(selectedNodesId[i]).select();
399 log ("tasksListCallback: no data");
402 log ("tasksListCallback Ajax error");
405 function restoreCurrentDaySelection(div) {
406 var elements = $(div).getElementsByTagName("a");
409 while (!day && i < elements.length)
411 day = elements[i].day;
416 && day.substr(0, 6) == currentDay.substr(0, 6)) {
417 for (i = 0; i < elements.length; i++) {
418 day = elements[i].day;
419 if (day && day == currentDay) {
420 var td = $(elements[i]).getParentWithTagName("td");
421 if (document.selectedDate)
422 document.selectedDate.deselect();
424 document.selectedDate = td;
430 function changeDateSelectorDisplay(day, keepCurrentDay) {
431 var url = ApplicationBaseURL + "dateselector";
433 url += "?day=" + day;
435 if (day != currentDay) {
439 var month = day.substr(0, 6);
440 if (cachedDateSelectors[month]) {
441 // log ("restoring cached selector for month: " + month);
442 setDateSelectorContent(cachedDateSelectors[month]);
445 // log ("loading selector for month: " + month);
446 if (document.dateSelectorAjaxRequest) {
447 document.dateSelectorAjaxRequest.aborted = true;
448 document.dateSelectorAjaxRequest.abort();
450 document.dateSelectorAjaxRequest
451 = triggerAjaxRequest(url,
452 dateSelectorCallback,
458 function changeCalendarDisplay(time, newView) {
459 var url = ApplicationBaseURL + ((newView) ? newView : currentView);
461 selectedCalendarCell = null;
473 url += "?day=" + day;
476 // log ("switching to view: " + newView);
477 // log ("changeCalendarDisplay: " + url);
479 if (document.dayDisplayAjaxRequest) {
480 // log ("aborting day ajaxrq");
481 document.dayDisplayAjaxRequest.aborted = true;
482 document.dayDisplayAjaxRequest.abort();
484 document.dayDisplayAjaxRequest
485 = triggerAjaxRequest(url, calendarDisplayCallback,
486 { "view": newView, "day": day, "hour": hour });
491 function _ensureView(view) {
492 if (currentView != view)
493 changeCalendarDisplay(null, view);
498 function onDayOverview() {
499 return _ensureView("dayview");
502 function onMulticolumnDayOverview() {
503 return _ensureView("multicolumndayview");
506 function onWeekOverview() {
507 return _ensureView("weekview");
510 function onMonthOverview() {
511 return _ensureView("monthview");
514 function scrollDayView(hour) {
517 if (hour.length == 3)
518 rowNumber = parseInt(hour.substr(0, 1));
520 if (hour.substr(0, 1) == "0")
521 rowNumber = parseInt(hour.substr(1, 1));
523 rowNumber = parseInt(hour.substr(0, 2));
528 var daysView = $("daysView");
530 $(daysView.childNodesWithTag("div")[0]).childNodesWithTag("div");
531 if (hours.length > 0)
532 daysView.scrollTop = hours[rowNumber].offsetTop;
535 function onClickableCellsDblClick(event) {
536 newEvent(this, 'event');
538 event.cancelBubble = true;
539 event.returnValue = false;
542 function refreshCalendarEvents() {
543 var todayDate = new Date();
546 if (currentView == "dayview") {
550 sd = todayDate.getDayString();
553 else if (currentView == "weekview") {
556 startDate = currentDay.asDate();
558 startDate = todayDate;
559 startDate = startDate.beginOfWeek();
560 sd = startDate.getDayString();
561 var endDate = new Date();
562 endDate.setTime(startDate.getTime());
564 ed = endDate.getDayString();
569 monthDate = currentDay.asDate();
571 monthDate = todayDate;
572 monthDate.setDate(1);
573 sd = monthDate.beginOfWeek().getDayString();
575 var lastMonthDate = new Date();
576 lastMonthDate.setTime(monthDate.getTime());
577 lastMonthDate.setMonth(monthDate.getMonth() + 1);
578 lastMonthDate.addDays(-1);
579 ed = lastMonthDate.endOfWeek().getDayString();
581 if (document.refreshCalendarEventsAjaxRequest) {
582 document.refreshCalendarEventsAjaxRequest.aborted = true;
583 document.refreshCalendarEventsAjaxRequest.abort();
585 var url = ApplicationBaseURL + "eventslist?sd=" + sd + "&ed=" + ed;
586 document.refreshCalendarEventsAjaxRequest
587 = triggerAjaxRequest(url, refreshCalendarEventsCallback,
588 {"startDate": sd, "endDate": ed});
591 function refreshCalendarEventsCallback(http) {
592 if (http.readyState == 4
593 && http.status == 200) {
594 var data = http.responseText.evalJSON(true);
595 // log("refresh calendar events: " + data.length);
596 for (var i = 0; i < data.length; i++)
597 drawCalendarEvent(data[i],
598 http.callbackData["startDate"],
599 http.callbackData["endDate"]);
602 log("AJAX error when refreshing calendar events");
605 function drawCalendarEvent(eventData, sd, ed) {
606 var viewStartDate = sd.asDate();
607 var viewEndDate = ed.asDate();
609 var startDate = new Date();
610 startDate.setTime(eventData[4] * 1000);
611 var endDate = new Date();
612 endDate.setTime(eventData[5] * 1000);
614 var days = startDate.daysUpTo(endDate);
616 var divs = new Array();
619 if (currentView == "monthview"
620 && (eventData[7] == 0))
621 title = startDate.getDisplayHoursString() + " " + eventData[3];
623 title = eventData[3];
625 // log("title: " + title);
626 // log("viewS: " + viewStartDate);
627 var startHour = null;
630 var siblings = new Array();
631 for (var i = 0; i < days.length; i++)
632 if (days[i].earlierDate(viewStartDate) == viewStartDate
633 && days[i].laterDate(viewEndDate) == viewEndDate) {
636 // log("day: " + days[i]);
638 var quarters = (startDate.getHours() * 4
639 + Math.floor(startDate.getMinutes() / 15));
641 startHour = startDate.getDisplayHoursString();
642 endHour = endDate.getDisplayHoursString();
649 if (i == days.length - 1) {
650 var quarters = (endDate.getHours() * 4
651 + Math.ceil(endDate.getMinutes() / 15));
656 lasts = ends - starts;
660 var eventDiv = newEventDIV(eventData[0], eventData[1], starts, lasts,
662 siblings.push(eventDiv);
663 eventDiv.siblings = siblings;
664 var dayString = days[i].getDayString();
665 // log("day: " + dayString);
666 var parentDiv = null;
667 if (currentView == "monthview") {
668 var dayDivs = $("monthDaysView").childNodesWithTag("div");
670 while (!parentDiv && j < dayDivs.length) {
671 if (dayDivs[j].getAttribute("day") == dayString)
672 parentDiv = dayDivs[j];
678 if (eventData[7] == 0) {
679 var daysView = $("daysView");
680 var eventsDiv = $(daysView).childNodesWithTag("div")[1];
681 var dayDivs = $(eventsDiv).childNodesWithTag("div");
683 while (!parentDiv && j < dayDivs.length) {
684 if (dayDivs[j].getAttribute("day") == dayString)
685 parentDiv = dayDivs[j].childNodesWithTag("div")[0];
691 var header = $("calendarHeader");
692 var daysDiv = $(header).childNodesWithTag("div")[1];
693 var dayDivs = $(daysDiv).childNodesWithTag("div");
695 while (!parentDiv && j < dayDivs.length) {
696 if (dayDivs[j].getAttribute("day") == dayString)
697 parentDiv = dayDivs[j];
704 parentDiv.appendChild(eventDiv);
708 function newEventDIV(cname, owner, starts, lasts,
709 startHour, endHour, title) {
710 var eventDiv = document.createElement("div");
711 eventDiv.cname = cname;
712 eventDiv.owner = owner;
713 $(eventDiv).addClassName("event");
714 $(eventDiv).addClassName("starts" + starts);
715 $(eventDiv).addClassName("lasts" + lasts);
716 for (var i = 1; i < 5; i++) {
717 var shadowDiv = document.createElement("div");
718 eventDiv.appendChild(shadowDiv);
719 $(shadowDiv).addClassName("shadow");
720 $(shadowDiv).addClassName("shadow" + i);
722 var innerDiv = document.createElement("div");
723 eventDiv.appendChild(innerDiv);
724 $(innerDiv).addClassName("eventInside");
725 $(innerDiv).addClassName("ownerIs" + owner);
727 var gradientDiv = document.createElement("div");
728 innerDiv.appendChild(gradientDiv);
729 $(gradientDiv).addClassName("gradient");
730 var gradientImg = document.createElement("img");
731 gradientDiv.appendChild(gradientImg);
732 gradientImg.src = ResourcesURL + "/event-gradient.png";
734 var textDiv = document.createElement("div");
735 innerDiv.appendChild(textDiv);
736 $(textDiv).addClassName("text");
738 var headerSpan = document.createElement("span");
739 textDiv.appendChild(headerSpan);
740 $(headerSpan).addClassName("eventHeader");
741 headerSpan.appendChild(document.createTextNode(startHour + " - "
743 textDiv.appendChild(document.createElement("br"));
745 textDiv.appendChild(document.createTextNode(title));
747 Event.observe(eventDiv, "mousedown", listRowMouseDownHandler);
748 Event.observe(eventDiv, "click",
749 onCalendarSelectEvent.bindAsEventListener(eventDiv));
750 Event.observe(eventDiv, "dblclick",
751 editDoubleClickedEvent.bindAsEventListener(eventDiv));
756 function calendarDisplayCallback(http) {
757 var div = $("calendarView");
759 if (http.readyState == 4
760 && http.status == 200) {
761 document.dayDisplayAjaxRequest = null;
762 div.innerHTML = http.responseText;
763 if (http.callbackData["view"])
764 currentView = http.callbackData["view"];
765 if (http.callbackData["day"])
766 currentDay = http.callbackData["day"];
769 if (http.callbackData["hour"])
770 hour = http.callbackData["hour"];
772 if (currentView == "monthview")
773 contentView = $("calendarContent");
776 contentView = $("daysView");
778 refreshCalendarEvents();
779 var days = document.getElementsByClassName("day", contentView);
780 if (currentView == "monthview")
781 for (var i = 0; i < days.length; i++) {
782 Event.observe(days[i], "click", onCalendarSelectDay.bindAsEventListener(days[i]));
783 Event.observe(days[i], "dblclick", onClickableCellsDblClick.bindAsEventListener(days[i]));
786 var headerDivs = $("calendarHeader").childNodesWithTag("div");
787 var headerDaysLabels = document.getElementsByClassName("day", headerDivs[0]);
788 var headerDays = document.getElementsByClassName("day", headerDivs[1]);
789 for (var i = 0; i < days.length; i++) {
790 headerDays[i].hour = "allday";
791 Event.observe(headerDaysLabels[i], "mousedown", listRowMouseDownHandler);
792 Event.observe(headerDays[i], "click",
793 onCalendarSelectDay.bindAsEventListener(days[i]));
794 Event.observe(headerDays[i], "dblclick",
795 onClickableCellsDblClick.bindAsEventListener(headerDays[i]));
796 Event.observe(days[i], "click",
797 onCalendarSelectDay.bindAsEventListener(days[i]));
798 var clickableCells = document.getElementsByClassName("clickableHourCell",
800 for (var j = 0; j < clickableCells.length; j++)
801 Event.observe(clickableCells[j], "dblclick",
802 onClickableCellsDblClick.bindAsEventListener(clickableCells[j]));
807 log ("calendarDisplayCallback Ajax error (" + http.readyState + "/" + http.status + ")");
810 function assignCalendar(name) {
811 if (typeof(skycalendar) != "undefined") {
814 node.calendar = new skycalendar(node);
815 node.calendar.setCalendarPage(ResourcesURL + "/skycalendar.html");
816 var dateFormat = node.getAttribute("dateFormat");
818 node.calendar.setDateFormat(dateFormat);
822 function popupCalendar(node) {
823 var nodeId = node.getAttribute("inputId");
824 var input = $(nodeId);
825 input.calendar.popup();
830 function onEventContextMenu(event) {
831 var topNode = $("eventsList");
834 var menu = $("eventsListMenu");
836 Event.observe(menu, "hideMenu", onEventContextMenuHide);
837 popupMenu(event, "eventsListMenu", this);
839 var topNode = $("eventsList");
840 var selectedNodes = topNode.getSelectedRows();
841 topNode.menuSelectedRows = selectedNodes;
842 for (var i = 0; i < selectedNodes.length; i++)
843 selectedNodes[i].deselect();
845 topNode.menuSelectedEntry = this;
849 function onEventContextMenuHide(event) {
850 var topNode = $("eventsList");
852 if (topNode.menuSelectedEntry) {
853 topNode.menuSelectedEntry.deselect();
854 topNode.menuSelectedEntry = null;
856 if (topNode.menuSelectedRows) {
857 var nodeIds = topNode.menuSelectedRows;
858 for (var i = 0; i < nodeIds.length; i++) {
859 var node = $(nodeIds[i]);
862 topNode.menuSelectedRows = null;
866 function onEventsSelectionChange() {
867 listOfSelection = this;
868 this.removeClassName("_unfocused");
869 $("tasksList").addClassName("_unfocused");
872 function onTasksSelectionChange() {
873 listOfSelection = this;
874 this.removeClassName("_unfocused");
875 $("eventsList").addClassName("_unfocused");
878 function _loadEventHref(href) {
879 if (document.eventsListAjaxRequest) {
880 document.eventsListAjaxRequest.aborted = true;
881 document.eventsListAjaxRequest.abort();
883 var url = ApplicationBaseURL + href;
884 document.eventsListAjaxRequest
885 = triggerAjaxRequest(url, eventsListCallback, href);
887 var table = $("eventsList").tBodies[0];
888 while (table.rows.length > 1)
889 table.removeChild(table.rows[1]);
894 function _loadTasksHref(href) {
895 if (document.tasksListAjaxRequest) {
896 document.tasksListAjaxRequest.aborted = true;
897 document.tasksListAjaxRequest.abort();
899 url = ApplicationBaseURL + href;
901 var tasksList = $("tasksList");
904 selectedIds = tasksList.getSelectedNodesId();
907 document.tasksListAjaxRequest
908 = triggerAjaxRequest(url, tasksListCallback, selectedIds);
910 tasksList.previousScroll = tasksList.scrollTop;
911 while (tasksList.childNodes.length)
912 tasksList.removeChild(tasksList.childNodes[0]);
917 function onHeaderClick(event) {
918 // log("onHeaderClick: " + this.link);
919 _loadEventHref(this.link);
921 preventDefault(event);
924 function refreshEvents() {
925 return _loadEventHref("eventslist?desc=" + sortOrder
927 + "&day=" + currentDay
928 + "&filterpopup=" + listFilter);
931 function refreshTasks() {
932 return _loadTasksHref("taskslist?show-completed=" + showCompletedTasks);
935 function refreshEventsAndDisplay() {
937 changeCalendarDisplay();
940 function onListFilterChange() {
941 var node = $("filterpopup");
943 listFilter = node.value;
944 // log ("listFilter = " + listFilter);
946 return refreshEvents();
949 function onEventClick(event) {
951 var hour = this.hour;
953 changeCalendarDisplay( { "day": day, "hour": hour} );
954 changeDateSelectorDisplay(day);
956 return onRowClick(event);
959 function selectMonthInMenu(menu, month) {
960 var entries = menu.childNodes[1].childNodesWithTag("LI");
961 for (i = 0; i < entries.length; i++) {
962 var entry = entries[i];
963 var entryMonth = entry.getAttribute("month");
964 if (entryMonth == month)
965 entry.addClassName("currentMonth");
967 entry.removeClassName("currentMonth");
971 function selectYearInMenu(menu, month) {
972 var entries = menu.childNodes[1].childNodes;
973 for (i = 0; i < entries.length; i++) {
974 var entry = entries[i];
975 if (entry instanceof HTMLLIElement) {
976 var entryMonth = entry.innerHTML;
977 if (entryMonth == month)
978 entry.addClassName("currentMonth");
980 entry.removeClassName("currentMonth");
985 function popupMonthMenu(event) {
986 if (event.button == 0) {
987 var id = this.getAttribute("id");
988 if (id == "monthLabel")
989 menuId = "monthListMenu";
991 menuId = "yearListMenu";
993 var popup = $(menuId);
994 if (id == "monthLabel")
995 selectMonthInMenu(popup, this.getAttribute("month"));
997 selectYearInMenu(popup, this.innerHTML);
999 popupToolbarMenu(this, menuId);
1004 function onMonthMenuItemClick(event) {
1005 var month = '' + this.getAttribute("month");
1006 var year = '' + $("yearLabel").innerHTML;
1008 changeDateSelectorDisplay(year + month + "01", true);
1011 function onYearMenuItemClick(event) {
1012 var month = '' + $("monthLabel").getAttribute("month");;
1013 var year = '' + this.innerHTML;
1015 changeDateSelectorDisplay(year + month + "01", true);
1018 function onSearchFormSubmit() {
1019 log ("search not implemented");
1024 function onCalendarSelectEvent() {
1025 var list = $("eventsList");
1028 if (selectedCalendarCell)
1029 for (var i = 0; i < selectedCalendarCell.length; i++)
1030 selectedCalendarCell[i].deselect();
1032 for (var i = 0; i < this.siblings.length; i++)
1033 this.siblings[i].select();
1034 selectedCalendarCell = this.siblings;
1035 var row = $(this.cname);
1037 var div = row.parentNode.parentNode.parentNode;
1038 div.scrollTop = row.offsetTop - (div.offsetHeight / 2);
1043 function onCalendarSelectDay(event) {
1045 if (currentView == "multicolumndayview")
1046 day = this.getAttribute("day");
1048 day = this.getAttribute("day");
1049 var needRefresh = (listFilter == 'view_selectedday'
1050 && day != currentDay);
1052 if (currentView == 'weekview')
1053 changeWeekCalendarDisplayOfSelectedDay(this);
1054 else if (currentView == 'monthview')
1055 changeMonthCalendarDisplayOfSelectedDay(this);
1056 changeDateSelectorDisplay(day);
1058 if (listOfSelection) {
1059 listOfSelection.addClassName("_unfocused");
1060 listOfSelection = null;
1067 function changeWeekCalendarDisplayOfSelectedDay(node) {
1068 var days = document.getElementsByClassName("day", node.parentNode);
1069 var headerDiv = $("calendarHeader").childNodesWithTag("div")[1];
1070 var headerDays = document.getElementsByClassName("day", headerDiv);
1072 // log ("days: " + days.length + "; headerDays: " + headerDays.length);
1073 for (var i = 0; i < days.length; i++)
1074 if (days[i] != node) {
1075 // log("unselect day : " + i);
1076 headerDays[i].removeClassName("selectedDay");
1077 days[i].removeClassName("selectedDay");
1080 // log("selected day : " + i);
1081 headerDays[i].addClassName("selectedDay");
1082 days[i].addClassName("selectedDay");
1086 function findMonthCalendarSelectedCell(daysContainer) {
1090 while (!found && i < daysContainer.childNodes.length) {
1091 var currentNode = daysContainer.childNodes[i];
1092 if (currentNode.tagName == 'DIV'
1093 && currentNode.hasClassName("selectedDay")) {
1094 daysContainer.selectedCell = currentNode;
1102 function changeMonthCalendarDisplayOfSelectedDay(node) {
1103 var daysContainer = node.parentNode;
1104 if (!daysContainer.selectedCell)
1105 findMonthCalendarSelectedCell(daysContainer);
1107 if (daysContainer.selectedCell)
1108 daysContainer.selectedCell.removeClassName("selectedDay");
1109 daysContainer.selectedCell = node;
1110 node.addClassName("selectedDay");
1113 function onShowCompletedTasks(event) {
1114 showCompletedTasks = (this.checked ? 1 : 0);
1116 return refreshTasks();
1119 function updateTaskStatus(event) {
1120 var taskId = this.parentNode.getAttribute("id");
1121 var taskOwner = this.parentNode.owner;
1122 var newStatus = (this.checked ? 1 : 0);
1123 var http = createHTTPClient();
1126 newStatus = (newStatus ? 0 : 1);
1127 //log("update task status: " + taskId + " to " + this.checked);
1128 event.cancelBubble = true;
1130 url = (UserFolderURL + "../" + taskOwner
1131 + "/Calendar/" + taskId
1132 + "/changeStatus?status=" + newStatus);
1135 // log ("url: " + url);
1136 // TODO: add parameter to signal that we are only interested in OK
1137 http.open("POST", url, false /* not async */);
1140 if (http.status == 200)
1143 log ("no http client?");
1148 function updateCalendarStatus(event) {
1149 var list = new Array();
1151 var nodes = $("calendarList").childNodesWithTag("li");
1152 for (var i = 0; i < nodes.length; i++) {
1153 var input = $(nodes[i]).childNodesWithTag("input")[0];
1154 if (input.checked) {
1155 var folderId = nodes[i].getAttribute("id");
1156 var elems = folderId.split(":");
1157 if (elems.length > 1)
1158 list.push(elems[0]);
1160 list.push(UserLogin);
1165 list.push(UserLogin);
1166 nodes[0].childNodesWithTag("input")[0].checked = true;
1168 // ApplicationBaseURL = (UserFolderURL + "Groups/_custom_"
1169 // + list.join(",") + "/Calendar/");
1172 var folderID = this.parentNode.getAttribute("id");
1173 var urlstr = URLForFolderID(folderID);
1175 urlstr += "/activateFolder";
1177 urlstr += "/deactivateFolder";
1178 //log("updateCalendarStatus: ajax request = " + urlstr + ", folderID = " + folderID);
1179 triggerAjaxRequest(urlstr, calendarStatusCallback, folderID);
1182 updateCalendarsList();
1185 changeCalendarDisplay();
1191 function calendarStatusCallback(http) {
1192 if (http.readyState == 4) {
1193 if (isHttpStatus204(http.status)) {
1196 changeCalendarDisplay();
1199 var folder = $(http.callbackData);
1200 var input = folder.childNodesWithTag("input")[0];
1201 input.checked = (!input.checked);
1205 log("calendarStatusCallback Ajax error");
1208 function calendarEntryCallback(http) {
1209 if (http.readyState == 4) {
1210 var denied = !isHttpStatus204(http.status);
1211 var entry = $(http.callbackData);
1213 entry.addClassName("denied");
1215 entry.removeClassName("denied");
1219 function updateCalendarsList(method) {
1220 var list = $("calendarList").childNodesWithTag("li");
1221 for (var i = 0; i < list.length; i++) {
1222 var folderID = list[i].getAttribute("id");
1223 var url = URLForFolderID(folderID) + "/canAccessContent";
1224 triggerAjaxRequest(url, calendarEntryCallback, folderID);
1228 function addContact(tag, fullContactName, contactId, contactName, contactEmail) {
1229 var uids = $("uixselector-calendarsList-uidList");
1230 // log("addContact");
1233 var re = new RegExp("(^|,)" + contactId + "($|,)");
1235 if (!re.test(uids.value))
1237 if (uids.value.length > 0)
1238 uids.value += ',' + contactId;
1240 uids.value = contactId;
1241 var names = $("calendarList");
1242 var listElems = names.childNodesWithTag("li");
1243 var colorDef = indexColor(listElems.length);
1244 names.appendChild(userCalendarEntry(contactId, colorDef));
1252 function validateBrowseURL(input) {
1253 var button = $("browseURLBtn");
1255 if (input.value.length) {
1256 if (!button.enabled)
1257 enableAnchor(button);
1258 } else if (!button.disabled)
1259 disableAnchor(button);
1262 function browseURL(anchor, event) {
1263 if (event.button == 0) {
1264 var input = $("url");
1265 var url = input.value;
1267 window.open(url, '_blank');
1273 function getMenus() {
1276 var dateMenu = new Array();
1277 for (var i = 0; i < 12; i++)
1278 dateMenu.push(onMonthMenuItemClick);
1279 menus["monthListMenu"] = dateMenu;
1281 dateMenu = new Array();
1282 for (var i = 0; i < 11; i++)
1283 dateMenu.push(onYearMenuItemClick);
1284 menus["yearListMenu"] = dateMenu;
1286 menus["eventsListMenu"] = new Array(onMenuNewEventClick, "-",
1288 editEvent, deleteEvent, "-",
1291 menus["calendarsMenu"] = new Array(null, null, "-", null, null, "-",
1292 null, "-", onMenuSharing);
1293 menus["searchMenu"] = new Array(setSearchCriteria);
1298 function onMenuSharing(event) {
1299 var folders = $("calendarList");
1300 var selected = folders.getSelectedNodes()[0];
1301 /* FIXME: activation of the context menu should preferable select the entry
1302 above which the event has occured */
1304 var folderID = selected.getAttribute("id");
1305 var urlstr = URLForFolderID(folderID) + "/acls";
1307 openAclWindow(urlstr);
1311 function configureDragHandles() {
1312 var handle = $("verticalDragHandle");
1314 handle.addInterface(SOGoDragHandlesInterface);
1315 handle.leftBlock=$("leftPanel");
1316 handle.rightBlock=$("rightPanel");
1319 handle = $("rightDragHandle");
1321 handle.addInterface(SOGoDragHandlesInterface);
1322 handle.upperBlock=$("eventsListView");
1323 handle.lowerBlock=$("calendarView");
1327 function initCalendarSelector() {
1328 var selector = $("calendarSelector");
1329 updateCalendarStatus();
1330 selector.changeNotification = updateCalendarsList;
1332 var list = $("calendarList").childNodesWithTag("li");
1333 for (var i = 0; i < list.length; i++) {
1334 var input = list[i].childNodesWithTag("input")[0];
1335 Event.observe(input, "click", updateCalendarStatus.bindAsEventListener(input)); // not registered in IE?
1336 //Event.observe(list[i], "mousedown", listRowMouseDownHandler, true); // problem with Safari
1337 Event.observe(list[i], "click", onRowClick);
1340 var links = $("calendarSelectorButtons").childNodesWithTag("a");
1341 Event.observe(links[0], "click", onCalendarAdd);
1342 Event.observe(links[1], "click", onCalendarRemove);
1345 function onCalendarAdd(event) {
1346 openUserFolderSelector(onFolderSubscribeCB, "calendar");
1348 preventDefault(event);
1351 function appendCalendar(folderName, folder) {
1352 var calendarList = $("calendarList");
1353 var lis = calendarList.childNodesWithTag("li");
1354 var color = indexColor(lis.length);
1355 //log ("color: " + color);
1357 var li = document.createElement("li");
1358 calendarList.appendChild(li);
1360 var checkBox = document.createElement("input");
1361 checkBox.setAttribute("type", "checkbox");
1362 li.appendChild(checkBox);
1364 li.appendChild(document.createTextNode(" "));
1366 var colorBox = document.createElement("div");
1367 li.appendChild(colorBox);
1368 li.appendChild(document.createTextNode(" " + folderName));
1369 colorBox.appendChild(document.createTextNode("OO"));
1371 li.setAttribute("id", folder);
1372 Event.observe(li, "mousedown", listRowMouseDownHandler);
1373 Event.observe(li, "click", onRowClick);
1374 $(checkBox).addClassName("checkBox");
1376 Event.observe(checkBox, "click", updateCalendarStatus.bindAsEventListener(checkBox));
1378 $(colorBox).addClassName("colorBox");
1380 $(colorBox).setStyle({ color: color,
1381 backgroundColor: color });
1384 var contactId = folder.split(":")[0];
1385 var url = URLForFolderID(folder) + "/canAccessContent";
1386 triggerAjaxRequest(url, calendarEntryCallback, folder);
1388 if (!document.styleSheets) return;
1389 var theRules = new Array();
1390 var lastSheet = document.styleSheets[document.styleSheets.length - 1];
1391 if (lastSheet.insertRule) { // Mozilla
1392 lastSheet.insertRule('.ownerIs' + contactId + ' {'
1393 + ' background-color: '
1395 + ' !important; }', 0);
1398 lastSheet.addRule('.ownerIs' + contactId,
1399 ' background-color: '
1401 + ' !important; }');
1405 function onFolderSubscribeCB(folderData) {
1406 var folder = $(folderData["folder"]);
1408 appendCalendar(folderData["folderName"], folderData["folder"]);
1411 function onFolderUnsubscribeCB(folderId) {
1412 var node = $(folderId);
1413 node.parentNode.removeChild(node);
1416 function onCalendarRemove(event) {
1417 var nodes = $("calendarList").getSelectedNodes();
1418 if (nodes.length > 0) {
1419 nodes[0].deselect();
1420 var folderId = nodes[0].getAttribute("id");
1421 var folderIdElements = folderId.split(":");
1422 if (folderIdElements.length > 1) {
1423 unsubscribeFromFolder(folderId, onFolderUnsubscribeCB, folderId);
1427 preventDefault(event);
1430 function configureSearchField() {
1431 var searchValue = $("searchValue");
1433 Event.observe(searchValue, "mousedown",
1434 onSearchMouseDown.bindAsEventListener(searchValue));
1435 Event.observe(searchValue, "click",
1436 popupSearchMenu.bindAsEventListener(searchValue));
1437 Event.observe(searchValue, "blur",
1438 onSearchBlur.bindAsEventListener(searchValue));
1439 Event.observe(searchValue, "focus",
1440 onSearchFocus.bindAsEventListener(searchValue));
1441 Event.observe(searchValue, "keydown",
1442 onSearchKeyDown.bindAsEventListener(searchValue));
1445 function configureLists() {
1446 var list = $("tasksList");
1447 list.multiselect = true;
1448 Event.observe(list, "mousedown",
1449 onTasksSelectionChange.bindAsEventListener(list));
1451 var input = $("showHideCompletedTasks");
1452 Event.observe(input, "click",
1453 onShowCompletedTasks.bindAsEventListener(input));
1455 list = $("eventsList");
1456 list.multiselect = true;
1457 Event.observe(list, "mousedown",
1458 onEventsSelectionChange.bindAsEventListener(list));
1459 var div = list.parentNode;
1460 Event.observe(div, "contextmenu",
1461 onEventContextMenu.bindAsEventListener(div));
1464 function initDateSelectorEvents() {
1465 var arrow = $("rightArrow");
1466 Event.observe(arrow, "click",
1467 onDateSelectorGotoMonth.bindAsEventListener(arrow));
1468 arrow = $("leftArrow");
1469 Event.observe(arrow, "click",
1470 onDateSelectorGotoMonth.bindAsEventListener(arrow));
1472 var menuButton = $("monthLabel");
1473 Event.observe(menuButton, "click",
1474 popupMonthMenu.bindAsEventListener(menuButton));
1475 menuButton = $("yearLabel");
1476 Event.observe(menuButton, "click",
1477 popupMonthMenu.bindAsEventListener(menuButton));
1480 function initCalendars() {
1481 if (!document.body.hasClassName("popup")) {
1482 initDateSelectorEvents();
1483 initCalendarSelector();
1484 configureSearchField();
1486 var selector = $("calendarSelector");
1488 selector.attachMenu("calendarsMenu");
1492 addEvent(window, 'load', initCalendars);