1 /* JavaScript for SOGoCalendar */
5 var listFilter = 'view_today';
7 var listOfSelection = null;
8 var selectedCalendarCell;
10 var showCompletedTasks = 0;
13 var currentView = "dayview";
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(node) {
254 var day = node.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);
285 function dateSelectorCallback(http) {
286 if (http.readyState == 4
287 && http.status == 200) {
288 document.dateSelectorAjaxRequest = null;
289 var content = http.responseText;
290 setDateSelectorContent(content);
291 cachedDateSelectors[http.callbackData] = content;
294 log ("dateSelectorCallback Ajax error");
297 function eventsListCallback(http) {
298 if (http.readyState == 4
299 && http.status == 200) {
300 var div = $("eventsListView");
302 document.eventsListAjaxRequest = null;
303 var table = $("eventsList").tBodies[0];
304 var params = parseQueryParameters(http.callbackData);
305 sortKey = params["sort"];
306 sortOrder = params["desc"];
307 configureSortableTableHeaders();
309 var data = http.responseText.evalJSON(true);
310 for (var i = 0; i < data.length; i++) {
311 var row = document.createElement("tr");
312 table.appendChild(row);
313 $(row).addClassName("eventRow");
314 row.setAttribute("id", data[i][0]);
315 row.cname = data[i][0];
316 row.owner = data[i][1];
318 var startDate = new Date();
319 startDate.setTime(data[i][4] * 1000);
320 row.day = startDate.getDayString();
321 row.hour = startDate.getHourString();
322 Event.observe(row, "click", onEventClick.bindAsEventListener(row));
323 Event.observe(row, "dblclick", editDoubleClickedEvent.bindAsEventListener(row));
324 Event.observe(row, "contextmenu",
325 onEventContextMenu.bindAsEventListener(row));
327 var td = document.createElement("td");
329 Event.observe(td, "mousedown", listRowMouseDownHandler, true);
330 td.appendChild(document.createTextNode(data[i][3]));
332 td = document.createElement("td");
334 Event.observe(td, "mousedown", listRowMouseDownHandler, true);
335 td.appendChild(document.createTextNode(data[i][8]));
337 td = document.createElement("td");
339 Event.observe(td, "mousedown", listRowMouseDownHandler, true);
340 td.appendChild(document.createTextNode(data[i][9]));
342 td = document.createElement("td");
344 Event.observe(td, "mousedown", listRowMouseDownHandler, true);
345 td.appendChild(document.createTextNode(data[i][6]));
349 log ("eventsListCallback Ajax error");
352 function tasksListCallback(http) {
353 var div = $("tasksListView");
355 if (http.readyState == 4
356 && http.status == 200) {
357 document.tasksListAjaxRequest = null;
358 var list = $("tasksList");
359 var data = http.responseText.evalJSON(true);
361 for (var i = 0; i < data.length; i++) {
362 //log(i + " = " + data[i][3]);
363 var listItem = document.createElement("li");
364 list.appendChild(listItem);
365 Event.observe(listItem, "mousedown", listRowMouseDownHandler); // causes problem with Safari
366 Event.observe(listItem, "click", onRowClick);
367 Event.observe(listItem, "dblclick", editDoubleClickedEvent.bindAsEventListener(listItem));
368 listItem.setAttribute("id", data[i][0]);
369 $(listItem).addClassName(data[i][5]);
370 var owner = data[i][1];
371 listItem.owner = owner;
372 $(listItem).addClassName("ownerIs" + owner);
373 listItem.cname = data[i][0];
374 var input = document.createElement("input");
375 input.setAttribute("type", "checkbox");
376 listItem.appendChild(input);
377 Event.observe(input, "click", updateTaskStatus.bindAsEventListener(input), true);
378 input.setAttribute("value", "1");
380 input.setAttribute("checked", "checked");
381 $(input).addClassName("checkBox");
382 listItem.appendChild(document.createTextNode(data[i][3]));
385 list.scrollTop = list.previousScroll;
387 if (http.callbackData) {
388 var selectedNodesId = http.callbackData;
389 for (var i = 0; i < selectedNodesId.length; i++) {
390 // log(selectedNodesId[i] + " (" + i + ") is selected");
391 $(selectedNodesId[i]).select();
395 log ("tasksListCallback: no data");
398 log ("tasksListCallback Ajax error");
401 function restoreCurrentDaySelection(div) {
402 var elements = div.getElementsByTagName("a");
405 while (!day && i < elements.length)
407 day = elements[i].day;
412 && day.substr(0, 6) == currentDay.substr(0, 6)) {
413 for (i = 0; i < elements.length; i++) {
414 day = elements[i].day;
415 if (day && day == currentDay) {
416 var td = elements[i].getParentWithTagName("td");
417 if (document.selectedDate)
418 document.selectedDate.deselect();
420 document.selectedDate = td;
426 function changeDateSelectorDisplay(day, keepCurrentDay) {
427 var url = ApplicationBaseURL + "dateselector";
429 url += "?day=" + day;
431 if (day != currentDay) {
435 var month = day.substr(0, 6);
436 if (cachedDateSelectors[month]) {
437 // log ("restoring cached selector for month: " + month);
438 setDateSelectorContent(cachedDateSelectors[month]);
441 // log ("loading selector for month: " + month);
442 if (document.dateSelectorAjaxRequest) {
443 document.dateSelectorAjaxRequest.aborted = true;
444 document.dateSelectorAjaxRequest.abort();
446 document.dateSelectorAjaxRequest
447 = triggerAjaxRequest(url,
448 dateSelectorCallback,
454 function changeCalendarDisplay(time, newView) {
455 var url = ApplicationBaseURL + ((newView) ? newView : currentView);
457 selectedCalendarCell = null;
469 url += "?day=" + day;
472 // log ("switching to view: " + newView);
473 // log ("changeCalendarDisplay: " + url);
475 if (document.dayDisplayAjaxRequest) {
476 // log ("aborting day ajaxrq");
477 document.dayDisplayAjaxRequest.aborted = true;
478 document.dayDisplayAjaxRequest.abort();
480 document.dayDisplayAjaxRequest
481 = triggerAjaxRequest(url, calendarDisplayCallback,
482 { "view": newView, "day": day, "hour": hour });
487 function _ensureView(view) {
488 if (currentView != view)
489 changeCalendarDisplay(null, view);
494 function onDayOverview() {
495 return _ensureView("dayview");
498 function onMulticolumnDayOverview() {
499 return _ensureView("multicolumndayview");
502 function onWeekOverview() {
503 return _ensureView("weekview");
506 function onMonthOverview() {
507 return _ensureView("monthview");
510 function scrollDayView(hour) {
513 if (hour.length == 3)
514 rowNumber = parseInt(hour.substr(0, 1));
516 if (hour.substr(0, 1) == "0")
517 rowNumber = parseInt(hour.substr(1, 1));
519 rowNumber = parseInt(hour.substr(0, 2));
524 var daysView = $("daysView");
526 $(daysView.childNodesWithTag("div")[0]).childNodesWithTag("div");
527 if (hours.length > 0)
528 daysView.scrollTop = hours[rowNumber].offsetTop;
531 function onClickableCellsDblClick(event) {
532 newEvent(this, 'event');
534 event.cancelBubble = true;
535 event.returnValue = false;
538 function refreshCalendarEvents() {
539 var todayDate = new Date();
542 if (currentView == "dayview") {
546 sd = todayDate.getDayString();
549 else if (currentView == "weekview") {
552 startDate = currentDay.asDate();
554 startDate = todayDate;
555 startDate = startDate.beginOfWeek();
556 sd = startDate.getDayString();
557 var endDate = new Date();
558 endDate.setTime(startDate.getTime());
560 ed = endDate.getDayString();
565 monthDate = currentDay.asDate();
567 monthDate = todayDate;
568 monthDate.setDate(1);
569 sd = monthDate.beginOfWeek().getDayString();
571 var lastMonthDate = new Date();
572 lastMonthDate.setTime(monthDate.getTime());
573 lastMonthDate.setMonth(monthDate.getMonth() + 1);
574 lastMonthDate.addDays(-1);
575 ed = lastMonthDate.endOfWeek().getDayString();
577 if (document.refreshCalendarEventsAjaxRequest) {
578 document.refreshCalendarEventsAjaxRequest.aborted = true;
579 document.refreshCalendarEventsAjaxRequest.abort();
581 var url = ApplicationBaseURL + "eventslist?sd=" + sd + "&ed=" + ed;
582 document.refreshCalendarEventsAjaxRequest
583 = triggerAjaxRequest(url, refreshCalendarEventsCallback,
584 {"startDate": sd, "endDate": ed});
587 function refreshCalendarEventsCallback(http) {
588 if (http.readyState == 4
589 && http.status == 200) {
590 var data = http.responseText.evalJSON(true);
591 // log("refresh calendar events: " + data.length);
592 for (var i = 0; i < data.length; i++)
593 drawCalendarEvent(data[i],
594 http.callbackData["startDate"],
595 http.callbackData["endDate"]);
598 log("AJAX error when refreshing calendar events");
601 function drawCalendarEvent(eventData, sd, ed) {
602 var viewStartDate = sd.asDate();
603 var viewEndDate = ed.asDate();
605 var startDate = new Date();
606 startDate.setTime(eventData[4] * 1000);
607 var endDate = new Date();
608 endDate.setTime(eventData[5] * 1000);
610 var days = startDate.daysUpTo(endDate);
612 var divs = new Array();
615 if (currentView == "monthview"
616 && (eventData[7] == 0))
617 title = startDate.getDisplayHoursString() + " " + eventData[3];
619 title = eventData[3];
621 // log("title: " + title);
622 // log("viewS: " + viewStartDate);
623 var startHour = null;
626 var siblings = new Array();
627 for (var i = 0; i < days.length; i++)
628 if (days[i].earlierDate(viewStartDate) == viewStartDate
629 && days[i].laterDate(viewEndDate) == viewEndDate) {
632 // log("day: " + days[i]);
634 var quarters = (startDate.getHours() * 4
635 + Math.floor(startDate.getMinutes() / 15));
637 startHour = startDate.getDisplayHoursString();
638 endHour = endDate.getDisplayHoursString();
645 if (i == days.length - 1) {
646 var quarters = (endDate.getHours() * 4
647 + Math.ceil(endDate.getMinutes() / 15));
652 lasts = ends - starts;
656 var eventDiv = newEventDIV(eventData[0], eventData[1], starts, lasts,
658 siblings.push(eventDiv);
659 eventDiv.siblings = siblings;
660 var dayString = days[i].getDayString();
661 // log("day: " + dayString);
662 var parentDiv = null;
663 if (currentView == "monthview") {
664 var dayDivs = $("monthDaysView").childNodesWithTag("div");
666 while (!parentDiv && j < dayDivs.length) {
667 if (dayDivs[j].getAttribute("day") == dayString)
668 parentDiv = dayDivs[j];
674 if (eventData[7] == 0) {
675 var daysView = $("daysView");
676 var eventsDiv = $(daysView).childNodesWithTag("div")[1];
677 var dayDivs = $(eventsDiv).childNodesWithTag("div");
679 while (!parentDiv && j < dayDivs.length) {
680 if (dayDivs[j].getAttribute("day") == dayString)
681 parentDiv = dayDivs[j].childNodesWithTag("div")[0];
687 var header = $("calendarHeader");
688 var daysDiv = $(header).childNodesWithTag("div")[1];
689 var dayDivs = $(daysDiv).childNodesWithTag("div");
691 while (!parentDiv && j < dayDivs.length) {
692 if (dayDivs[j].getAttribute("day") == dayString)
693 parentDiv = dayDivs[j];
700 parentDiv.appendChild(eventDiv);
704 function newEventDIV(cname, owner, starts, lasts,
705 startHour, endHour, title) {
706 var eventDiv = document.createElement("div");
707 eventDiv.cname = cname;
708 eventDiv.owner = owner;
709 eventDiv.addClassName("event");
710 eventDiv.addClassName("starts" + starts);
711 eventDiv.addClassName("lasts" + lasts);
712 for (var i = 1; i < 5; i++) {
713 var shadowDiv = document.createElement("div");
714 eventDiv.appendChild(shadowDiv);
715 shadowDiv.addClassName("shadow");
716 shadowDiv.addClassName("shadow" + i);
718 var innerDiv = document.createElement("div");
719 eventDiv.appendChild(innerDiv);
720 innerDiv.addClassName("eventInside");
721 innerDiv.addClassName("ownerIs" + owner);
723 var gradientDiv = document.createElement("div");
724 innerDiv.appendChild(gradientDiv);
725 gradientDiv.addClassName("gradient");
726 var gradientImg = document.createElement("img");
727 gradientDiv.appendChild(gradientImg);
728 gradientImg.src = ResourcesURL + "/event-gradient.png";
730 var textDiv = document.createElement("div");
731 innerDiv.appendChild(textDiv);
732 textDiv.addClassName("text");
734 var headerSpan = document.createElement("span");
735 textDiv.appendChild(headerSpan);
736 headerSpan.addClassName("eventHeader");
737 headerSpan.appendChild(document.createTextNode(startHour + " - "
739 textDiv.appendChild(document.createElement("br"));
741 textDiv.appendChild(document.createTextNode(title));
743 Event.observe(eventDiv, "mousedown", listRowMouseDownHandler);
744 Event.observe(eventDiv, "click",
745 onCalendarSelectEvent.bindAsEventListener(eventDiv));
746 Event.observe(eventDiv, "dblclick",
747 editDoubleClickedEvent.bindAsEventListener(eventDiv));
752 function calendarDisplayCallback(http) {
753 var div = $("calendarView");
755 if (http.readyState == 4
756 && http.status == 200) {
757 document.dayDisplayAjaxRequest = null;
758 div.innerHTML = http.responseText;
759 if (http.callbackData["view"])
760 currentView = http.callbackData["view"];
761 if (http.callbackData["day"])
762 currentDay = http.callbackData["day"];
764 if (http.callbackData["hour"])
765 hour = http.callbackData["hour"];
767 if (currentView == "monthview")
768 contentView = $("calendarContent");
771 contentView = $("daysView");
773 refreshCalendarEvents();
774 var days = document.getElementsByClassName("day", contentView);
775 if (currentView == "monthview")
776 for (var i = 0; i < days.length; i++) {
777 Event.observe(days[i], "click", onCalendarSelectDay.bindAsEventListener(days[i]));
778 Event.observe(days[i], "dblclick", onClickableCellsDblClick.bindAsEventListener(days[i]));
781 var headerDivs = $("calendarHeader").childNodesWithTag("div");
782 var headerDaysLabels = document.getElementsByClassName("day", headerDivs[0]);
783 var headerDays = document.getElementsByClassName("day", headerDivs[1]);
784 for (var i = 0; i < days.length; i++) {
785 headerDays[i].hour = "allday";
786 Event.observe(headerDaysLabels[i], "mousedown", listRowMouseDownHandler);
787 Event.observe(headerDays[i], "click",
788 onCalendarSelectDay.bindAsEventListener(days[i]));
789 Event.observe(headerDays[i], "dblclick",
790 onClickableCellsDblClick.bindAsEventListener(headerDays[i]));
791 Event.observe(days[i], "click",
792 onCalendarSelectDay.bindAsEventListener(days[i]));
793 var clickableCells = document.getElementsByClassName("clickableHourCell",
795 for (var j = 0; j < clickableCells.length; j++)
796 Event.observe(clickableCells[j], "dblclick",
797 onClickableCellsDblClick.bindAsEventListener(clickableCells[j]));
802 log ("calendarDisplayCallback Ajax error (" + http.readyState + "/" + http.status + ")");
805 function assignCalendar(name) {
806 if (typeof(skycalendar) != "undefined") {
809 node.calendar = new skycalendar(node);
810 node.calendar.setCalendarPage(ResourcesURL + "/skycalendar.html");
811 var dateFormat = node.getAttribute("dateFormat");
813 node.calendar.setDateFormat(dateFormat);
817 function popupCalendar(node) {
818 var nodeId = node.getAttribute("inputId");
819 var input = $(nodeId);
820 input.calendar.popup();
825 function onEventContextMenu(event) {
826 var topNode = $("eventsList");
829 var menu = $("eventsListMenu");
831 Event.observe(menu, "hideMenu", onEventContextMenuHide);
832 popupMenu(event, "eventsListMenu", this);
834 var topNode = $("eventsList");
835 var selectedNodes = topNode.getSelectedRows();
836 topNode.menuSelectedRows = selectedNodes;
837 for (var i = 0; i < selectedNodes.length; i++)
838 selectedNodes[i].deselect();
840 topNode.menuSelectedEntry = this;
844 function onEventContextMenuHide(event) {
845 var topNode = $("eventsList");
847 if (topNode.menuSelectedEntry) {
848 topNode.menuSelectedEntry.deselect();
849 topNode.menuSelectedEntry = null;
851 if (topNode.menuSelectedRows) {
852 var nodeIds = topNode.menuSelectedRows;
853 for (var i = 0; i < nodeIds.length; i++) {
854 var node = $(nodeIds[i]);
857 topNode.menuSelectedRows = null;
861 function onEventsSelectionChange() {
862 listOfSelection = this;
863 this.removeClassName("_unfocused");
864 $("tasksList").addClassName("_unfocused");
867 function onTasksSelectionChange() {
868 listOfSelection = this;
869 this.removeClassName("_unfocused");
870 $("eventsList").addClassName("_unfocused");
873 function _loadEventHref(href) {
874 if (document.eventsListAjaxRequest) {
875 document.eventsListAjaxRequest.aborted = true;
876 document.eventsListAjaxRequest.abort();
878 var url = ApplicationBaseURL + href;
879 document.eventsListAjaxRequest
880 = triggerAjaxRequest(url, eventsListCallback, href);
882 var table = $("eventsList").tBodies[0];
883 while (table.rows.length > 1)
884 table.removeChild(table.rows[1]);
889 function _loadTasksHref(href) {
890 if (document.tasksListAjaxRequest) {
891 document.tasksListAjaxRequest.aborted = true;
892 document.tasksListAjaxRequest.abort();
894 url = ApplicationBaseURL + href;
896 var tasksList = $("tasksList");
899 selectedIds = tasksList.getSelectedNodesId();
902 document.tasksListAjaxRequest
903 = triggerAjaxRequest(url, tasksListCallback, selectedIds);
905 tasksList.previousScroll = tasksList.scrollTop;
906 while (tasksList.childNodes.length)
907 tasksList.removeChild(tasksList.childNodes[0]);
912 function onHeaderClick(event) {
913 // log("onHeaderClick: " + this.link);
914 _loadEventHref(this.link);
916 preventDefault(event);
919 function refreshEvents() {
920 return _loadEventHref("eventslist?desc=" + sortOrder
922 + "&day=" + currentDay
923 + "&filterpopup=" + listFilter);
926 function refreshTasks() {
927 return _loadTasksHref("taskslist?show-completed=" + showCompletedTasks);
930 function refreshEventsAndDisplay() {
932 changeCalendarDisplay();
935 function onListFilterChange() {
936 var node = $("filterpopup");
938 listFilter = node.value;
939 // log ("listFilter = " + listFilter);
941 return refreshEvents();
944 function onEventClick(event) {
945 var target = getTarget(event);
946 var node = target.getParentWithTagName("tr");
948 var hour = node.hour;
950 changeCalendarDisplay( { "day": day, "hour": hour} );
951 changeDateSelectorDisplay(day);
953 return onRowClick(event);
956 function selectMonthInMenu(menu, month) {
957 var entries = menu.childNodes[1].childNodesWithTag("LI");
958 for (i = 0; i < entries.length; i++) {
959 var entry = entries[i];
960 var entryMonth = entry.getAttribute("month");
961 if (entryMonth == month)
962 entry.addClassName("currentMonth");
964 entry.removeClassName("currentMonth");
968 function selectYearInMenu(menu, month) {
969 var entries = menu.childNodes[1].childNodes;
970 for (i = 0; i < entries.length; i++) {
971 var entry = entries[i];
972 if (entry instanceof HTMLLIElement) {
973 var entryMonth = entry.innerHTML;
974 if (entryMonth == month)
975 entry.addClassName("currentMonth");
977 entry.removeClassName("currentMonth");
982 function popupMonthMenu(event, menuId) {
983 var node = event.target;
985 if (event.button == 0) {
986 event.cancelBubble = true;
987 event.returnValue = false;
989 if (document.currentPopupMenu)
990 hideMenu(event, document.currentPopupMenu);
992 var popup = $(menuId);
993 var id = node.getAttribute("id");
994 if (id == "monthLabel")
995 selectMonthInMenu(popup, node.getAttribute("month"));
997 selectYearInMenu(popup, node.innerHTML);
999 var diff = (popup.offsetWidth - node.offsetWidth) /2;
1001 popup.style.top = (node.offsetTop + 95) + "px";
1002 popup.style.left = (node.offsetLeft - diff) + "px";
1003 popup.style.visibility = "visible";
1005 bodyOnClick = "" + document.body.getAttribute("onclick");
1006 document.body.setAttribute("onclick", "onBodyClick('" + menuId + "');");
1007 document.currentPopupMenu = popup;
1011 function onMonthMenuItemClick(event) {
1012 var month = '' + this.getAttribute("month");
1013 var year = '' + $("yearLabel").innerHTML;
1015 changeDateSelectorDisplay(year + month + "01", true);
1018 function onYearMenuItemClick(event) {
1019 var month = '' + $("monthLabel").getAttribute("month");;
1020 var year = '' + this.innerHTML;
1022 changeDateSelectorDisplay(year + month + "01", true);
1025 function onSearchFormSubmit() {
1026 log ("search not implemented");
1031 function onCalendarSelectEvent() {
1032 var list = $("eventsList");
1035 if (selectedCalendarCell)
1036 for (var i = 0; i < selectedCalendarCell.length; i++)
1037 selectedCalendarCell[i].deselect();
1039 for (var i = 0; i < this.siblings.length; i++)
1040 this.siblings[i].select();
1041 selectedCalendarCell = this.siblings;
1042 var row = $(this.cname);
1044 var div = row.parentNode.parentNode.parentNode;
1045 div.scrollTop = row.offsetTop - (div.offsetHeight / 2);
1050 function onCalendarSelectDay(event) {
1052 if (currentView == "multicolumndayview")
1053 day = this.getAttribute("day");
1055 day = this.getAttribute("day");
1056 var needRefresh = (listFilter == 'view_selectedday'
1057 && day != currentDay);
1059 if (currentView == 'weekview')
1060 changeWeekCalendarDisplayOfSelectedDay(this);
1061 else if (currentView == 'monthview')
1062 changeMonthCalendarDisplayOfSelectedDay(this);
1063 changeDateSelectorDisplay(day);
1065 if (listOfSelection) {
1066 listOfSelection.addClassName("_unfocused");
1067 listOfSelection = null;
1074 function changeWeekCalendarDisplayOfSelectedDay(node) {
1075 var days = document.getElementsByClassName("day", node.parentNode);
1076 var headerDiv = $("calendarHeader").childNodesWithTag("div")[1];
1077 var headerDays = document.getElementsByClassName("day", headerDiv);
1079 // log ("days: " + days.length + "; headerDays: " + headerDays.length);
1080 for (var i = 0; i < days.length; i++)
1081 if (days[i] != node) {
1082 // log("unselect day : " + i);
1083 headerDays[i].removeClassName("selectedDay");
1084 days[i].removeClassName("selectedDay");
1087 // log("selected day : " + i);
1088 headerDays[i].addClassName("selectedDay");
1089 days[i].addClassName("selectedDay");
1093 function findMonthCalendarSelectedCell(daysContainer) {
1097 while (!found && i < daysContainer.childNodes.length) {
1098 var currentNode = daysContainer.childNodes[i];
1099 if (currentNode instanceof HTMLDivElement
1100 && currentNode.hasClassName("selectedDay")) {
1101 daysContainer.selectedCell = currentNode;
1109 function changeMonthCalendarDisplayOfSelectedDay(node) {
1110 var daysContainer = node.parentNode;
1111 if (!daysContainer.selectedCell)
1112 findMonthCalendarSelectedCell(daysContainer);
1114 if (daysContainer.selectedCell)
1115 daysContainer.selectedCell.removeClassName("selectedDay");
1116 daysContainer.selectedCell = node;
1117 node.addClassName("selectedDay");
1120 function onShowCompletedTasks(event) {
1121 showCompletedTasks = (this.checked ? 1 : 0);
1123 return refreshTasks();
1126 function updateTaskStatus(event) {
1127 var taskId = this.parentNode.getAttribute("id");
1128 var taskOwner = this.parentNode.owner;
1129 var newStatus = (this.checked ? 1 : 0);
1130 var http = createHTTPClient();
1132 // log("update task status: " + taskId + " to " + this.checked);
1133 event.cancelBubble = true;
1135 url = (UserFolderURL + "../" + taskOwner
1136 + "/Calendar/" + taskId
1137 + "/changeStatus?status=" + newStatus);
1140 // log ("url: " + url);
1141 // TODO: add parameter to signal that we are only interested in OK
1142 http.open("POST", url, false /* not async */);
1145 if (http.status == 200)
1148 log ("no http client?");
1153 function updateCalendarStatus(event) {
1154 var list = new Array();
1156 var nodes = $("calendarList").childNodesWithTag("li");
1157 for (var i = 0; i < nodes.length; i++) {
1158 var input = $(nodes[i]).childNodesWithTag("input")[0];
1159 if (input.checked) {
1160 var folderId = nodes[i].getAttribute("id");
1161 var elems = folderId.split(":");
1162 if (elems.length > 1)
1163 list.push(elems[0]);
1165 list.push(UserLogin);
1170 list.push(UserLogin);
1171 nodes[0].childNodesWithTag("input")[0].checked = true;
1173 // ApplicationBaseURL = (UserFolderURL + "Groups/_custom_"
1174 // + list.join(",") + "/Calendar/");
1177 var folderID = this.parentNode.getAttribute("id");
1178 var urlstr = URLForFolderID(folderID);
1180 urlstr += "/activateFolder";
1182 urlstr += "/deactivateFolder";
1183 //log("updateCalendarStatus: ajax request = " + urlstr + ", folderID = " + folderID);
1184 triggerAjaxRequest(urlstr, calendarStatusCallback, folderID);
1187 updateCalendarsList();
1190 changeCalendarDisplay();
1196 function calendarStatusCallback(http) {
1197 if (http.readyState == 4) {
1198 if (isHttpStatus204(http.status)) {
1201 changeCalendarDisplay();
1204 var folder = $(http.callbackData);
1205 var input = folder.childNodesWithTag("input")[0];
1206 input.checked = (!input.checked);
1210 log("calendarStatusCallback Ajax error");
1213 function calendarEntryCallback(http) {
1214 if (http.readyState == 4) {
1215 var denied = (http.status != 204)
1216 var entry = $(http.callbackData);
1218 entry.addClassName("denied");
1220 entry.removeClassName("denied");
1224 function updateCalendarsList(method) {
1225 var list = $("calendarList").childNodesWithTag("li");
1226 for (var i = 0; i < list.length; i++) {
1227 var folderID = list[i].getAttribute("id");
1228 var url = URLForFolderID(folderID) + "/canAccessContent";
1229 triggerAjaxRequest(url, calendarEntryCallback, folderID);
1233 function addContact(tag, fullContactName, contactId, contactName, contactEmail) {
1234 var uids = $("uixselector-calendarsList-uidList");
1235 // log("addContact");
1238 var re = new RegExp("(^|,)" + contactId + "($|,)");
1240 if (!re.test(uids.value))
1242 if (uids.value.length > 0)
1243 uids.value += ',' + contactId;
1245 uids.value = contactId;
1246 var names = $("calendarList");
1247 var listElems = names.childNodesWithTag("li");
1248 var colorDef = indexColor(listElems.length);
1249 names.appendChild(userCalendarEntry(contactId, colorDef));
1257 function validateBrowseURL(input) {
1258 var button = $("browseURLBtn");
1260 if (input.value.length) {
1261 if (!button.enabled)
1262 enableAnchor(button);
1263 } else if (!button.disabled)
1264 disableAnchor(button);
1267 function browseURL(anchor, event) {
1268 if (event.button == 0) {
1269 var input = $("url");
1270 var url = input.value;
1272 window.open(url, '_blank');
1278 function getMenus() {
1281 var dateMenu = new Array();
1282 for (var i = 0; i < 12; i++)
1283 dateMenu.push(onMonthMenuItemClick);
1284 menus["monthListMenu"] = dateMenu;
1286 dateMenu = new Array();
1287 for (var i = 0; i < 11; i++)
1288 dateMenu.push(onYearMenuItemClick);
1289 menus["yearListMenu"] = dateMenu;
1291 menus["eventsListMenu"] = new Array(onMenuNewEventClick, "-",
1293 editEvent, deleteEvent, "-",
1296 menus["calendarsMenu"] = new Array(null, null, "-", null, null, "-",
1297 null, "-", onMenuSharing);
1298 menus["searchMenu"] = new Array(setSearchCriteria);
1303 function onMenuSharing(event) {
1304 var folders = $("calendarList");
1305 var selected = folders.getSelectedNodes()[0];
1306 /* FIXME: activation of the context menu should preferable select the entry
1307 above which the event has occured */
1309 var folderID = selected.getAttribute("id");
1310 var urlstr = URLForFolderID(folderID) + "/acls";
1312 openAclWindow(urlstr);
1316 function configureDragHandles() {
1317 var handle = $("verticalDragHandle");
1319 handle.addInterface(SOGoDragHandlesInterface);
1320 handle.leftBlock=$("leftPanel");
1321 handle.rightBlock=$("rightPanel");
1324 handle = $("rightDragHandle");
1326 handle.addInterface(SOGoDragHandlesInterface);
1327 handle.upperBlock=$("eventsListView");
1328 handle.lowerBlock=$("calendarView");
1332 function initCalendarSelector() {
1333 var selector = $("calendarSelector");
1334 updateCalendarStatus();
1335 selector.changeNotification = updateCalendarsList;
1337 var list = $("calendarList").childNodesWithTag("li");
1338 for (var i = 0; i < list.length; i++) {
1339 var input = list[i].childNodesWithTag("input")[0];
1340 Event.observe(input, "click", updateCalendarStatus.bindAsEventListener(input)); // not registered in IE?
1341 //Event.observe(list[i], "mousedown", listRowMouseDownHandler, true); // problem with Safari
1342 Event.observe(list[i], "click", onRowClick);
1345 var links = $("calendarSelectorButtons").childNodesWithTag("a");
1346 Event.observe(links[0], "click", onCalendarAdd);
1347 Event.observe(links[1], "click", onCalendarRemove);
1350 function onCalendarAdd(event) {
1351 openUserFolderSelector(onFolderSubscribeCB, "calendar");
1353 preventDefault(event);
1356 function appendCalendar(folderName, folder) {
1357 var calendarList = $("calendarList");
1358 var lis = calendarList.childNodesWithTag("li");
1359 var color = indexColor(lis.length);
1360 log ("color: " + color);
1362 var li = document.createElement("li");
1363 calendarList.appendChild(li);
1365 var checkBox = document.createElement("input");
1366 li.appendChild(checkBox);
1368 li.appendChild(document.createTextNode(" "));
1370 var colorBox = document.createElement("div");
1371 li.appendChild(colorBox);
1372 li.appendChild(document.createTextNode(" " + folderName));
1373 colorBox.appendChild(document.createTextNode("OO"));
1375 li.setAttribute("id", folder);
1376 Event.observe(li, "mousedown", listRowMouseDownHandler);
1377 Event.observe(li, "click", onRowClick);
1378 checkBox.addClassName("checkBox");
1379 checkBox.type = "checkbox";
1380 Event.observe(checkBox, "click", updateCalendarStatus.bindAsEventListener(checkBox));
1382 colorBox.addClassName("colorBox");
1384 colorBox.setStyle({ color: color,
1385 backgroundColor: color });
1388 var contactId = folder.split(":")[0];
1389 var styles = document.getElementsByTagName("style");
1391 var url = URLForFolderID(folder) + "/canAccessContent";
1392 triggerAjaxRequest(url, calendarEntryCallback, folder);
1394 styles[0].innerHTML += ('.ownerIs' + contactId + ' {'
1395 + ' background-color: '
1397 + ' !important; }');
1400 function onFolderSubscribeCB(folderData) {
1401 var folder = $(folderData["folder"]);
1403 appendCalendar(folderData["folderName"], folderData["folder"]);
1406 function onFolderUnsubscribeCB(folderId) {
1407 var node = $(folderId);
1408 node.parentNode.removeChild(node);
1411 function onCalendarRemove(event) {
1412 var nodes = $("calendarList").getSelectedNodes();
1413 if (nodes.length > 0) {
1414 nodes[0].deselect();
1415 var folderId = nodes[0].getAttribute("id");
1416 var folderIdElements = folderId.split(":");
1417 if (folderIdElements.length > 1) {
1418 unsubscribeFromFolder(folderId, onFolderUnsubscribeCB, folderId);
1422 preventDefault(event);
1425 function configureSearchField() {
1426 var searchValue = $("searchValue");
1428 Event.observe(searchValue, "mousedown",
1429 onSearchMouseDown.bindAsEventListener(searchValue));
1430 Event.observe(searchValue, "click",
1431 popupSearchMenu.bindAsEventListener(searchValue));
1432 Event.observe(searchValue, "blur",
1433 onSearchBlur.bindAsEventListener(searchValue));
1434 Event.observe(searchValue, "focus",
1435 onSearchFocus.bindAsEventListener(searchValue));
1436 Event.observe(searchValue, "keydown",
1437 onSearchKeyDown.bindAsEventListener(searchValue));
1440 function configureLists() {
1441 var list = $("tasksList");
1442 list.multiselect = true;
1443 Event.observe(list, "mousedown",
1444 onTasksSelectionChange.bindAsEventListener(list));
1446 var input = $("showHideCompletedTasks");
1447 Event.observe(input, "click",
1448 onShowCompletedTasks.bindAsEventListener(input));
1450 list = $("eventsList");
1451 list.multiselect = true;
1452 Event.observe(list, "mousedown",
1453 onEventsSelectionChange.bindAsEventListener(list));
1454 var div = list.parentNode;
1455 Event.observe(div, "contextmenu",
1456 onEventContextMenu.bindAsEventListener(div));
1459 function initCalendars() {
1460 if (!document.body.hasClassName("popup")) {
1461 initCalendarSelector();
1462 configureSearchField();
1464 var selector = $("calendarSelector");
1466 selector.attachMenu("calendarsMenu");
1470 addEvent(window, 'load', initCalendars);