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) {
26 var day = sender.getAttribute("day");
31 if (sender.parentNode.getAttribute("id") != "toolbar"
32 && currentView == "multicolumndayview" && type == "event")
33 user = sender.parentNode.parentNode.getAttribute("user");
35 var hour = sender.getAttribute("hour");
36 var urlstr = UserFolderURL + "../" + user + "/Calendar/new" + type;
37 var params = new Array();
39 params.push("day=" + day);
41 params.push("hm=" + hour);
42 if (params.length > 0)
43 urlstr += "?" + params.join("&");
45 window.open(urlstr, "", "width=490,height=470,resizable=0");
47 return false; /* stop following the link */
50 function onMenuNewEventClick(event) {
51 newEvent(this, "event");
54 function onMenuNewTaskClick(event) {
55 newEvent(this, "task");
58 function _editEventId(id, owner) {
61 urlBase = UserFolderURL + "../" + owner + "/";
62 urlBase += "Calendar/"
64 var urlstr = urlBase + id + "/edit";
66 var win = window.open(urlstr, "SOGo_edit_" + id,
67 "width=490,height=470,resizable=0");
71 function editEvent() {
72 if (listOfSelection) {
73 var nodes = listOfSelection.getSelectedRows();
75 for (var i = 0; i < nodes.length; i++)
76 _editEventId(nodes[i].getAttribute("id"),
77 nodes[i].getAttribute("owner"));
78 } else if (selectedCalendarCell) {
79 _editEventId(selectedCalendarCell.getAttribute("aptCName"),
80 selectedCalendarCell.getAttribute("owner"));
83 return false; /* stop following the link */
86 function _batchDeleteEvents() {
87 var events = eventsToDelete.shift();
88 var owner = ownersOfEventsToDelete.shift();
89 var urlstr = (UserFolderURL + "../" + owner + "/Calendar/batchDelete?ids="
91 document.deleteEventAjaxRequest = triggerAjaxRequest(urlstr,
96 function deleteEvent() {
97 if (listOfSelection) {
98 var nodes = listOfSelection.getSelectedRows();
100 if (nodes.length > 0) {
102 if (listOfSelection == $("tasksList"))
103 label = labels["taskDeleteConfirmation"].decodeEntities();
105 label = labels["appointmentDeleteConfirmation"].decodeEntities();
107 if (confirm(label)) {
108 if (document.deleteEventAjaxRequest) {
109 document.deleteEventAjaxRequest.aborted = true;
110 document.deleteEventAjaxRequest.abort();
112 var sortedNodes = new Array();
113 var owners = new Array();
115 for (var i = 0; i < nodes.length; i++) {
116 var owner = nodes[i].getAttribute("owner");
117 if (!sortedNodes[owner]) {
118 sortedNodes[owner] = new Array();
121 sortedNodes[owner].push(nodes[i].getAttribute("id"));
123 for (var i = 0; i < owners.length; i++) {
124 ownersOfEventsToDelete.push(owners[i]);
125 eventsToDelete.push(sortedNodes[owners[i]]);
127 _batchDeleteEvents();
131 else if (selectedCalendarCell) {
132 var label = labels["appointmentDeleteConfirmation"].decodeEntities();
133 if (confirm(label)) {
134 if (document.deleteEventAjaxRequest) {
135 document.deleteEventAjaxRequest.aborted = true;
136 document.deleteEventAjaxRequest.abort();
138 eventsToDelete.push([selectedCalendarCell.getAttribute("aptCName")]);
139 ownersOfEventsToDelete.push(selectedCalendarCell.getAttribute("owner"));
140 _batchDeleteEvents();
144 window.alert("no selection");
149 function modifyEvent(sender, modification) {
150 var currentLocation = '' + window.location;
151 var arr = currentLocation.split("/");
152 arr[arr.length-1] = modification;
154 document.modifyEventAjaxRequest = triggerAjaxRequest(arr.join("/"),
161 function closeInvitationWindow() {
162 var closeDiv = document.createElement("div");
163 closeDiv.addClassName("javascriptPopupBackground");
164 var closePseudoWin = document.createElement("div");
165 closePseudoWin.addClassName("javascriptMessagePseudoWindow");
166 closePseudoWin.style.top = "0px;";
167 closePseudoWin.style.left = "0px;";
168 closePseudoWin.style.right = "0px;";
169 closePseudoWin.appendChild(document.createTextNode(labels["closeThisWindowMessage"].decodeEntities()));
170 document.body.appendChild(closeDiv);
171 document.body.appendChild(closePseudoWin);
174 function modifyEventCallback(http) {
175 if (http.readyState == 4) {
176 if (http.status == 200) {
177 log("closing window...?");
178 if (queryParameters["mail-invitation"] == "yes")
179 closeInvitationWindow();
181 window.opener.setTimeout("refreshAppointmentsAndDisplay();", 100);
182 window.setTimeout("window.close();", 100);
186 log("showing alert...");
187 window.alert(labels["eventPartStatModificationError"]);
189 document.modifyEventAjaxRequest = null;
193 function deleteEventCallback(http) {
194 if (http.readyState == 4
195 && http.status == 200) {
196 var nodes = http.callbackData;
197 for (var i = 0; i < nodes.length; i++) {
198 var node = $(nodes[i]);
200 node.parentNode.removeChild(node);
202 if (eventsToDelete.length)
203 _batchDeleteEvents();
205 document.deleteEventAjaxRequest = null;
206 refreshAppointments();
208 changeCalendarDisplay();
212 log ("ajax fuckage");
215 function editDoubleClickedEvent(node) {
216 _editEventId(node.getAttribute("id"),
217 node.getAttribute("owner"));
222 function onSelectAll() {
223 var list = $("appointmentsList");
224 list.selectRowsMatchingClass("appointmentRow");
229 function displayAppointment(event) {
230 _editEventId(this.getAttribute("aptCName"),
231 this.getAttribute("owner"));
233 preventDefault(event);
234 event.stopPropagation();
235 event.cancelBubble = true;
236 event.returnValue = false;
239 function onDaySelect(node) {
240 var day = node.getAttribute("day");
241 var needRefresh = (listFilter == 'view_selectedday'
242 && day != currentDay);
244 var td = node.getParentWithTagName("td");
245 var table = td.getParentWithTagName("table");
247 // log ("table.selected: " + table.selected);
249 if (document.selectedDate)
250 document.selectedDate.deselect();
253 document.selectedDate = td;
255 changeCalendarDisplay( { "day": day } );
257 refreshAppointments();
262 function onDateSelectorGotoMonth(node) {
263 var day = node.getAttribute("date");
265 changeDateSelectorDisplay(day, true);
270 function onCalendarGotoDay(node) {
271 var day = node.getAttribute("date");
273 changeDateSelectorDisplay(day);
274 changeCalendarDisplay( { "day": day } );
279 function gotoToday() {
280 changeDateSelectorDisplay('');
281 changeCalendarDisplay();
286 function setDateSelectorContent(content) {
287 var div = $("dateSelectorView");
289 div.innerHTML = content;
290 if (currentDay.length > 0)
291 restoreCurrentDaySelection(div);
294 function dateSelectorCallback(http) {
295 if (http.readyState == 4
296 && http.status == 200) {
297 document.dateSelectorAjaxRequest = null;
298 var content = http.responseText;
299 setDateSelectorContent(content);
300 cachedDateSelectors[http.callbackData] = content;
303 log ("ajax fuckage");
306 function appointmentsListCallback(http) {
307 var div = $("appointmentsListView");
309 if (http.readyState == 4
310 && http.status == 200) {
311 document.appointmentsListAjaxRequest = null;
312 div.innerHTML = http.responseText;
313 var params = parseQueryParameters(http.callbackData);
314 sortKey = params["sort"];
315 sortOrder = params["desc"];
316 var list = $("appointmentsList");
317 Event.observe(list, "selectionchange", onAppointmentsSelectionChange.bindAsEventListener(list), true);
318 configureSortableTableHeaders();
321 log ("ajax fuckage");
324 function tasksListCallback(http) {
325 var div = $("tasksListView");
327 if (http.readyState == 4
328 && http.status == 200) {
329 document.tasksListAjaxRequest = null;
330 var list = $("tasksList");
331 var scroll = list.scrollTop;
332 div.innerHTML = http.responseText;
333 list = $("tasksList");
334 Event.observe(list, "selectionchange", onTasksSelectionChange.bindAsEventListener(list), true);
335 list.scrollTop = scroll;
336 if (http.callbackData) {
337 var selectedNodesId = http.callbackData;
338 for (var i = 0; i < selectedNodesId.length; i++)
339 $(selectedNodesId[i]).select();
343 log ("ajax fuckage");
346 function restoreCurrentDaySelection(div) {
347 var elements = div.getElementsByTagName("a");
350 while (!day && i < elements.length)
352 day = elements[i].getAttribute("day");
357 && day.substr(0, 6) == currentDay.substr(0, 6)) {
358 for (i = 0; i < elements.length; i++) {
359 day = elements[i].getAttribute("day");
360 if (day && day == currentDay) {
361 var td = elements[i].getParentWithTagName("td");
362 if (document.selectedDate)
363 document.selectedDate.deselect();
365 document.selectedDate = td;
371 function changeDateSelectorDisplay(day, keepCurrentDay) {
372 var url = ApplicationBaseURL + "dateselector";
374 url += "?day=" + day;
376 if (day != currentDay) {
380 var month = day.substr(0, 6);
381 if (cachedDateSelectors[month]) {
382 // log ("restoring cached selector for month: " + month);
383 setDateSelectorContent(cachedDateSelectors[month]);
386 // log ("loading selector for month: " + month);
387 if (document.dateSelectorAjaxRequest) {
388 document.dateSelectorAjaxRequest.aborted = true;
389 document.dateSelectorAjaxRequest.abort();
391 document.dateSelectorAjaxRequest
392 = triggerAjaxRequest(url,
393 dateSelectorCallback,
399 function changeCalendarDisplay(time, newView) {
400 var url = ApplicationBaseURL + ((newView) ? newView : currentView);
402 selectedCalendarCell = null;
414 url += "?day=" + day;
417 // log ("switching to view: " + newView);
418 // log ("changeCalendarDisplay: " + url);
420 if (document.dayDisplayAjaxRequest) {
421 // log ("aborting day ajaxrq");
422 document.dayDisplayAjaxRequest.aborted = true;
423 document.dayDisplayAjaxRequest.abort();
425 document.dayDisplayAjaxRequest = triggerAjaxRequest(url,
426 calendarDisplayCallback,
434 function _ensureView(view) {
435 if (currentView != view)
436 changeCalendarDisplay(null, view);
441 function onDayOverview() {
442 return _ensureView("dayview");
445 function onMulticolumnDayOverview() {
446 return _ensureView("multicolumndayview");
449 function onWeekOverview() {
450 return _ensureView("weekview");
453 function onMonthOverview() {
454 return _ensureView("monthview");
457 function scrollDayView(hour) {
460 if (hour.length == 3)
461 rowNumber = parseInt(hour.substr(0, 1));
463 if (hour.substr(0, 1) == "0")
464 rowNumber = parseInt(hour.substr(1, 1));
466 rowNumber = parseInt(hour.substr(0, 2));
471 var daysView = $("daysView");
472 var hours = $(daysView.childNodesWithTag("div")[0]).childNodesWithTag("div");
473 if (hours.length > 0)
474 daysView.parentNode.scrollTop = hours[rowNumber + 1].offsetTop;
477 function onClickableCellsDblClick(event) {
478 newEvent(this, 'event');
480 event.cancelBubble = true;
481 event.returnValue = false;
484 function calendarDisplayCallback(http) {
485 var div = $("calendarView");
487 //log ("calendarDisplayCallback: " + div);
488 if (http.readyState == 4
489 && http.status == 200) {
490 document.dayDisplayAjaxRequest = null;
491 div.innerHTML = http.responseText;
492 if (http.callbackData["view"])
493 currentView = http.callbackData["view"];
494 if (http.callbackData["day"])
495 currentDay = http.callbackData["day"];
497 if (http.callbackData["hour"])
498 hour = http.callbackData["hour"];
500 if (currentView == "monthview")
501 contentView = $("calendarContent");
504 contentView = $("daysView");
506 var appointments = document.getElementsByClassName("appointment", contentView);
507 for (var i = 0; i < appointments.length; i++) {
508 Event.observe(appointments[i], "mousedown", listRowMouseDownHandler);
509 Event.observe(appointments[i], "click", onCalendarSelectAppointment.bindAsEventListener(appointments[i]));
510 Event.observe(appointments[i], "dblclick", displayAppointment.bindAsEventListener(appointments[i]));
512 var days = document.getElementsByClassName("day", contentView);
513 if (currentView == "monthview")
514 for (var i = 0; i < days.length; i++) {
515 Event.observe(days[i], "click", onCalendarSelectDay.bindAsEventListener(days[i]));
516 Event.observe(days[i], "dblclick", onClickableCellsDblClick.bindAsEventListener(days[i]));
519 for (var i = 0; i < days.length; i++) {
520 Event.observe(days[i], "click", onCalendarSelectDay.bindAsEventListener(days[i]));
521 var clickableCells = document.getElementsByClassName("clickableHourCell",
523 for (var j = 0; j < clickableCells.length; j++)
524 Event.observe(clickableCells[j], "dblclick", onClickableCellsDblClick.bindAsEventListener(clickableCells[j]));
529 log ("ajax fuckage");
532 function assignCalendar(name) {
533 if (typeof(skycalendar) != "undefined") {
536 node.calendar = new skycalendar(node);
537 node.calendar.setCalendarPage(ResourcesURL + "/skycalendar.html");
538 var dateFormat = node.getAttribute("dateFormat");
540 node.calendar.setDateFormat(dateFormat);
544 function popupCalendar(node) {
545 var nodeId = node.getAttribute("inputId");
546 var input = $(nodeId);
547 input.calendar.popup();
552 function onAppointmentContextMenu(event, element) {
553 var topNode = $("appointmentsList");
556 var menu = $("appointmentsListMenu");
558 Event.observe(menu, "hideMenu", onAppointmentContextMenuHide);
559 popupMenu(event, "appointmentsListMenu", element);
561 var topNode = $("appointmentsList");
562 var selectedNodes = topNode.getSelectedRows();
563 topNode.menuSelectedRows = selectedNodes;
564 for (var i = 0; i < selectedNodes.length; i++)
565 selectedNodes[i].deselect();
567 topNode.menuSelectedEntry = element;
571 function onAppointmentContextMenuHide(event) {
572 var topNode = $("appointmentsList");
574 if (topNode.menuSelectedEntry) {
575 topNode.menuSelectedEntry.deselect();
576 topNode.menuSelectedEntry = null;
578 if (topNode.menuSelectedRows) {
579 var nodeIds = topNode.menuSelectedRows;
580 for (var i = 0; i < nodeIds.length; i++) {
581 var node = $(nodeIds[i]);
584 topNode.menuSelectedRows = null;
588 function onAppointmentsSelectionChange() {
589 listOfSelection = this;
590 this.removeClassName("_unfocused");
591 $("tasksList").addClassName("_unfocused");
594 function onTasksSelectionChange() {
595 listOfSelection = this;
596 this.removeClassName("_unfocused");
597 $("appointmentsList").addClassName("_unfocused");
600 function _loadAppointmentHref(href) {
601 if (document.appointmentsListAjaxRequest) {
602 document.appointmentsListAjaxRequest.aborted = true;
603 document.appointmentsListAjaxRequest.abort();
605 var url = ApplicationBaseURL + href;
606 document.appointmentsListAjaxRequest
607 = triggerAjaxRequest(url, appointmentsListCallback, href);
612 function _loadTasksHref(href) {
613 if (document.tasksListAjaxRequest) {
614 document.tasksListAjaxRequest.aborted = true;
615 document.tasksListAjaxRequest.abort();
617 url = ApplicationBaseURL + href;
619 var selectedIds = $("tasksList").getSelectedNodesId();
620 document.tasksListAjaxRequest
621 = triggerAjaxRequest(url, tasksListCallback, selectedIds);
626 function onHeaderClick(event) {
627 // log("onHeaderClick: " + this.link);
628 _loadAppointmentHref(this.link);
630 preventDefault(event);
633 function refreshAppointments() {
634 return _loadAppointmentHref("aptlist?desc=" + sortOrder
636 + "&day=" + currentDay
637 + "&filterpopup=" + listFilter);
640 function refreshTasks() {
641 return _loadTasksHref("taskslist?show-completed=" + showCompletedTasks);
644 function refreshAppointmentsAndDisplay() {
645 refreshAppointments();
646 changeCalendarDisplay();
649 function onListFilterChange() {
650 var node = $("filterpopup");
652 listFilter = node.value;
653 // log ("listFilter = " + listFilter);
655 return refreshAppointments();
658 function onAppointmentClick(event) {
659 var target = getTarget(event);
660 var node = target.getParentWithTagName("tr");
661 var day = node.getAttribute("day");
662 var hour = node.getAttribute("hour");
664 changeCalendarDisplay( { "day": day, "hour": hour} );
665 changeDateSelectorDisplay(day);
667 return onRowClick(event);
670 function selectMonthInMenu(menu, month) {
671 var entries = menu.childNodes[1].childNodesWithTag("LI");
672 for (i = 0; i < entries.length; i++) {
673 var entry = entries[i];
674 var entryMonth = entry.getAttribute("month");
675 if (entryMonth == month)
676 entry.addClassName("currentMonth");
678 entry.removeClassName("currentMonth");
682 function selectYearInMenu(menu, month) {
683 var entries = menu.childNodes[1].childNodes;
684 for (i = 0; i < entries.length; i++) {
685 var entry = entries[i];
686 if (entry instanceof HTMLLIElement) {
687 var entryMonth = entry.innerHTML;
688 if (entryMonth == month)
689 entry.addClassName("currentMonth");
691 entry.removeClassName("currentMonth");
696 function popupMonthMenu(event, menuId) {
697 var node = event.target;
699 if (event.button == 0) {
700 event.cancelBubble = true;
701 event.returnValue = false;
703 if (document.currentPopupMenu)
704 hideMenu(event, document.currentPopupMenu);
706 var popup = $(menuId);
707 var id = node.getAttribute("id");
708 if (id == "monthLabel")
709 selectMonthInMenu(popup, node.getAttribute("month"));
711 selectYearInMenu(popup, node.innerHTML);
713 var diff = (popup.offsetWidth - node.offsetWidth) /2;
715 popup.style.top = (node.offsetTop + 95) + "px";
716 popup.style.left = (node.offsetLeft - diff) + "px";
717 popup.style.visibility = "visible";
719 bodyOnClick = "" + document.body.getAttribute("onclick");
720 document.body.setAttribute("onclick", "onBodyClick('" + menuId + "');");
721 document.currentPopupMenu = popup;
725 function onMonthMenuItemClick(event) {
726 var month = '' + this.getAttribute("month");
727 var year = '' + $("yearLabel").innerHTML;
729 changeDateSelectorDisplay(year + month + "01", true);
731 // event.cancelBubble();
734 function onYearMenuItemClick(event) {
735 var month = '' + $("monthLabel").getAttribute("month");;
736 var year = '' + this.innerHTML;
738 changeDateSelectorDisplay(year + month + "01", true);
741 function onSearchFormSubmit() {
742 log ("search not implemented");
747 function onCalendarSelectAppointment() {
748 var list = $("appointmentsList");
751 var aptCName = this.getAttribute("aptCName");
752 if (selectedCalendarCell)
753 selectedCalendarCell.deselect();
755 selectedCalendarCell = this;
756 var row = $(aptCName);
758 var div = row.parentNode.parentNode.parentNode;
759 div.scrollTop = row.offsetTop - (div.offsetHeight / 2);
764 function onCalendarSelectDay(event) {
766 if (currentView == "multicolumndayview")
767 day = this.parentNode.getAttribute("day");
769 day = this.getAttribute("day");
770 var needRefresh = (listFilter == 'view_selectedday'
771 && day != currentDay);
773 if (currentView == 'weekview')
774 changeWeekCalendarDisplayOfSelectedDay(this);
775 else if (currentView == 'monthview')
776 changeMonthCalendarDisplayOfSelectedDay(this);
777 changeDateSelectorDisplay(day);
779 if (listOfSelection) {
780 listOfSelection.addClassName("_unfocused");
781 listOfSelection = null;
785 refreshAppointments();
788 function changeWeekCalendarDisplayOfSelectedDay(node) {
789 var days = document.getElementsByClassName("day", node.parentNode);
791 for (var i = 0; i < days.length; i++)
793 days[i].removeClassName("selectedDay");
795 node.addClassName("selectedDay");
798 function findMonthCalendarSelectedCell(daysContainer) {
802 while (!found && i < daysContainer.childNodes.length) {
803 var currentNode = daysContainer.childNodes[i];
804 if (currentNode instanceof HTMLDivElement
805 && currentNode.hasClassName("selectedDay")) {
806 daysContainer.selectedCell = currentNode;
814 function changeMonthCalendarDisplayOfSelectedDay(node) {
815 var daysContainer = node.parentNode;
816 if (!daysContainer.selectedCell)
817 findMonthCalendarSelectedCell(daysContainer);
819 if (daysContainer.selectedCell)
820 daysContainer.selectedCell.removeClassName("selectedDay");
821 daysContainer.selectedCell = node;
822 node.addClassName("selectedDay");
825 function onShowCompletedTasks(node) {
826 showCompletedTasks = (node.checked ? 1 : 0);
828 return refreshTasks();
831 function updateTaskStatus(node) {
832 var taskId = node.parentNode.getAttribute("id");
833 var taskOwner = node.parentNode.getAttribute("owner");
834 var newStatus = (node.checked ? 1 : 0);
835 // log ("update task status: " + taskId);
837 var http = createHTTPClient();
839 url = (UserFolderURL + "../" + taskOwner + "/Calendar/"
840 + taskId + "/changeStatus?status=" + newStatus);
843 // log ("url: " + url);
844 // TODO: add parameter to signal that we are only interested in OK
846 http.open("GET", url, false /* not async */);
848 if (http.status == 200)
851 log ("no http client?");
856 function updateCalendarStatus(event) {
857 var list = new Array();
859 var nodes = $("calendarList").childNodesWithTag("li");
860 for (var i = 0; i < nodes.length; i++) {
861 var input = $(nodes[i]).childNodesWithTag("input")[0];
863 var folderId = nodes[i].getAttribute("id");
864 var elems = folderId.split(":");
865 if (elems.length > 1)
868 list.push(UserLogin);
873 list.push(UserLogin);
874 nodes[0].childNodesWithTag("input")[0].checked = true;
876 // ApplicationBaseURL = (UserFolderURL + "Groups/_custom_"
877 // + list.join(",") + "/Calendar/");
880 var folderID = this.parentNode.getAttribute("id");
881 var urlstr = URLForFolderID(folderID);
883 urlstr += "/activateFolder";
885 urlstr += "/deactivateFolder";
886 triggerAjaxRequest(urlstr, calendarStatusCallback, folderID);
889 updateCalendarsList();
890 refreshAppointments();
892 changeCalendarDisplay();
898 function calendarStatusCallback(http) {
899 if (http.readyState == 4) {
900 if (http.status == 204) {
901 refreshAppointments();
903 changeCalendarDisplay();
906 var folder = $(http.callbackData);
907 var input = folder.childNodesWithTag("input")[0];
908 input.checked = (!input.checked);
913 function calendarEntryCallback(http) {
916 if (http.readyState == 4) {
917 if (http.status == 200)
918 disabled = (http.responseText == "0");
919 var entry = $(http.callbackData);
920 var input = entry.childNodesWithTag("input")[0];
921 input.disabled = disabled;
923 input.checked = false;
924 $(entry).addClassName("denied");
927 $(entry).removeClassName("denied");
931 function updateCalendarsList(method) {
932 var list = $("calendarList").childNodesWithTag("li");
933 for (var i = 0; i < list.length; i++) {
934 var folderID = list[i].getAttribute("id");
935 var url = URLForFolderID(folderID) + "/canAccessContent";
936 triggerAjaxRequest(url, calendarEntryCallback, folderID);
940 function addContact(tag, fullContactName, contactId, contactName, contactEmail) {
941 var uids = $("uixselector-calendarsList-uidList");
942 // log("addContact");
945 var re = new RegExp("(^|,)" + contactId + "($|,)");
947 if (!re.test(uids.value))
949 if (uids.value.length > 0)
950 uids.value += ',' + contactId;
952 uids.value = contactId;
953 var names = $("calendarList");
954 var listElems = names.childNodesWithTag("li");
955 var colorDef = indexColor(listElems.length);
956 names.appendChild(userCalendarEntry(contactId, colorDef));
964 function validateBrowseURL(input) {
965 var button = $("browseURLBtn");
967 if (input.value.length) {
969 enableAnchor(button);
970 } else if (!button.disabled)
971 disableAnchor(button);
974 function browseURL(anchor, event) {
975 if (event.button == 0) {
976 var input = $("url");
977 var url = input.value;
979 window.open(url, '_blank');
985 function getMenus() {
988 var dateMenu = new Array();
989 for (var i = 0; i < 12; i++)
990 dateMenu.push(onMonthMenuItemClick);
991 menus["monthListMenu"] = dateMenu;
993 dateMenu = new Array();
994 for (var i = 0; i < 11; i++)
995 dateMenu.push(onYearMenuItemClick);
996 menus["yearListMenu"] = dateMenu;
998 menus["appointmentsListMenu"] = new Array(onMenuNewEventClick, "-",
1000 editEvent, deleteEvent, "-",
1003 menus["calendarsMenu"] = new Array(null, null, "-", null, null, "-",
1004 null, "-", onMenuSharing);
1005 menus["searchMenu"] = new Array(setSearchCriteria);
1010 function onMenuSharing(event) {
1011 var folders = $("calendarList");
1012 var selected = folders.getSelectedNodes()[0];
1013 /* FIXME: activation of the context menu should preferable select the entry
1014 above which the event has occured */
1016 var folderID = selected.getAttribute("id");
1017 var urlstr = URLForFolderID(folderID) + "/acls";
1019 openAclWindow(urlstr);
1023 function configureDragHandles() {
1024 var handle = $("verticalDragHandle");
1026 handle.addInterface(SOGoDragHandlesInterface);
1027 handle.leftBlock=$("leftPanel");
1028 handle.rightBlock=$("rightPanel");
1031 handle = $("rightDragHandle");
1033 handle.addInterface(SOGoDragHandlesInterface);
1034 handle.upperBlock=$("appointmentsListView");
1035 handle.lowerBlock=$("calendarView");
1039 function initCalendarSelector() {
1040 var selector = $("calendarSelector");
1041 updateCalendarStatus();
1042 selector.changeNotification = updateCalendarsList;
1044 var list = $("calendarList").childNodesWithTag("li");
1045 for (var i = 0; i < list.length; i++) {
1046 var input = list[i].childNodesWithTag("input")[0];
1047 Event.observe(input, "change", updateCalendarStatus.bindAsEventListener(input));
1048 Event.observe(list[i], "mousedown", listRowMouseDownHandler);
1049 Event.observe(list[i], "click", onRowClick);
1052 var links = $("calendarSelectorButtons").childNodesWithTag("a");
1053 Event.observe(links[0], "click", onCalendarAdd);
1054 Event.observe(links[1], "click", onCalendarRemove);
1057 function onCalendarAdd(event) {
1058 openUserFolderSelector(onFolderSubscribeCB, "calendar");
1060 preventDefault(event);
1063 function appendCalendar(folderName, folder) {
1064 var calendarList = $("calendarList");
1065 var lis = calendarList.childNodesWithTag("li");
1066 var color = indexColor(lis.length);
1067 log ("color: " + color);
1068 var li = document.createElement("li");
1069 li.setAttribute("id", folder);
1070 Event.observe(li, "mousedown", listRowMouseDownHandler);
1071 Event.observe(li, "click", onRowClick);
1072 var checkBox = document.createElement("input");
1073 checkBox.addClassName("checkBox");
1074 checkBox.type = "checkbox";
1075 Event.observe(checkBox, "change", updateCalendarStatus);
1076 li.appendChild(checkBox);
1077 li.appendChild(document.createTextNode(" "));
1078 var colorBox = document.createElement("div");
1079 colorBox.appendChild(document.createTextNode("OO"));
1080 colorBox.addClassName("colorBox");
1082 colorBox.setStyle({ color: color,
1083 backgroundColor: color });
1085 li.appendChild(colorBox);
1086 li.appendChild(document.createTextNode(" " + folderName));
1088 calendarList.appendChild(li);
1090 var contactId = folder.split(":")[0];
1091 var styles = document.getElementsByTagName("style");
1093 var url = URLForFolderID(folder) + "/canAccessContent";
1094 triggerAjaxRequest(url, calendarEntryCallback, folder);
1096 styles[0].innerHTML += ('.ownerIs' + contactId + ' {'
1097 + ' background-color: '
1099 + ' !important; }');
1102 function onFolderSubscribeCB(folderData) {
1103 var folder = $(folderData["folder"]);
1105 appendCalendar(folderData["folderName"], folderData["folder"]);
1108 function onFolderUnsubscribeCB(folderId) {
1109 var node = $(folderId);
1110 node.parentNode.removeChild(node);
1113 function onCalendarRemove(event) {
1114 var nodes = $("calendarList").getSelectedNodes();
1115 if (nodes.length > 0) {
1116 nodes[0].deselect();
1117 var folderId = nodes[0].getAttribute("id");
1118 var folderIdElements = folderId.split(":");
1119 if (folderIdElements.length > 1) {
1120 unsubscribeFromFolder(folderId, onFolderUnsubscribeCB, folderId);
1124 preventDefault(event);
1127 function configureSearchField() {
1128 var searchValue = $("searchValue");
1130 Event.observe(searchValue, "mousedown", onSearchMouseDown.bindAsEventListener(searchValue));
1131 Event.observe(searchValue, "click", popupSearchMenu.bindAsEventListener(searchValue));
1132 Event.observe(searchValue, "blur", onSearchBlur.bindAsEventListener(searchValue));
1133 Event.observe(searchValue, "focus", onSearchFocus.bindAsEventListener(searchValue));
1134 Event.observe(searchValue, "keydown", onSearchKeyDown.bindAsEventListener(searchValue));
1137 function initCalendars() {
1138 if (!document.body.hasClassName("popup")) {
1139 initCalendarSelector();
1140 configureSearchField();
1141 var selector = $("calendarSelector");
1143 selector.attachMenu("calendarsMenu");
1147 addEvent(window, 'load', initCalendars);