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 calendarsOfEventsToDelete = new Array();
22 var usersRightsWindowHeight = 250;
23 var usersRightsWindowWidth = 502;
25 function newEvent(sender, type) {
30 var hour = sender.hour;
32 hour = sender.getAttribute("hour");
33 var folderID = getSelectedFolder();
34 var urlstr = ApplicationBaseURL + folderID + "/new" + type;
35 var params = new Array();
37 params.push("day=" + day);
39 params.push("hm=" + hour);
40 if (params.length > 0)
41 urlstr += "?" + params.join("&");
43 window.open(urlstr, "", "width=490,height=470,resizable=0");
45 return false; /* stop following the link */
48 function getSelectedFolder() {
51 var nodes = $("calendarList").getSelectedRows();
53 folder = nodes[0].getAttribute("id");
60 function onMenuNewEventClick(event) {
61 newEvent(this, "event");
64 function onMenuNewTaskClick(event) {
65 newEvent(this, "task");
68 function _editEventId(id, calendar) {
69 var urlstr = ApplicationBaseURL + "/" + calendar + "/" + id + "/edit";
70 var targetname = "SOGo_edit_" + id;
71 var win = window.open(urlstr, "_blank",
72 "width=490,height=470,resizable=0");
76 function editEvent() {
77 if (listOfSelection) {
78 var nodes = listOfSelection.getSelectedRows();
80 for (var i = 0; i < nodes.length; i++)
81 _editEventId(nodes[i].getAttribute("id"),
83 } else if (selectedCalendarCell) {
84 _editEventId(selectedCalendarCell[0].cname,
85 selectedCalendarCell[0].calendar);
88 return false; /* stop following the link */
91 function _batchDeleteEvents() {
92 var events = eventsToDelete.shift();
93 var calendar = calendarsOfEventsToDelete.shift();
94 var urlstr = (ApplicationBaseURL + "/" + calendar
95 + "/batchDelete?ids=" + events.join('/'));
96 document.deleteEventAjaxRequest = triggerAjaxRequest(urlstr,
101 function deleteEvent() {
102 if (listOfSelection) {
103 var nodes = listOfSelection.getSelectedRows();
105 if (nodes.length > 0) {
107 if (listOfSelection == $("tasksList"))
108 label = labels["taskDeleteConfirmation"];
110 label = labels["eventDeleteConfirmation"];
112 if (confirm(label)) {
113 if (document.deleteEventAjaxRequest) {
114 document.deleteEventAjaxRequest.aborted = true;
115 document.deleteEventAjaxRequest.abort();
117 var sortedNodes = new Array();
118 var calendars = new Array();
120 for (var i = 0; i < nodes.length; i++) {
121 var calendar = nodes[i].calendar;
122 if (!sortedNodes[calendar]) {
123 sortedNodes[calendar] = new Array();
124 calendars.push(calendar);
126 sortedNodes[calendar].push(nodes[i].cname);
128 for (var i = 0; i < calendars.length; i++) {
129 calendarsOfEventsToDelete.push(calendars[i]);
130 eventsToDelete.push(sortedNodes[calendars[i]]);
132 _batchDeleteEvents();
136 else if (selectedCalendarCell) {
137 var label = labels["eventDeleteConfirmation"];
138 if (confirm(label)) {
139 if (document.deleteEventAjaxRequest) {
140 document.deleteEventAjaxRequest.aborted = true;
141 document.deleteEventAjaxRequest.abort();
143 eventsToDelete.push([selectedCalendarCell[0].cname]);
144 calendarsOfEventsToDelete.push(selectedCalendarCell[0].calendar);
145 _batchDeleteEvents();
149 window.alert("no selection");
154 function modifyEvent(sender, modification) {
155 var currentLocation = '' + window.location;
156 var arr = currentLocation.split("/");
157 arr[arr.length-1] = modification;
159 document.modifyEventAjaxRequest = triggerAjaxRequest(arr.join("/"),
166 function closeInvitationWindow() {
167 var closeDiv = document.createElement("div");
168 document.body.appendChild(closeDiv);
169 closeDiv.addClassName("javascriptPopupBackground");
171 var closePseudoWin = document.createElement("div");
172 document.body.appendChild(closePseudoWin);
173 closePseudoWin.addClassName("javascriptMessagePseudoTopWindow");
174 closePseudoWin.style.top = "0px;";
175 closePseudoWin.style.left = "0px;";
176 closePseudoWin.style.right = "0px;";
177 closePseudoWin.appendChild(document.createTextNode(labels["closeThisWindowMessage"]));
179 var calLink = document.createElement("a");
180 closePseudoWin.appendChild(calLink);
181 calLink.href = ApplicationBaseURL;
182 calLink.appendChild(document.createTextNode(labels["Calendar"].toLowerCase()));
185 function modifyEventCallback(http) {
186 if (http.readyState == 4) {
187 if (http.status == 200) {
188 var mailInvitation = queryParameters["mail-invitation"];
189 if (mailInvitation && mailInvitation.toLowerCase() == "yes")
190 closeInvitationWindow();
192 window.opener.setTimeout("refreshEventsAndDisplay();", 100);
193 window.setTimeout("window.close();", 100);
197 // log("showing alert...");
198 window.alert(labels["eventPartStatModificationError"]);
200 document.modifyEventAjaxRequest = null;
204 function deleteEventCallback(http) {
205 if (http.readyState == 4) {
206 if (isHttpStatus204(http.status)) {
207 var nodes = http.callbackData;
208 for (var i = 0; i < nodes.length; i++) {
209 var node = $(nodes[i]);
211 node.parentNode.removeChild(node);
213 if (eventsToDelete.length)
214 _batchDeleteEvents();
216 document.deleteEventAjaxRequest = null;
219 changeCalendarDisplay();
223 log ("deleteEventCallback Ajax error");
227 function editDoubleClickedEvent(event) {
228 _editEventId(this.cname, this.calendar);
230 preventDefault(event);
231 event.cancelBubble = true;
234 function onSelectAll() {
235 var list = $("eventsList");
236 list.selectRowsMatchingClass("eventRow");
241 function onDaySelect(node) {
242 var day = node.getAttribute('day');
243 var needRefresh = (listFilter == 'view_selectedday'
244 && day != currentDay);
246 var td = $(node).getParentWithTagName("td");
247 var table = $(td).getParentWithTagName("table");
249 // log ("table.selected: " + table.selected);
251 if (document.selectedDate)
252 document.selectedDate.deselect();
255 document.selectedDate = td;
257 changeCalendarDisplay( { "day": day } );
264 function onDateSelectorGotoMonth(event) {
265 var day = this.getAttribute("date");
267 changeDateSelectorDisplay(day, true);
272 function onCalendarGotoDay(node) {
273 var day = node.getAttribute("date");
275 changeDateSelectorDisplay(day);
276 changeCalendarDisplay( { "day": day } );
281 function gotoToday() {
282 changeDateSelectorDisplay('');
283 changeCalendarDisplay();
288 function setDateSelectorContent(content) {
289 var div = $("dateSelectorView");
291 div.innerHTML = content;
292 if (currentDay.length > 0)
293 restoreCurrentDaySelection(div);
295 initDateSelectorEvents();
298 function dateSelectorCallback(http) {
299 if (http.readyState == 4
300 && http.status == 200) {
301 document.dateSelectorAjaxRequest = null;
302 var content = http.responseText;
303 setDateSelectorContent(content);
304 cachedDateSelectors[http.callbackData] = content;
307 log ("dateSelectorCallback Ajax error");
310 function eventsListCallback(http) {
311 if (http.readyState == 4
312 && http.status == 200) {
313 var div = $("eventsListView");
315 document.eventsListAjaxRequest = null;
316 var table = $("eventsList");
317 var params = parseQueryParameters(http.callbackData);
318 sortKey = params["sort"];
319 sortOrder = params["desc"];
320 lastClickedRow = null; // from generic.js
322 var data = http.responseText.evalJSON(true);
323 for (var i = 0; i < data.length; i++) {
324 var row = document.createElement("tr");
325 table.tBodies[0].appendChild(row);
326 $(row).addClassName("eventRow");
327 row.setAttribute("id", escape(data[i][0]));
328 row.cname = escape(data[i][0]);
329 row.calendar = data[i][1];
331 var startDate = new Date();
332 startDate.setTime(data[i][4] * 1000);
333 row.day = startDate.getDayString();
334 row.hour = startDate.getHourString();
335 Event.observe(row, "click",
336 onEventClick.bindAsEventListener(row));
337 Event.observe(row, "dblclick",
338 editDoubleClickedEvent.bindAsEventListener(row));
339 Event.observe(row, "contextmenu",
340 onEventContextMenu.bindAsEventListener(row));
342 var td = document.createElement("td");
344 Event.observe(td, "mousedown", listRowMouseDownHandler, true);
345 td.appendChild(document.createTextNode(data[i][3]));
347 td = document.createElement("td");
349 Event.observe(td, "mousedown", listRowMouseDownHandler, true);
350 td.appendChild(document.createTextNode(data[i][8]));
352 td = document.createElement("td");
354 Event.observe(td, "mousedown", listRowMouseDownHandler, true);
355 td.appendChild(document.createTextNode(data[i][9]));
357 td = document.createElement("td");
359 Event.observe(td, "mousedown", listRowMouseDownHandler, true);
360 td.appendChild(document.createTextNode(data[i][6]));
364 log ("eventsListCallback Ajax error");
367 function tasksListCallback(http) {
368 var div = $("tasksListView");
370 if (http.readyState == 4
371 && http.status == 200) {
372 document.tasksListAjaxRequest = null;
373 var list = $("tasksList");
374 var data = http.responseText.evalJSON(true);
376 for (var i = 0; i < data.length; i++) {
377 //log(i + " = " + data[i][3]);
378 var listItem = document.createElement("li");
379 list.appendChild(listItem);
380 Event.observe(listItem, "mousedown", listRowMouseDownHandler);
381 Event.observe(listItem, "click", onRowClick);
382 Event.observe(listItem, "dblclick", editDoubleClickedEvent.bindAsEventListener(listItem));
383 listItem.setAttribute("id", data[i][0]);
384 $(listItem).addClassName(data[i][5]);
385 listItem.calendar = data[i][1];
386 $(listItem).addClassName("calendarFolder" + data[i][1]);
387 listItem.cname = escape(data[i][0]);
388 var input = document.createElement("input");
389 input.setAttribute("type", "checkbox");
390 listItem.appendChild(input);
391 Event.observe(input, "click", updateTaskStatus.bindAsEventListener(input), true);
392 input.setAttribute("value", "1");
394 input.setAttribute("checked", "checked");
395 $(input).addClassName("checkBox");
396 listItem.appendChild(document.createTextNode(data[i][3]));
399 list.scrollTop = list.previousScroll;
401 if (http.callbackData) {
402 var selectedNodesId = http.callbackData;
403 for (var i = 0; i < selectedNodesId.length; i++) {
404 // log(selectedNodesId[i] + " (" + i + ") is selected");
405 $(selectedNodesId[i]).select();
409 log ("tasksListCallback: no data");
412 log ("tasksListCallback Ajax error");
415 function restoreCurrentDaySelection(div) {
416 var elements = $(div).getElementsByTagName("a");
419 while (!day && i < elements.length)
421 day = elements[i].day;
426 && day.substr(0, 6) == currentDay.substr(0, 6)) {
427 for (i = 0; i < elements.length; i++) {
428 day = elements[i].day;
429 if (day && day == currentDay) {
430 var td = $(elements[i]).getParentWithTagName("td");
431 if (document.selectedDate)
432 document.selectedDate.deselect();
434 document.selectedDate = td;
440 function changeDateSelectorDisplay(day, keepCurrentDay) {
441 var url = ApplicationBaseURL + "/dateselector";
443 url += "?day=" + day;
445 if (day != currentDay) {
449 var month = day.substr(0, 6);
450 if (cachedDateSelectors[month]) {
451 // log ("restoring cached selector for month: " + month);
452 setDateSelectorContent(cachedDateSelectors[month]);
455 // log ("loading selector for month: " + month);
456 if (document.dateSelectorAjaxRequest) {
457 document.dateSelectorAjaxRequest.aborted = true;
458 document.dateSelectorAjaxRequest.abort();
460 document.dateSelectorAjaxRequest
461 = triggerAjaxRequest(url,
462 dateSelectorCallback,
468 function changeCalendarDisplay(time, newView) {
469 var url = ApplicationBaseURL + "/" + ((newView) ? newView : currentView);
471 selectedCalendarCell = null;
483 url += "?day=" + day;
486 // log ("switching to view: " + newView);
487 // log ("changeCalendarDisplay: " + url);
489 if (document.dayDisplayAjaxRequest) {
490 // log ("aborting day ajaxrq");
491 document.dayDisplayAjaxRequest.aborted = true;
492 document.dayDisplayAjaxRequest.abort();
494 document.dayDisplayAjaxRequest
495 = triggerAjaxRequest(url, calendarDisplayCallback,
496 { "view": newView, "day": day, "hour": hour });
501 function _ensureView(view) {
502 if (currentView != view)
503 changeCalendarDisplay(null, view);
508 function onDayOverview() {
509 return _ensureView("dayview");
512 function onMulticolumnDayOverview() {
513 return _ensureView("multicolumndayview");
516 function onWeekOverview() {
517 return _ensureView("weekview");
520 function onMonthOverview() {
521 return _ensureView("monthview");
524 function scrollDayView(hour) {
527 if (hour.length == 3)
528 rowNumber = parseInt(hour.substr(0, 1));
530 if (hour.substr(0, 1) == "0")
531 rowNumber = parseInt(hour.substr(1, 1));
533 rowNumber = parseInt(hour.substr(0, 2));
538 var daysView = $("daysView");
540 $(daysView.childNodesWithTag("div")[0]).childNodesWithTag("div");
541 if (hours.length > 0)
542 daysView.scrollTop = hours[rowNumber].offsetTop;
545 function onClickableCellsDblClick(event) {
546 newEvent(this, 'event');
548 event.cancelBubble = true;
549 event.returnValue = false;
552 function refreshCalendarEvents() {
553 var todayDate = new Date();
556 if (currentView == "dayview") {
560 sd = todayDate.getDayString();
563 else if (currentView == "weekview") {
566 startDate = currentDay.asDate();
568 startDate = todayDate;
569 startDate = startDate.beginOfWeek();
570 sd = startDate.getDayString();
571 var endDate = new Date();
572 endDate.setTime(startDate.getTime());
574 ed = endDate.getDayString();
579 monthDate = currentDay.asDate();
581 monthDate = todayDate;
582 monthDate.setDate(1);
583 sd = monthDate.beginOfWeek().getDayString();
585 var lastMonthDate = new Date();
586 lastMonthDate.setTime(monthDate.getTime());
587 lastMonthDate.setMonth(monthDate.getMonth() + 1);
588 lastMonthDate.addDays(-1);
589 ed = lastMonthDate.endOfWeek().getDayString();
591 if (document.refreshCalendarEventsAjaxRequest) {
592 document.refreshCalendarEventsAjaxRequest.aborted = true;
593 document.refreshCalendarEventsAjaxRequest.abort();
595 var url = ApplicationBaseURL + "/eventslist?sd=" + sd + "&ed=" + ed;
596 document.refreshCalendarEventsAjaxRequest
597 = triggerAjaxRequest(url, refreshCalendarEventsCallback,
598 {"startDate": sd, "endDate": ed});
601 function refreshCalendarEventsCallback(http) {
602 if (http.readyState == 4
603 && http.status == 200) {
604 var data = http.responseText.evalJSON(true);
605 // log("refresh calendar events: " + data.length);
606 for (var i = 0; i < data.length; i++)
607 drawCalendarEvent(data[i],
608 http.callbackData["startDate"],
609 http.callbackData["endDate"]);
612 log("AJAX error when refreshing calendar events");
615 function drawCalendarEvent(eventData, sd, ed) {
616 var viewStartDate = sd.asDate();
617 var viewEndDate = ed.asDate();
619 var startDate = new Date();
620 startDate.setTime(eventData[4] * 1000);
621 var endDate = new Date();
622 endDate.setTime(eventData[5] * 1000);
624 // log ("s: " + startDate + "; e: " + endDate);
626 var days = startDate.daysUpTo(endDate);
628 var divs = new Array();
631 if (currentView == "monthview"
632 && (eventData[7] == 0))
633 title = startDate.getDisplayHoursString() + " " + eventData[3];
635 title = eventData[3];
637 // log("title: " + title);
638 // log("viewS: " + viewStartDate);
639 var startHour = null;
642 var siblings = new Array();
643 for (var i = 0; i < days.length; i++)
644 if (days[i].earlierDate(viewStartDate) == viewStartDate
645 && days[i].laterDate(viewEndDate) == viewEndDate) {
648 // log("day: " + days[i]);
650 var quarters = (startDate.getUTCHours() * 4
651 + Math.floor(startDate.getUTCMinutes() / 15));
653 startHour = startDate.getDisplayHoursString();
654 endHour = endDate.getDisplayHoursString();
661 if (i == days.length - 1) {
662 var quarters = (endDate.getUTCHours() * 4
663 + Math.ceil(endDate.getUTCMinutes() / 15));
668 lasts = ends - starts;
672 var eventDiv = newEventDIV(eventData[0], eventData[1], starts, lasts,
674 siblings.push(eventDiv);
675 eventDiv.siblings = siblings;
676 var dayString = days[i].getDayString();
677 // log("day: " + dayString);
678 var parentDiv = null;
679 if (currentView == "monthview") {
680 var dayDivs = $("monthDaysView").childNodesWithTag("div");
682 while (!parentDiv && j < dayDivs.length) {
683 if (dayDivs[j].getAttribute("day") == dayString)
684 parentDiv = dayDivs[j];
690 if (eventData[7] == 0) {
691 var daysView = $("daysView");
692 var eventsDiv = $(daysView).childNodesWithTag("div")[1];
693 var dayDivs = $(eventsDiv).childNodesWithTag("div");
695 while (!parentDiv && j < dayDivs.length) {
696 if (dayDivs[j].getAttribute("day") == dayString)
697 parentDiv = dayDivs[j].childNodesWithTag("div")[0];
703 var header = $("calendarHeader");
704 var daysDiv = $(header).childNodesWithTag("div")[1];
705 var dayDivs = $(daysDiv).childNodesWithTag("div");
707 while (!parentDiv && j < dayDivs.length) {
708 if (dayDivs[j].getAttribute("day") == dayString)
709 parentDiv = dayDivs[j];
716 parentDiv.appendChild(eventDiv);
720 function newEventDIV(cname, calendar, starts, lasts,
721 startHour, endHour, title) {
722 var eventDiv = document.createElement("div");
723 eventDiv.cname = escape(cname);
724 eventDiv.calendar = calendar;
725 $(eventDiv).addClassName("event");
726 $(eventDiv).addClassName("starts" + starts);
727 $(eventDiv).addClassName("lasts" + lasts);
728 for (var i = 1; i < 5; i++) {
729 var shadowDiv = document.createElement("div");
730 eventDiv.appendChild(shadowDiv);
731 $(shadowDiv).addClassName("shadow");
732 $(shadowDiv).addClassName("shadow" + i);
734 var innerDiv = document.createElement("div");
735 eventDiv.appendChild(innerDiv);
736 $(innerDiv).addClassName("eventInside");
737 $(innerDiv).addClassName("calendarFolder" + calendar);
739 var gradientDiv = document.createElement("div");
740 innerDiv.appendChild(gradientDiv);
741 $(gradientDiv).addClassName("gradient");
742 var gradientImg = document.createElement("img");
743 gradientDiv.appendChild(gradientImg);
744 gradientImg.src = ResourcesURL + "/event-gradient.png";
746 var textDiv = document.createElement("div");
747 innerDiv.appendChild(textDiv);
748 $(textDiv).addClassName("text");
750 var headerSpan = document.createElement("span");
751 textDiv.appendChild(headerSpan);
752 $(headerSpan).addClassName("eventHeader");
753 headerSpan.appendChild(document.createTextNode(startHour + " - "
755 textDiv.appendChild(document.createElement("br"));
757 textDiv.appendChild(document.createTextNode(title));
759 Event.observe(eventDiv, "mousedown", listRowMouseDownHandler);
760 Event.observe(eventDiv, "click",
761 onCalendarSelectEvent.bindAsEventListener(eventDiv));
762 Event.observe(eventDiv, "dblclick",
763 editDoubleClickedEvent.bindAsEventListener(eventDiv));
768 function calendarDisplayCallback(http) {
769 var div = $("calendarView");
771 if (http.readyState == 4
772 && http.status == 200) {
773 document.dayDisplayAjaxRequest = null;
774 div.update(http.responseText);
775 if (http.callbackData["view"])
776 currentView = http.callbackData["view"];
777 if (http.callbackData["day"])
778 currentDay = http.callbackData["day"];
781 if (http.callbackData["hour"])
782 hour = http.callbackData["hour"];
784 if (currentView == "monthview")
785 contentView = $("calendarContent");
788 contentView = $("daysView");
790 refreshCalendarEvents();
791 var days = document.getElementsByClassName("day", contentView);
792 if (currentView == "monthview")
793 for (var i = 0; i < days.length; i++) {
794 Event.observe(days[i], "click", onCalendarSelectDay.bindAsEventListener(days[i]));
795 Event.observe(days[i], "dblclick", onClickableCellsDblClick.bindAsEventListener(days[i]));
798 var headerDivs = $("calendarHeader").childNodesWithTag("div");
799 var headerDaysLabels = document.getElementsByClassName("day", headerDivs[0]);
800 var headerDays = document.getElementsByClassName("day", headerDivs[1]);
801 for (var i = 0; i < days.length; i++) {
802 headerDays[i].hour = "allday";
803 Event.observe(headerDaysLabels[i], "mousedown", listRowMouseDownHandler);
804 Event.observe(headerDays[i], "click",
805 onCalendarSelectDay.bindAsEventListener(days[i]));
806 Event.observe(headerDays[i], "dblclick",
807 onClickableCellsDblClick.bindAsEventListener(headerDays[i]));
808 Event.observe(days[i], "click",
809 onCalendarSelectDay.bindAsEventListener(days[i]));
810 var clickableCells = document.getElementsByClassName("clickableHourCell",
812 for (var j = 0; j < clickableCells.length; j++)
813 Event.observe(clickableCells[j], "dblclick",
814 onClickableCellsDblClick.bindAsEventListener(clickableCells[j]));
819 log ("calendarDisplayCallback Ajax error (" + http.readyState + "/" + http.status + ")");
822 function assignCalendar(name) {
823 if (typeof(skycalendar) != "undefined") {
826 node.calendar = new skycalendar(node);
827 node.calendar.setCalendarPage(ResourcesURL + "/skycalendar.html");
828 var dateFormat = node.getAttribute("dateFormat");
830 node.calendar.setDateFormat(dateFormat);
834 function popupCalendar(node) {
835 var nodeId = node.getAttribute("inputId");
836 var input = $(nodeId);
837 input.calendar.popup();
842 function onEventContextMenu(event) {
843 var topNode = $("eventsList");
846 var menu = $("eventsListMenu");
848 Event.observe(menu, "hideMenu", onEventContextMenuHide);
849 popupMenu(event, "eventsListMenu", this);
851 var topNode = $("eventsList");
852 var selectedNodes = topNode.getSelectedRows();
853 topNode.menuSelectedRows = selectedNodes;
854 for (var i = 0; i < selectedNodes.length; i++)
855 selectedNodes[i].deselect();
857 topNode.menuSelectedEntry = this;
861 function onEventContextMenuHide(event) {
862 var topNode = $("eventsList");
864 if (topNode.menuSelectedEntry) {
865 topNode.menuSelectedEntry.deselect();
866 topNode.menuSelectedEntry = null;
868 if (topNode.menuSelectedRows) {
869 var nodeIds = topNode.menuSelectedRows;
870 for (var i = 0; i < nodeIds.length; i++) {
871 var node = $(nodeIds[i]);
874 topNode.menuSelectedRows = null;
878 function onEventsSelectionChange() {
879 listOfSelection = this;
880 this.removeClassName("_unfocused");
881 $("tasksList").addClassName("_unfocused");
884 function onTasksSelectionChange() {
885 listOfSelection = this;
886 this.removeClassName("_unfocused");
887 $("eventsList").addClassName("_unfocused");
890 function _loadEventHref(href) {
891 if (document.eventsListAjaxRequest) {
892 document.eventsListAjaxRequest.aborted = true;
893 document.eventsListAjaxRequest.abort();
895 var url = ApplicationBaseURL + "/" + href;
896 document.eventsListAjaxRequest
897 = triggerAjaxRequest(url, eventsListCallback, href);
899 var table = $("eventsList").tBodies[0];
900 while (table.rows.length > 0)
901 table.removeChild(table.rows[0]);
906 function _loadTasksHref(href) {
907 if (document.tasksListAjaxRequest) {
908 document.tasksListAjaxRequest.aborted = true;
909 document.tasksListAjaxRequest.abort();
911 url = ApplicationBaseURL + "/" + href;
913 var tasksList = $("tasksList");
916 selectedIds = tasksList.getSelectedNodesId();
919 document.tasksListAjaxRequest
920 = triggerAjaxRequest(url, tasksListCallback, selectedIds);
922 tasksList.previousScroll = tasksList.scrollTop;
923 while (tasksList.childNodes.length)
924 tasksList.removeChild(tasksList.childNodes[0]);
929 function onHeaderClick(event) {
930 //log("onHeaderClick: " + this.link);
931 //_loadEventHref(this.link);
933 preventDefault(event);
936 function refreshEvents() {
937 return _loadEventHref("eventslist?desc=" + sortOrder
939 + "&day=" + currentDay
940 + "&filterpopup=" + listFilter);
943 function refreshTasks() {
944 return _loadTasksHref("taskslist?show-completed=" + showCompletedTasks);
947 function refreshEventsAndDisplay() {
949 changeCalendarDisplay();
952 function onListFilterChange() {
953 var node = $("filterpopup");
955 listFilter = node.value;
956 // log ("listFilter = " + listFilter);
958 return refreshEvents();
961 function onEventClick(event) { log ("onEventClick");
963 var hour = this.hour;
965 changeCalendarDisplay( { "day": day, "hour": hour} );
966 changeDateSelectorDisplay(day);
968 return onRowClick(event);
971 function selectMonthInMenu(menu, month) {
972 var entries = menu.childNodes[1].childNodesWithTag("LI");
973 for (i = 0; i < entries.length; i++) {
974 var entry = entries[i];
975 var entryMonth = entry.getAttribute("month");
976 if (entryMonth == month)
977 entry.addClassName("currentMonth");
979 entry.removeClassName("currentMonth");
983 function selectYearInMenu(menu, month) {
984 var entries = menu.childNodes[1].childNodes;
985 for (i = 0; i < entries.length; i++) {
986 var entry = entries[i];
987 if (entry.tagName == "LI") {
988 var entryMonth = entry.innerHTML;
989 if (entryMonth == month)
990 entry.addClassName("currentMonth");
992 entry.removeClassName("currentMonth");
997 function popupMonthMenu(event) {
998 if (event.button == 0) {
999 var id = this.getAttribute("id");
1000 if (id == "monthLabel")
1001 menuId = "monthListMenu";
1003 menuId = "yearListMenu";
1005 var popup = $(menuId);
1006 if (id == "monthLabel")
1007 selectMonthInMenu(popup, this.getAttribute("month"));
1009 selectYearInMenu(popup, this.innerHTML);
1011 popupToolbarMenu(this, menuId);
1016 function onMonthMenuItemClick(event) {
1017 var month = '' + this.getAttribute("month");
1018 var year = '' + $("yearLabel").innerHTML;
1020 changeDateSelectorDisplay(year + month + "01", true);
1023 function onYearMenuItemClick(event) {
1024 var month = '' + $("monthLabel").getAttribute("month");;
1025 var year = '' + this.innerHTML;
1027 changeDateSelectorDisplay(year + month + "01", true);
1030 function onSearchFormSubmit() {
1031 log ("search not implemented");
1036 function onCalendarSelectEvent() {
1037 var list = $("eventsList");
1038 $(list.tBodies[0]).deselectAll();
1040 if (selectedCalendarCell)
1041 for (var i = 0; i < selectedCalendarCell.length; i++)
1042 selectedCalendarCell[i].deselect();
1044 for (var i = 0; i < this.siblings.length; i++)
1045 this.siblings[i].select();
1046 selectedCalendarCell = this.siblings;
1047 var row = $(this.cname);
1049 var div = row.parentNode.parentNode.parentNode;
1050 div.scrollTop = row.offsetTop - (div.offsetHeight / 2);
1055 function onCalendarSelectDay(event) {
1057 if (currentView == "multicolumndayview")
1058 day = this.getAttribute("day");
1060 day = this.getAttribute("day");
1061 var needRefresh = (listFilter == 'view_selectedday'
1062 && day != currentDay);
1064 if (currentView == 'weekview')
1065 changeWeekCalendarDisplayOfSelectedDay(this);
1066 else if (currentView == 'monthview')
1067 changeMonthCalendarDisplayOfSelectedDay(this);
1068 changeDateSelectorDisplay(day);
1070 if (listOfSelection) {
1071 listOfSelection.addClassName("_unfocused");
1072 listOfSelection = null;
1079 function changeWeekCalendarDisplayOfSelectedDay(node) {
1080 var days = document.getElementsByClassName("day", node.parentNode);
1081 var headerDiv = $("calendarHeader").childNodesWithTag("div")[1];
1082 var headerDays = document.getElementsByClassName("day", headerDiv);
1084 // log ("days: " + days.length + "; headerDays: " + headerDays.length);
1085 for (var i = 0; i < days.length; i++)
1086 if (days[i] != node) {
1087 // log("unselect day : " + i);
1088 headerDays[i].removeClassName("selectedDay");
1089 days[i].removeClassName("selectedDay");
1092 // log("selected day : " + i);
1093 headerDays[i].addClassName("selectedDay");
1094 days[i].addClassName("selectedDay");
1098 function findMonthCalendarSelectedCell(daysContainer) {
1102 while (!found && i < daysContainer.childNodes.length) {
1103 var currentNode = daysContainer.childNodes[i];
1104 if (currentNode.tagName == 'DIV'
1105 && currentNode.hasClassName("selectedDay")) {
1106 daysContainer.selectedCell = currentNode;
1114 function changeMonthCalendarDisplayOfSelectedDay(node) {
1115 var daysContainer = node.parentNode;
1116 if (!daysContainer.selectedCell)
1117 findMonthCalendarSelectedCell(daysContainer);
1119 if (daysContainer.selectedCell)
1120 daysContainer.selectedCell.removeClassName("selectedDay");
1121 daysContainer.selectedCell = node;
1122 node.addClassName("selectedDay");
1125 function onShowCompletedTasks(event) {
1126 showCompletedTasks = (this.checked ? 1 : 0);
1128 return refreshTasks();
1131 function updateTaskStatus(event) {
1132 var taskId = this.parentNode.getAttribute("id");
1133 var newStatus = (this.checked ? 1 : 0);
1134 var http = createHTTPClient();
1136 if (isSafari() && !isSafari3()) {
1137 newStatus = (newStatus ? 0 : 1);
1140 url = (ApplicationBaseURL + "/" + this.parentNode.calendar
1141 + "/" + taskId + "/changeStatus?status=" + newStatus);
1144 // TODO: add parameter to signal that we are only interested in OK
1145 http.open("POST", url, false /* not async */);
1148 if (http.status == 200)
1151 log ("no http client?");
1156 function updateCalendarStatus(event) {
1157 var list = new Array();
1158 var newStatus = (this.checked ? 1 : 0);
1160 if (isSafari() && !isSafari3()) {
1161 newStatus = (newStatus ? 0 : 1);
1162 this.checked = newStatus;
1165 var nodes = $("calendarList").childNodesWithTag("li");
1166 for (var i = 0; i < nodes.length; i++) {
1167 var input = $(nodes[i]).childNodesWithTag("input")[0];
1168 if (input.checked) {
1169 var folderId = nodes[i].getAttribute("id");
1170 var elems = folderId.split(":");
1171 if (elems.length > 1)
1172 list.push(elems[0]);
1174 list.push(UserLogin);
1178 // if (!list.length) {
1179 // list.push(UserLogin);
1180 // nodes[0].childNodesWithTag("input")[0].checked = true;
1183 // ApplicationBaseURL = (UserFolderURL + "Groups/_custom_"
1184 // + list.join(",") + "/Calendar/");
1187 var folderID = this.parentNode.getAttribute("id");
1188 var urlstr = URLForFolderID(folderID);
1190 urlstr += "/activateFolder";
1192 urlstr += "/deactivateFolder";
1193 //log("updateCalendarStatus: ajax request = " + urlstr + ", folderID = " + folderID);
1194 triggerAjaxRequest(urlstr, calendarStatusCallback, folderID);
1197 updateCalendarsList();
1200 changeCalendarDisplay();
1206 function calendarStatusCallback(http) {
1207 if (http.readyState == 4) {
1208 if (isHttpStatus204(http.status)) {
1211 changeCalendarDisplay();
1214 var folder = $(http.callbackData);
1215 var input = folder.childNodesWithTag("input")[0];
1216 input.checked = (!input.checked);
1220 log("calendarStatusCallback Ajax error");
1223 function calendarEntryCallback(http) {
1224 if (http.readyState == 4) {
1225 var denied = !isHttpStatus204(http.status);
1226 var entry = $(http.callbackData);
1228 entry.addClassName("denied");
1230 entry.removeClassName("denied");
1234 function updateCalendarsList(method) {
1235 var list = $("calendarList").childNodesWithTag("li");
1236 for (var i = 0; i < list.length; i++) {
1237 var folderID = list[i].getAttribute("id");
1238 var url = URLForFolderID(folderID) + "/canAccessContent";
1239 triggerAjaxRequest(url, calendarEntryCallback, folderID);
1243 function addContact(tag, fullContactName, contactId, contactName, contactEmail) {
1244 var uids = $("uixselector-calendarsList-uidList");
1245 // log("addContact");
1248 var re = new RegExp("(^|,)" + contactId + "($|,)");
1250 if (!re.test(uids.value))
1252 if (uids.value.length > 0)
1253 uids.value += ',' + contactId;
1255 uids.value = contactId;
1256 var names = $("calendarList");
1257 var listElems = names.childNodesWithTag("li");
1258 var colorDef = indexColor(listElems.length);
1259 names.appendChild(userCalendarEntry(contactId, colorDef));
1267 function validateBrowseURL(input) {
1268 var button = $("browseURLBtn");
1270 if (input.value.length) {
1271 if (!button.enabled)
1272 enableAnchor(button);
1273 } else if (!button.disabled)
1274 disableAnchor(button);
1277 function browseURL(anchor, event) {
1278 if (event.button == 0) {
1279 var input = $("url");
1280 var url = input.value;
1282 window.open(url, '_blank');
1288 function getMenus() {
1291 var dateMenu = new Array();
1292 for (var i = 0; i < 12; i++)
1293 dateMenu.push(onMonthMenuItemClick);
1294 menus["monthListMenu"] = dateMenu;
1296 dateMenu = new Array();
1297 for (var i = 0; i < 11; i++)
1298 dateMenu.push(onYearMenuItemClick);
1299 menus["yearListMenu"] = dateMenu;
1301 menus["eventsListMenu"] = new Array(onMenuNewEventClick, "-",
1303 editEvent, deleteEvent, "-",
1306 menus["calendarsMenu"] = new Array(onMenuModify,
1308 onCalendarNew, onCalendarRemove,
1309 "-", null, null, "-",
1310 null, "-", onMenuSharing);
1311 menus["searchMenu"] = new Array(setSearchCriteria);
1316 function onMenuSharing(event) {
1317 var folders = $("calendarList");
1318 var selected = folders.getSelectedNodes()[0];
1319 /* FIXME: activation of the context menu should preferable select the entry
1320 above which the event has occured */
1322 var folderID = selected.getAttribute("id");
1323 var urlstr = URLForFolderID(folderID) + "/acls";
1325 openAclWindow(urlstr);
1329 function configureDragHandles() {
1330 var handle = $("verticalDragHandle");
1332 handle.addInterface(SOGoDragHandlesInterface);
1333 handle.leftBlock=$("leftPanel");
1334 handle.rightBlock=$("rightPanel");
1337 handle = $("rightDragHandle");
1339 handle.addInterface(SOGoDragHandlesInterface);
1340 handle.upperBlock=$("eventsListView");
1341 handle.lowerBlock=$("calendarView");
1345 function initCalendarSelector() {
1346 var selector = $("calendarSelector");
1347 updateCalendarStatus();
1348 selector.changeNotification = updateCalendarsList;
1350 var list = $("calendarList");
1351 list.multiselect = true;
1352 var items = list.childNodesWithTag("li");
1353 for (var i = 0; i < items.length; i++) {
1354 var input = items[i].childNodesWithTag("input")[0];
1355 Event.observe(input, "click", updateCalendarStatus.bindAsEventListener(input));
1356 Event.observe(items[i], "mousedown", listRowMouseDownHandler);
1357 Event.observe(items[i], "selectstart", listRowMouseDownHandler);
1358 Event.observe(items[i], "click", onRowClick);
1361 var links = $("calendarSelectorButtons").childNodesWithTag("a");
1362 Event.observe(links[0], "click", onCalendarNew);
1363 Event.observe(links[1], "click", onCalendarAdd);
1364 Event.observe(links[2], "click", onCalendarRemove);
1367 function onMenuModify(event) {
1368 var folders = $("calendarList");
1369 var selected = folders.getSelectedNodes()[0];
1371 if (UserLogin == selected.getAttribute("owner")) {
1372 var node = selected.childNodes[4];
1373 var currentName = node.nodeValue.trim();
1374 var newName = window.prompt(labels["Name of the Calendar"],
1376 if (newName && newName.length > 0
1377 && newName != currentName) {
1378 var url = (URLForFolderID(selected.getAttribute("id"))
1379 + "/renameFolder?name=" + escape(newName.utf8encode()));
1380 triggerAjaxRequest(url, folderRenameCallback,
1381 {node: node, name: " " + newName});
1384 window.alert(clabels["Unable to rename that folder!"]);
1387 function folderRenameCallback(http) {
1388 if (http.readyState == 4) {
1389 if (isHttpStatus204(http.status)) {
1390 var dict = http.callbackData;
1391 dict["node"].nodeValue = dict["name"];
1396 function onCalendarNew(event) {
1397 createFolder(window.prompt(labels["Name of the Calendar"]),
1399 preventDefault(event);
1402 function onCalendarAdd(event) {
1403 openUserFolderSelector(onFolderSubscribeCB, "calendar");
1404 preventDefault(event);
1407 function appendCalendar(folderName, folderPath) {
1411 owner = getSubscribedFolderOwner(folderPath);
1412 folderPath = accessToSubscribedFolder(folderPath);
1415 folderPath = "/" + folderName;
1420 //log ("append name: " + folderName + "; path: " + folderPath + "; owner: " + owner);
1423 window.alert(clabels["You have already subscribed to that folder!"]);
1425 var calendarList = $("calendarList");
1426 var lis = calendarList.childNodesWithTag("li");
1427 var color = indexColor(lis.length + 100);
1428 //log ("color: " + color);
1430 var li = document.createElement("li");
1432 // Add the calendar to the proper place
1433 var previousOwner = null;
1434 for (var i = 1; i < lis.length; i++) {
1435 var currentFolderName = lis[i].lastChild.nodeValue.strip();
1436 var currentOwner = lis[i].readAttribute('owner');
1437 if (currentOwner == owner) {
1438 previousOwner = currentOwner;
1439 if (currentFolderName > folderName)
1442 else if (previousOwner ||
1443 (currentOwner != UserLogin && currentOwner > owner))
1446 if (i != lis.length) // User is subscribed to other calendars of the same owner
1447 calendarList.insertBefore(li, lis[i]);
1449 calendarList.appendChild(li);
1451 li.setAttribute("id", folderPath);
1452 li.setAttribute("owner", owner);
1454 var checkBox = document.createElement("input");
1455 checkBox.setAttribute("type", "checkbox");
1456 li.appendChild(checkBox);
1457 li.appendChild(document.createTextNode(" "));
1458 $(checkBox).addClassName("checkBox");
1460 var colorBox = document.createElement("div");
1461 li.appendChild(colorBox);
1462 li.appendChild(document.createTextNode(folderName));
1463 colorBox.appendChild(document.createTextNode("OO"));
1465 $(colorBox).addClassName("colorBox");
1466 $(colorBox).addClassName('calendarFolder' + folderPath.substr(1));
1468 // Register events (doesn't work with Safari)
1469 Event.observe(li, "mousedown", listRowMouseDownHandler);
1470 Event.observe(li, "selectstart", listRowMouseDownHandler);
1471 Event.observe(li, "click", onRowClick);
1472 Event.observe(checkBox, "click",
1473 updateCalendarStatus.bindAsEventListener(checkBox));
1475 var url = URLForFolderID(folderPath) + "/canAccessContent";
1476 triggerAjaxRequest(url, calendarEntryCallback, folderPath);
1478 // Update CSS for events color
1479 if (!document.styleSheets) return;
1480 var theRules = new Array();
1481 var lastSheet = document.styleSheets[document.styleSheets.length - 1];
1482 if (lastSheet.insertRule) { // Mozilla
1483 lastSheet.insertRule('.calendarFolder' + folderPath.substr(1) + ' {'
1484 + ' background-color: '
1486 + ' !important; }', 0);
1487 lastSheet.insertRule('div.colorBox.calendarFolder' + folderPath.substr(1) + ' {'
1490 + ' !important; }', 0);
1493 lastSheet.addRule('.calendarFolder' + folderPath.substr(1),
1494 ' background-color: '
1496 + ' !important; }');
1497 lastSheet.addRule('div.colorBox.calendarFolder' + folderPath.substr(1),
1500 + ' !important; }');
1505 function onFolderSubscribeCB(folderData) {
1506 var folder = $(folderData["folder"]);
1508 appendCalendar(folderData["folderName"], folderData["folder"]);
1511 function onFolderUnsubscribeCB(folderId) {
1512 var node = $(folderId);
1513 node.parentNode.removeChild(node);
1514 if (removeFolderRequestCount == 0) {
1517 changeCalendarDisplay();
1521 function onCalendarRemove(event) {
1522 if (removeFolderRequestCount == 0) {
1523 var nodes = $("calendarList").getSelectedNodes();
1524 for (var i = 0; i < nodes.length; i++) {
1525 nodes[i].deselect();
1526 var folderId = nodes[i].getAttribute("id");
1527 var folderIdElements = folderId.split("_");
1528 if (folderIdElements.length > 1) {
1529 unsubscribeFromFolder(folderId, onFolderUnsubscribeCB, folderId);
1532 deletePersonalCalendar(folderIdElements[0]);
1536 preventDefault(event);
1539 function deletePersonalCalendar(folderElement) {
1540 var folderId = folderElement.substr(1);
1542 = labels["Are you sure you want to delete the calendar \"%{0}\"?"].formatted($(folderElement).lastChild.nodeValue.strip());
1543 if (window.confirm(label)) {
1544 removeFolderRequestCount++;
1545 var url = ApplicationBaseURL + "/" + folderId + "/deleteFolder";
1546 triggerAjaxRequest(url, deletePersonalCalendarCallback, folderId);
1550 function deletePersonalCalendarCallback(http) {
1551 if (http.readyState == 4) {
1552 if (isHttpStatus204(http.status)) {
1553 var ul = $("calendarList");
1554 var children = ul.childNodesWithTag("li");
1557 while (!done && i < children.length) {
1558 var currentFolderId = children[i].getAttribute("id").substr(1);
1559 if (currentFolderId == http.callbackData) {
1560 ul.removeChild(children[i]);
1566 removeFolderRequestCount--;
1567 if (removeFolderRequestCount == 0) {
1570 changeCalendarDisplay();
1575 log ("ajax problem 5: " + http.status);
1578 function configureLists() {
1579 var list = $("tasksList");
1580 list.multiselect = true;
1581 Event.observe(list, "mousedown",
1582 onTasksSelectionChange.bindAsEventListener(list));
1584 var input = $("showHideCompletedTasks");
1585 Event.observe(input, "click",
1586 onShowCompletedTasks.bindAsEventListener(input));
1588 list = $("eventsList");
1589 list.multiselect = true;
1590 //configureSortableTableHeaders(list);
1591 TableKit.Resizable.init(list, {'trueResize' : true, 'keepWidth' : true});
1592 Event.observe(list, "mousedown",
1593 onEventsSelectionChange.bindAsEventListener(list));
1594 var div = list.parentNode;
1595 Event.observe(div, "contextmenu",
1596 onEventContextMenu.bindAsEventListener(div));
1599 function initDateSelectorEvents() {
1600 var arrow = $("rightArrow");
1601 Event.observe(arrow, "click",
1602 onDateSelectorGotoMonth.bindAsEventListener(arrow));
1603 arrow = $("leftArrow");
1604 Event.observe(arrow, "click",
1605 onDateSelectorGotoMonth.bindAsEventListener(arrow));
1607 var menuButton = $("monthLabel");
1608 Event.observe(menuButton, "click",
1609 popupMonthMenu.bindAsEventListener(menuButton));
1610 menuButton = $("yearLabel");
1611 Event.observe(menuButton, "click",
1612 popupMonthMenu.bindAsEventListener(menuButton));
1615 function initCalendars() {
1616 if (!document.body.hasClassName("popup")) {
1617 initDateSelectorEvents();
1618 initCalendarSelector();
1619 configureSearchField();
1621 var selector = $("calendarSelector");
1623 selector.attachMenu("calendarsMenu");
1627 addEvent(window, 'load', initCalendars);