X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=UI%2FWebServerResources%2FSchedulerUI.js;h=337d6f45c25b53387b9a82b82e6833f0b2cbb195;hb=9afd25ddbbb12ed3ee76b8e12ad3b6c0b8e3d839;hp=b4fe4f2f07d502fd90b722d5117a52e659964956;hpb=ddfde35f210f69ef6ba1b92dbd0ba990a8476698;p=scalable-opengroupware.org diff --git a/UI/WebServerResources/SchedulerUI.js b/UI/WebServerResources/SchedulerUI.js index b4fe4f2f..337d6f45 100644 --- a/UI/WebServerResources/SchedulerUI.js +++ b/UI/WebServerResources/SchedulerUI.js @@ -17,7 +17,7 @@ var cachedDateSelectors = new Array(); var contactSelectorAction = 'calendars-contacts'; var eventsToDelete = new Array(); -var ownersOfEventsToDelete = new Array(); +var calendarsOfEventsToDelete = new Array(); var usersRightsWindowHeight = 250; var usersRightsWindowWidth = 502; @@ -27,15 +27,11 @@ function newEvent(sender, type) { if (!day) day = currentDay; - var user = UserLogin; - if (sender.parentNode.getAttribute("id") != "toolbar" - && currentView == "multicolumndayview" && type == "event") - user = sender.parentNode.parentNode.getAttribute("user"); - var hour = sender.hour; if (!hour) hour = sender.getAttribute("hour"); - var urlstr = UserFolderURL + "../" + user + "/Calendar/new" + type; + var folderID = getSelectedFolder(); + var urlstr = ApplicationBaseURL + folderID + "/new" + type; var params = new Array(); if (day) params.push("day=" + day); @@ -49,6 +45,18 @@ function newEvent(sender, type) { return false; /* stop following the link */ } +function getSelectedFolder() { + var folder; + + var nodes = $("calendarList").getSelectedRows(); + if (nodes.length > 0) + folder = nodes[0].getAttribute("id"); + else + folder = "/personal"; + + return folder; +} + function onMenuNewEventClick(event) { newEvent(this, "event"); } @@ -57,13 +65,8 @@ function onMenuNewTaskClick(event) { newEvent(this, "task"); } -function _editEventId(id, owner) { - var urlBase; - if (owner) - urlBase = UserFolderURL + "../" + owner + "/"; - urlBase += "Calendar/" - - var urlstr = urlBase + id + "/edit"; +function _editEventId(id, calendar) { + var urlstr = ApplicationBaseURL + "/" + calendar + "/" + id + "/edit"; var targetname = "SOGo_edit_" + id; var win = window.open(urlstr, "_blank", "width=490,height=470,resizable=0"); @@ -76,10 +79,10 @@ function editEvent() { for (var i = 0; i < nodes.length; i++) _editEventId(nodes[i].getAttribute("id"), - nodes[i].owner); + nodes[i].calendar); } else if (selectedCalendarCell) { _editEventId(selectedCalendarCell[0].cname, - selectedCalendarCell[0].owner); + selectedCalendarCell[0].calendar); } return false; /* stop following the link */ @@ -87,9 +90,9 @@ function editEvent() { function _batchDeleteEvents() { var events = eventsToDelete.shift(); - var owner = ownersOfEventsToDelete.shift(); - var urlstr = (UserFolderURL + "../" + owner + "/Calendar/batchDelete?ids=" - + events.join('/')); + var calendar = calendarsOfEventsToDelete.shift(); + var urlstr = (ApplicationBaseURL + "/" + calendar + + "/batchDelete?ids=" + events.join('/')); document.deleteEventAjaxRequest = triggerAjaxRequest(urlstr, deleteEventCallback, events); @@ -102,9 +105,9 @@ function deleteEvent() { if (nodes.length > 0) { var label = ""; if (listOfSelection == $("tasksList")) - label = labels["taskDeleteConfirmation"].decodeEntities(); + label = labels["taskDeleteConfirmation"]; else - label = labels["eventDeleteConfirmation"].decodeEntities(); + label = labels["eventDeleteConfirmation"]; if (confirm(label)) { if (document.deleteEventAjaxRequest) { @@ -112,33 +115,33 @@ function deleteEvent() { document.deleteEventAjaxRequest.abort(); } var sortedNodes = new Array(); - var owners = new Array(); + var calendars = new Array(); for (var i = 0; i < nodes.length; i++) { - var owner = nodes[i].owner; - if (!sortedNodes[owner]) { - sortedNodes[owner] = new Array(); - owners.push(owner); + var calendar = nodes[i].calendar; + if (!sortedNodes[calendar]) { + sortedNodes[calendar] = new Array(); + calendars.push(calendar); } - sortedNodes[owner].push(nodes[i].cname); + sortedNodes[calendar].push(nodes[i].cname); } - for (var i = 0; i < owners.length; i++) { - ownersOfEventsToDelete.push(owners[i]); - eventsToDelete.push(sortedNodes[owners[i]]); + for (var i = 0; i < calendars.length; i++) { + calendarsOfEventsToDelete.push(calendars[i]); + eventsToDelete.push(sortedNodes[calendars[i]]); } _batchDeleteEvents(); } } } else if (selectedCalendarCell) { - var label = labels["eventDeleteConfirmation"].decodeEntities(); + var label = labels["eventDeleteConfirmation"]; if (confirm(label)) { if (document.deleteEventAjaxRequest) { document.deleteEventAjaxRequest.aborted = true; document.deleteEventAjaxRequest.abort(); } eventsToDelete.push([selectedCalendarCell[0].cname]); - ownersOfEventsToDelete.push(selectedCalendarCell[0].owner); + calendarsOfEventsToDelete.push(selectedCalendarCell[0].calendar); _batchDeleteEvents(); } } @@ -162,59 +165,67 @@ function modifyEvent(sender, modification) { function closeInvitationWindow() { var closeDiv = document.createElement("div"); + document.body.appendChild(closeDiv); closeDiv.addClassName("javascriptPopupBackground"); + var closePseudoWin = document.createElement("div"); + document.body.appendChild(closePseudoWin); closePseudoWin.addClassName("javascriptMessagePseudoTopWindow"); closePseudoWin.style.top = "0px;"; closePseudoWin.style.left = "0px;"; closePseudoWin.style.right = "0px;"; - closePseudoWin.appendChild(document.createTextNode(labels["closeThisWindowMessage"].decodeEntities())); - document.body.appendChild(closeDiv); - document.body.appendChild(closePseudoWin); + closePseudoWin.appendChild(document.createTextNode(labels["closeThisWindowMessage"])); + + var calLink = document.createElement("a"); + closePseudoWin.appendChild(calLink); + calLink.href = ApplicationBaseURL; + calLink.appendChild(document.createTextNode(labels["Calendar"].toLowerCase())); } function modifyEventCallback(http) { - if (http.readyState == 4) { - if (http.status == 200) { - if (queryParameters["mail-invitation"].toLowerCase() == "yes") - closeInvitationWindow(); - else { - window.opener.setTimeout("refreshEventsAndDisplay();", 100); - window.setTimeout("window.close();", 100); - } - } + if (http.readyState == 4) { + if (http.status == 200) { + var mailInvitation = queryParameters["mail-invitation"]; + if (mailInvitation && mailInvitation.toLowerCase() == "yes") + closeInvitationWindow(); else { -// log("showing alert..."); - window.alert(labels["eventPartStatModificationError"]); + window.opener.setTimeout("refreshEventsAndDisplay();", 100); + window.setTimeout("window.close();", 100); } - document.modifyEventAjaxRequest = null; - } + } + else { +// log("showing alert..."); + window.alert(labels["eventPartStatModificationError"]); + } + document.modifyEventAjaxRequest = null; + } } function deleteEventCallback(http) { - if (http.readyState == 4 - && http.status == 200) { - var nodes = http.callbackData; - for (var i = 0; i < nodes.length; i++) { - var node = $(nodes[i]); - if (node) - node.parentNode.removeChild(node); - } - if (eventsToDelete.length) - _batchDeleteEvents(); - else { - document.deleteEventAjaxRequest = null; - refreshEvents(); - refreshTasks(); - changeCalendarDisplay(); + if (http.readyState == 4) { + if (isHttpStatus204(http.status)) { + var nodes = http.callbackData; + for (var i = 0; i < nodes.length; i++) { + var node = $(nodes[i]); + if (node) + node.parentNode.removeChild(node); + } + if (eventsToDelete.length) + _batchDeleteEvents(); + else { + document.deleteEventAjaxRequest = null; + refreshEvents(); + refreshTasks(); + changeCalendarDisplay(); + } } + else + log ("deleteEventCallback Ajax error"); } - else - log ("deleteEventCallback Ajax error"); } function editDoubleClickedEvent(event) { - _editEventId(this.cname, this.owner); + _editEventId(this.cname, this.calendar); preventDefault(event); event.cancelBubble = true; @@ -302,51 +313,53 @@ function eventsListCallback(http) { var div = $("eventsListView"); document.eventsListAjaxRequest = null; - var table = $("eventsList").tBodies[0]; + var table = $("eventsList"); var params = parseQueryParameters(http.callbackData); sortKey = params["sort"]; sortOrder = params["desc"]; - configureSortableTableHeaders(); - - var data = http.responseText.evalJSON(true); - for (var i = 0; i < data.length; i++) { - var row = document.createElement("tr"); - table.appendChild(row); - $(row).addClassName("eventRow"); - row.setAttribute("id", data[i][0]); - row.cname = data[i][0]; - row.owner = data[i][1]; - - var startDate = new Date(); - startDate.setTime(data[i][4] * 1000); - row.day = startDate.getDayString(); - row.hour = startDate.getHourString(); - Event.observe(row, "click", - onEventClick.bindAsEventListener(row)); - Event.observe(row, "dblclick", - editDoubleClickedEvent.bindAsEventListener(row)); - Event.observe(row, "contextmenu", - onEventContextMenu.bindAsEventListener(row)); - - var td = document.createElement("td"); - row.appendChild(td); - Event.observe(td, "mousedown", listRowMouseDownHandler, true); - td.appendChild(document.createTextNode(data[i][3])); - - td = document.createElement("td"); - row.appendChild(td); - Event.observe(td, "mousedown", listRowMouseDownHandler, true); - td.appendChild(document.createTextNode(data[i][8])); - - td = document.createElement("td"); - row.appendChild(td); - Event.observe(td, "mousedown", listRowMouseDownHandler, true); - td.appendChild(document.createTextNode(data[i][9])); + lastClickedRow = -1; // from generic.js + + if (http.responseText.length > 0) { + var data = http.responseText.evalJSON(true); + for (var i = 0; i < data.length; i++) { + var row = document.createElement("tr"); + table.tBodies[0].appendChild(row); + $(row).addClassName("eventRow"); + row.setAttribute("id", escape(data[i][0])); + row.cname = escape(data[i][0]); + row.calendar = data[i][1]; + + var startDate = new Date(); + startDate.setTime(data[i][4] * 1000); + row.day = startDate.getDayString(); + row.hour = startDate.getHourString(); + Event.observe(row, "click", + onEventClick.bindAsEventListener(row)); + Event.observe(row, "dblclick", + editDoubleClickedEvent.bindAsEventListener(row)); + Event.observe(row, "contextmenu", + onEventContextMenu.bindAsEventListener(row)); + + var td = document.createElement("td"); + row.appendChild(td); + Event.observe(td, "mousedown", listRowMouseDownHandler, true); + td.appendChild(document.createTextNode(data[i][3])); + + td = document.createElement("td"); + row.appendChild(td); + Event.observe(td, "mousedown", listRowMouseDownHandler, true); + td.appendChild(document.createTextNode(data[i][8])); + + td = document.createElement("td"); + row.appendChild(td); + Event.observe(td, "mousedown", listRowMouseDownHandler, true); + td.appendChild(document.createTextNode(data[i][9])); - td = document.createElement("td"); - row.appendChild(td); - Event.observe(td, "mousedown", listRowMouseDownHandler, true); - td.appendChild(document.createTextNode(data[i][6])); + td = document.createElement("td"); + row.appendChild(td); + Event.observe(td, "mousedown", listRowMouseDownHandler, true); + td.appendChild(document.createTextNode(data[i][6])); + } } } else @@ -360,50 +373,53 @@ function tasksListCallback(http) { && http.status == 200) { document.tasksListAjaxRequest = null; var list = $("tasksList"); - var data = http.responseText.evalJSON(true); - - for (var i = 0; i < data.length; i++) { - //log(i + " = " + data[i][3]); - var listItem = document.createElement("li"); - list.appendChild(listItem); - Event.observe(listItem, "mousedown", listRowMouseDownHandler); // causes problem with Safari - Event.observe(listItem, "click", onRowClick); - Event.observe(listItem, "dblclick", editDoubleClickedEvent.bindAsEventListener(listItem)); - listItem.setAttribute("id", data[i][0]); - $(listItem).addClassName(data[i][5]); - var owner = data[i][1]; - listItem.owner = owner; - $(listItem).addClassName("ownerIs" + owner); - listItem.cname = data[i][0]; - var input = document.createElement("input"); - input.setAttribute("type", "checkbox"); - listItem.appendChild(input); - Event.observe(input, "click", updateTaskStatus.bindAsEventListener(input), true); - input.setAttribute("value", "1"); - if (data[i][2] == 1) - input.setAttribute("checked", "checked"); - $(input).addClassName("checkBox"); - listItem.appendChild(document.createTextNode(data[i][3])); - } + + if (http.responseText.length > 0) { + var data = http.responseText.evalJSON(true); + + for (var i = 0; i < data.length; i++) { + //log(i + " = " + data[i][3]); + var listItem = document.createElement("li"); + list.appendChild(listItem); + Event.observe(listItem, "mousedown", listRowMouseDownHandler); + Event.observe(listItem, "click", onRowClick); + Event.observe(listItem, "dblclick", + editDoubleClickedEvent.bindAsEventListener(listItem)); + listItem.setAttribute("id", data[i][0]); + $(listItem).addClassName(data[i][5]); + listItem.calendar = data[i][1]; + $(listItem).addClassName("calendarFolder" + data[i][1]); + listItem.cname = escape(data[i][0]); + var input = document.createElement("input"); + input.setAttribute("type", "checkbox"); + listItem.appendChild(input); + Event.observe(input, "click", updateTaskStatus.bindAsEventListener(input), true); + input.setAttribute("value", "1"); + if (data[i][2] == 1) + input.setAttribute("checked", "checked"); + $(input).addClassName("checkBox"); + listItem.appendChild(document.createTextNode(data[i][3])); + } - list.scrollTop = list.previousScroll; + list.scrollTop = list.previousScroll; - if (http.callbackData) { - var selectedNodesId = http.callbackData; - for (var i = 0; i < selectedNodesId.length; i++) { -// log(selectedNodesId[i] + " (" + i + ") is selected"); - $(selectedNodesId[i]).select(); + if (http.callbackData) { + var selectedNodesId = http.callbackData; + for (var i = 0; i < selectedNodesId.length; i++) { + // log(selectedNodesId[i] + " (" + i + ") is selected"); + $(selectedNodesId[i]).select(); + } } + else + log ("tasksListCallback: no data"); } - else - log ("tasksListCallback: no data"); } else log ("tasksListCallback Ajax error"); } function restoreCurrentDaySelection(div) { - var elements = div.getElementsByTagName("a"); + var elements = $(div).getElementsByTagName("a"); var day = null; var i = 9; while (!day && i < elements.length) @@ -417,10 +433,10 @@ function restoreCurrentDaySelection(div) { for (i = 0; i < elements.length; i++) { day = elements[i].day; if (day && day == currentDay) { - var td = elements[i].getParentWithTagName("td"); + var td = $(elements[i]).getParentWithTagName("td"); if (document.selectedDate) document.selectedDate.deselect(); - td.select(); + $(td).select(); document.selectedDate = td; } } @@ -428,7 +444,7 @@ function restoreCurrentDaySelection(div) { } function changeDateSelectorDisplay(day, keepCurrentDay) { - var url = ApplicationBaseURL + "dateselector"; + var url = ApplicationBaseURL + "/dateselector"; if (day) url += "?day=" + day; @@ -455,16 +471,16 @@ function changeDateSelectorDisplay(day, keepCurrentDay) { } } -function changeCalendarDisplay(time, newView) { - var url = ApplicationBaseURL + ((newView) ? newView : currentView); +function changeCalendarDisplay(data, newView) { + var url = ApplicationBaseURL + "/" + ((newView) ? newView : currentView); selectedCalendarCell = null; var day = null; - var hour = null; - if (time) { - day = time['day']; - hour = time['hour']; + var scrollEvent = null; + if (data) { + day = data['day']; + scrollEvent = data['scrollEvent']; } if (!day) @@ -483,7 +499,9 @@ function changeCalendarDisplay(time, newView) { } document.dayDisplayAjaxRequest = triggerAjaxRequest(url, calendarDisplayCallback, - { "view": newView, "day": day, "hour": hour }); + { "view": newView, + "day": day, + "scrollEvent": scrollEvent }); return false; } @@ -511,25 +529,26 @@ function onMonthOverview() { return _ensureView("monthview"); } -function scrollDayView(hour) { - var rowNumber; - if (hour) { - if (hour.length == 3) - rowNumber = parseInt(hour.substr(0, 1)); - else { - if (hour.substr(0, 1) == "0") - rowNumber = parseInt(hour.substr(1, 1)); - else - rowNumber = parseInt(hour.substr(0, 2)); - } - } else - rowNumber = 8; - +function scrollDayView(scrollEvent) { + var offset = 0; var daysView = $("daysView"); var hours = - $(daysView.childNodesWithTag("div")[0]).childNodesWithTag("div"); - if (hours.length > 0) - daysView.scrollTop = hours[rowNumber].offsetTop; + $(daysView.childNodesWithTag("div")[0]).childNodesWithTag("div"); + + if (scrollEvent && scrollEvent.siblings) { + var classes = scrollEvent.siblings[0].getAttribute("class").split(" "); + for (var i = 0; i < classes.length; i++) { + if (classes[i].startsWith("starts")) { + var starts = Math.floor(parseInt(classes[i].substr(6)) / 4); + offset = hours[starts].offsetTop; + } + } + } + else { + offset = hours[8].offsetTop; + } + + daysView.scrollTop = offset - 5; } function onClickableCellsDblClick(event) { @@ -582,7 +601,7 @@ function refreshCalendarEvents() { document.refreshCalendarEventsAjaxRequest.aborted = true; document.refreshCalendarEventsAjaxRequest.abort(); } - var url = ApplicationBaseURL + "eventslist?sd=" + sd + "&ed=" + ed; + var url = ApplicationBaseURL + "/eventslist?sd=" + sd + "&ed=" + ed; document.refreshCalendarEventsAjaxRequest = triggerAjaxRequest(url, refreshCalendarEventsCallback, {"startDate": sd, "endDate": ed}); @@ -591,12 +610,15 @@ function refreshCalendarEvents() { function refreshCalendarEventsCallback(http) { if (http.readyState == 4 && http.status == 200) { - var data = http.responseText.evalJSON(true); + + if (http.responseText.length > 0) { + var data = http.responseText.evalJSON(true); // log("refresh calendar events: " + data.length); - for (var i = 0; i < data.length; i++) + for (var i = 0; i < data.length; i++) drawCalendarEvent(data[i], http.callbackData["startDate"], http.callbackData["endDate"]); + } } else log("AJAX error when refreshing calendar events"); @@ -611,9 +633,9 @@ function drawCalendarEvent(eventData, sd, ed) { var endDate = new Date(); endDate.setTime(eventData[5] * 1000); - var days = startDate.daysUpTo(endDate); +// log ("s: " + startDate + "; e: " + endDate); - var divs = new Array(); + var days = startDate.daysUpTo(endDate); var title; if (currentView == "monthview" @@ -635,8 +657,8 @@ function drawCalendarEvent(eventData, sd, ed) { // log("day: " + days[i]); if (i == 0) { - var quarters = (startDate.getHours() * 4 - + Math.floor(startDate.getMinutes() / 15)); + var quarters = (startDate.getUTCHours() * 4 + + Math.floor(startDate.getUTCMinutes() / 15)); starts = quarters; startHour = startDate.getDisplayHoursString(); endHour = endDate.getDisplayHoursString(); @@ -647,8 +669,8 @@ function drawCalendarEvent(eventData, sd, ed) { var ends; var lasts; if (i == days.length - 1) { - var quarters = (endDate.getHours() * 4 - + Math.ceil(endDate.getMinutes() / 15)); + var quarters = (endDate.getUTCHours() * 4 + + Math.ceil(endDate.getUTCMinutes() / 15)); ends = quarters; } else @@ -701,43 +723,47 @@ function drawCalendarEvent(eventData, sd, ed) { } } if (parentDiv) - parentDiv.appendChild(eventDiv); + parentDiv.appendChild(eventDiv); } + + var eventTR = $(eventData[0]); + if (eventTR) + eventTR.siblings = siblings; } -function newEventDIV(cname, owner, starts, lasts, +function newEventDIV(cname, calendar, starts, lasts, startHour, endHour, title) { var eventDiv = document.createElement("div"); - eventDiv.cname = cname; - eventDiv.owner = owner; - eventDiv.addClassName("event"); - eventDiv.addClassName("starts" + starts); - eventDiv.addClassName("lasts" + lasts); + eventDiv.cname = escape(cname); + eventDiv.calendar = calendar; + $(eventDiv).addClassName("event"); + $(eventDiv).addClassName("starts" + starts); + $(eventDiv).addClassName("lasts" + lasts); for (var i = 1; i < 5; i++) { var shadowDiv = document.createElement("div"); eventDiv.appendChild(shadowDiv); - shadowDiv.addClassName("shadow"); - shadowDiv.addClassName("shadow" + i); + $(shadowDiv).addClassName("shadow"); + $(shadowDiv).addClassName("shadow" + i); } var innerDiv = document.createElement("div"); eventDiv.appendChild(innerDiv); - innerDiv.addClassName("eventInside"); - innerDiv.addClassName("ownerIs" + owner); + $(innerDiv).addClassName("eventInside"); + $(innerDiv).addClassName("calendarFolder" + calendar); var gradientDiv = document.createElement("div"); innerDiv.appendChild(gradientDiv); - gradientDiv.addClassName("gradient"); + $(gradientDiv).addClassName("gradient"); var gradientImg = document.createElement("img"); gradientDiv.appendChild(gradientImg); gradientImg.src = ResourcesURL + "/event-gradient.png"; var textDiv = document.createElement("div"); innerDiv.appendChild(textDiv); - textDiv.addClassName("text"); + $(textDiv).addClassName("text"); if (startHour) { var headerSpan = document.createElement("span"); textDiv.appendChild(headerSpan); - headerSpan.addClassName("eventHeader"); + $(headerSpan).addClassName("eventHeader"); headerSpan.appendChild(document.createTextNode(startHour + " - " + endHour)); textDiv.appendChild(document.createElement("br")); @@ -759,28 +785,28 @@ function calendarDisplayCallback(http) { if (http.readyState == 4 && http.status == 200) { document.dayDisplayAjaxRequest = null; - div.innerHTML = http.responseText; + div.update(http.responseText); if (http.callbackData["view"]) currentView = http.callbackData["view"]; if (http.callbackData["day"]) currentDay = http.callbackData["day"]; - var hour = null; - if (http.callbackData["hour"]) - hour = http.callbackData["hour"]; var contentView; if (currentView == "monthview") contentView = $("calendarContent"); else { - scrollDayView(hour); + var scrollEvent = http.callbackData.scrollEvent; + scrollDayView($(scrollEvent)); contentView = $("daysView"); } refreshCalendarEvents(); var days = document.getElementsByClassName("day", contentView); if (currentView == "monthview") for (var i = 0; i < days.length; i++) { - Event.observe(days[i], "click", onCalendarSelectDay.bindAsEventListener(days[i])); - Event.observe(days[i], "dblclick", onClickableCellsDblClick.bindAsEventListener(days[i])); + Event.observe(days[i], "click", + onCalendarSelectDay.bindAsEventListener(days[i])); + Event.observe(days[i], "dblclick", + onClickableCellsDblClick.bindAsEventListener(days[i])); } else { var headerDivs = $("calendarHeader").childNodesWithTag("div"); @@ -808,15 +834,15 @@ function calendarDisplayCallback(http) { } function assignCalendar(name) { - if (typeof(skycalendar) != "undefined") { - var node = $(name); + if (typeof(skycalendar) != "undefined") { + var node = $(name); - node.calendar = new skycalendar(node); - node.calendar.setCalendarPage(ResourcesURL + "/skycalendar.html"); - var dateFormat = node.getAttribute("dateFormat"); - if (dateFormat) - node.calendar.setDateFormat(dateFormat); - } + node.calendar = new skycalendar(node); + node.calendar.setCalendarPage(ResourcesURL + "/skycalendar.html"); + var dateFormat = node.getAttribute("dateFormat"); + if (dateFormat) + node.calendar.setDateFormat(dateFormat); + } } function popupCalendar(node) { @@ -880,13 +906,13 @@ function _loadEventHref(href) { document.eventsListAjaxRequest.aborted = true; document.eventsListAjaxRequest.abort(); } - var url = ApplicationBaseURL + href; + var url = ApplicationBaseURL + "/" + href; document.eventsListAjaxRequest = triggerAjaxRequest(url, eventsListCallback, href); var table = $("eventsList").tBodies[0]; - while (table.rows.length > 1) - table.removeChild(table.rows[1]); + while (table.rows.length > 0) + table.removeChild(table.rows[0]); return false; } @@ -896,7 +922,7 @@ function _loadTasksHref(href) { document.tasksListAjaxRequest.aborted = true; document.tasksListAjaxRequest.abort(); } - url = ApplicationBaseURL + href; + url = ApplicationBaseURL + "/" + href; var tasksList = $("tasksList"); var selectedIds; @@ -915,8 +941,8 @@ function _loadTasksHref(href) { } function onHeaderClick(event) { -// log("onHeaderClick: " + this.link); - _loadEventHref(this.link); + //log("onHeaderClick: " + this.link); + //_loadEventHref(this.link); preventDefault(event); } @@ -947,11 +973,9 @@ function onListFilterChange() { } function onEventClick(event) { - var day = this.day; - var hour = this.hour; - - changeCalendarDisplay( { "day": day, "hour": hour} ); - changeDateSelectorDisplay(day); + changeCalendarDisplay( { "day": this.day, + "scrollEvent": this.getAttribute("id") } ); + changeDateSelectorDisplay(this.day); return onRowClick(event); } @@ -972,7 +996,7 @@ function selectYearInMenu(menu, month) { var entries = menu.childNodes[1].childNodes; for (i = 0; i < entries.length; i++) { var entry = entries[i]; - if (entry instanceof HTMLLIElement) { + if (entry.tagName == "LI") { var entryMonth = entry.innerHTML; if (entryMonth == month) entry.addClassName("currentMonth"); @@ -1023,7 +1047,7 @@ function onSearchFormSubmit() { function onCalendarSelectEvent() { var list = $("eventsList"); - list.deselectAll(); + $(list.tBodies[0]).deselectAll(); if (selectedCalendarCell) for (var i = 0; i < selectedCalendarCell.length; i++) @@ -1089,7 +1113,7 @@ function findMonthCalendarSelectedCell(daysContainer) { while (!found && i < daysContainer.childNodes.length) { var currentNode = daysContainer.childNodes[i]; - if (currentNode instanceof HTMLDivElement + if (currentNode.tagName == 'DIV' && currentNode.hasClassName("selectedDay")) { daysContainer.selectedCell = currentNode; found = true; @@ -1118,19 +1142,17 @@ function onShowCompletedTasks(event) { function updateTaskStatus(event) { var taskId = this.parentNode.getAttribute("id"); - var taskOwner = this.parentNode.owner; var newStatus = (this.checked ? 1 : 0); var http = createHTTPClient(); + + if (isSafari() && !isSafari3()) { + newStatus = (newStatus ? 0 : 1); + } -// log("update task status: " + taskId + " to " + this.checked); - event.cancelBubble = true; - - url = (UserFolderURL + "../" + taskOwner - + "/Calendar/" + taskId - + "/changeStatus?status=" + newStatus); + url = (ApplicationBaseURL + "/" + this.parentNode.calendar + + "/" + taskId + "/changeStatus?status=" + newStatus); if (http) { -// log ("url: " + url); // TODO: add parameter to signal that we are only interested in OK http.open("POST", url, false /* not async */); http.url = url; @@ -1145,6 +1167,12 @@ function updateTaskStatus(event) { function updateCalendarStatus(event) { var list = new Array(); + var newStatus = (this.checked ? 1 : 0); + + if (isSafari() && !isSafari3()) { + newStatus = (newStatus ? 0 : 1); + this.checked = newStatus; + } var nodes = $("calendarList").childNodesWithTag("li"); for (var i = 0; i < nodes.length; i++) { @@ -1159,17 +1187,18 @@ function updateCalendarStatus(event) { } } - if (!list.length) { - list.push(UserLogin); - nodes[0].childNodesWithTag("input")[0].checked = true; - } +// if (!list.length) { +// list.push(UserLogin); +// nodes[0].childNodesWithTag("input")[0].checked = true; +// } + // ApplicationBaseURL = (UserFolderURL + "Groups/_custom_" // + list.join(",") + "/Calendar/"); if (event) { var folderID = this.parentNode.getAttribute("id"); var urlstr = URLForFolderID(folderID); - if (this.checked) + if (newStatus) urlstr += "/activateFolder"; else urlstr += "/deactivateFolder"; @@ -1189,22 +1218,22 @@ function updateCalendarStatus(event) { function calendarStatusCallback(http) { if (http.readyState == 4) { if (isHttpStatus204(http.status)) { - refreshEvents(); - refreshTasks(); - changeCalendarDisplay(); - } - else { - var folder = $(http.callbackData); - var input = folder.childNodesWithTag("input")[0]; - input.checked = (!input.checked); - } - } - else - log("calendarStatusCallback Ajax error"); + refreshEvents(); + refreshTasks(); + changeCalendarDisplay(); + } + else { + var folder = $(http.callbackData); + var input = folder.childNodesWithTag("input")[0]; + input.checked = (!input.checked); + } + } + else + log("calendarStatusCallback Ajax error"); } function calendarEntryCallback(http) { - if (http.readyState == 4) { + if (http.readyState == 4) { var denied = !isHttpStatus204(http.status); var entry = $(http.callbackData); if (denied) @@ -1286,7 +1315,10 @@ function getMenus() { editEvent, deleteEvent, "-", onSelectAll, "-", null, null); - menus["calendarsMenu"] = new Array(null, null, "-", null, null, "-", + menus["calendarsMenu"] = new Array(onMenuModify, + "-", + onCalendarNew, onCalendarRemove, + "-", null, null, "-", null, "-", onMenuSharing); menus["searchMenu"] = new Array(setSearchCriteria); @@ -1327,107 +1359,227 @@ function initCalendarSelector() { updateCalendarStatus(); selector.changeNotification = updateCalendarsList; - var list = $("calendarList").childNodesWithTag("li"); - for (var i = 0; i < list.length; i++) { - var input = list[i].childNodesWithTag("input")[0]; - Event.observe(input, "click", updateCalendarStatus.bindAsEventListener(input)); // not registered in IE? - //Event.observe(list[i], "mousedown", listRowMouseDownHandler, true); // problem with Safari - Event.observe(list[i], "click", onRowClick); + var list = $("calendarList"); + list.multiselect = true; + var items = list.childNodesWithTag("li"); + for (var i = 0; i < items.length; i++) { + var input = items[i].childNodesWithTag("input")[0]; + Event.observe(input, "click", updateCalendarStatus.bindAsEventListener(input)); + Event.observe(items[i], "mousedown", listRowMouseDownHandler); + Event.observe(items[i], "selectstart", listRowMouseDownHandler); + Event.observe(items[i], "click", onRowClick); } var links = $("calendarSelectorButtons").childNodesWithTag("a"); - Event.observe(links[0], "click", onCalendarAdd); - Event.observe(links[1], "click", onCalendarRemove); + Event.observe(links[0], "click", onCalendarNew); + Event.observe(links[1], "click", onCalendarAdd); + Event.observe(links[2], "click", onCalendarRemove); } -function onCalendarAdd(event) { - openUserFolderSelector(onFolderSubscribeCB, "calendar"); +function onMenuModify(event) { + var folders = $("calendarList"); + var selected = folders.getSelectedNodes()[0]; + + if (UserLogin == selected.getAttribute("owner")) { + var node = selected.childNodes[4]; + var currentName = node.nodeValue.trim(); + var newName = window.prompt(labels["Name of the Calendar"], + currentName); + if (newName && newName.length > 0 + && newName != currentName) { + var url = (URLForFolderID(selected.getAttribute("id")) + + "/renameFolder?name=" + escape(newName.utf8encode())); + triggerAjaxRequest(url, folderRenameCallback, + {node: node, name: " " + newName}); + } + } else + window.alert(clabels["Unable to rename that folder!"]); +} + +function folderRenameCallback(http) { + if (http.readyState == 4) { + if (isHttpStatus204(http.status)) { + var dict = http.callbackData; + dict["node"].nodeValue = dict["name"]; + } + } +} - preventDefault(event); +function onCalendarNew(event) { + createFolder(window.prompt(labels["Name of the Calendar"]), + appendCalendar); + preventDefault(event); } -function appendCalendar(folderName, folder) { - var calendarList = $("calendarList"); - var lis = calendarList.childNodesWithTag("li"); - var color = indexColor(lis.length); - log ("color: " + color); +function onCalendarAdd(event) { + openUserFolderSelector(onFolderSubscribeCB, "calendar"); + preventDefault(event); +} - var li = document.createElement("li"); - calendarList.appendChild(li); +function appendCalendar(folderName, folderPath) { + var owner; - var checkBox = document.createElement("input"); - li.appendChild(checkBox); - - li.appendChild(document.createTextNode(" ")); - - var colorBox = document.createElement("div"); - li.appendChild(colorBox); - li.appendChild(document.createTextNode(" " + folderName)); - colorBox.appendChild(document.createTextNode("OO")); - - li.setAttribute("id", folder); - Event.observe(li, "mousedown", listRowMouseDownHandler); - Event.observe(li, "click", onRowClick); - checkBox.addClassName("checkBox"); - checkBox.type = "checkbox"; - Event.observe(checkBox, "click", updateCalendarStatus.bindAsEventListener(checkBox)); - - colorBox.addClassName("colorBox"); - if (color) { - colorBox.setStyle({ color: color, - backgroundColor: color }); - } + if (folderPath) { + owner = getSubscribedFolderOwner(folderPath); + folderPath = accessToSubscribedFolder(folderPath); + } + else + folderPath = "/" + folderName; - var contactId = folder.split(":")[0]; - var styles = document.getElementsByTagName("style"); + if (!owner) + owner = UserLogin; - var url = URLForFolderID(folder) + "/canAccessContent"; - triggerAjaxRequest(url, calendarEntryCallback, folder); + //log ("append name: " + folderName + "; path: " + folderPath + "; owner: " + owner); - styles[0].innerHTML += ('.ownerIs' + contactId + ' {' - + ' background-color: ' - + color - + ' !important; }'); + if ($(folderPath)) + window.alert(clabels["You have already subscribed to that folder!"]); + else { + var calendarList = $("calendarList"); + var lis = calendarList.childNodesWithTag("li"); + var color = indexColor(lis.length + 100); + //log ("color: " + color); + + var li = document.createElement("li"); + + // Add the calendar to the proper place + var previousOwner = null; + for (var i = 1; i < lis.length; i++) { + var currentFolderName = lis[i].lastChild.nodeValue.strip(); + var currentOwner = lis[i].readAttribute('owner'); + if (currentOwner == owner) { + previousOwner = currentOwner; + if (currentFolderName > folderName) + break; + } + else if (previousOwner || + (currentOwner != UserLogin && currentOwner > owner)) + break; + } + if (i != lis.length) // User is subscribed to other calendars of the same owner + calendarList.insertBefore(li, lis[i]); + else + calendarList.appendChild(li); + + li.setAttribute("id", folderPath); + li.setAttribute("owner", owner); + + var checkBox = document.createElement("input"); + checkBox.setAttribute("type", "checkbox"); + li.appendChild(checkBox); + li.appendChild(document.createTextNode(" ")); + $(checkBox).addClassName("checkBox"); + + var colorBox = document.createElement("div"); + li.appendChild(colorBox); + li.appendChild(document.createTextNode(folderName)); + colorBox.appendChild(document.createTextNode("OO")); + + $(colorBox).addClassName("colorBox"); + $(colorBox).addClassName('calendarFolder' + folderPath.substr(1)); + + // Register events (doesn't work with Safari) + Event.observe(li, "mousedown", listRowMouseDownHandler); + Event.observe(li, "selectstart", listRowMouseDownHandler); + Event.observe(li, "click", onRowClick); + Event.observe(checkBox, "click", + updateCalendarStatus.bindAsEventListener(checkBox)); + + var url = URLForFolderID(folderPath) + "/canAccessContent"; + triggerAjaxRequest(url, calendarEntryCallback, folderPath); + + // Update CSS for events color + if (!document.styleSheets) return; + + var styleElement = document.createElement("style"); + styleElement.type = "text/css"; + var selectors = [ + '.calendarFolder' + folderPath.substr(1), + 'div.colorBox.calendarFolder' + folderPath.substr(1) + ]; + var rules = [ + ' { background-color: ' + color + ' !important; }', + ' { color: ' + color + ' !important; }' + ]; + for (var i = 0; i < rules.length; i++) + if (styleElement.styleSheet && styleElement.styleSheet.addRule) + styleElement.styleSheet.addRule(selectors[i], rules[i]); // IE + else + styleElement.appendChild(document.createTextNode(selectors[i] + rules[i])); // Mozilla _+ Safari + document.getElementsByTagName("head")[0].appendChild(styleElement); + } } function onFolderSubscribeCB(folderData) { - var folder = $(folderData["folder"]); + var folder = $(folderData["folder"]); if (!folder) - appendCalendar(folderData["folderName"], folderData["folder"]); + appendCalendar(folderData["folderName"], folderData["folder"]); } function onFolderUnsubscribeCB(folderId) { - var node = $(folderId); - node.parentNode.removeChild(node); + var node = $(folderId); + node.parentNode.removeChild(node); + if (removeFolderRequestCount == 0) { + refreshEvents(); + refreshTasks(); + changeCalendarDisplay(); + } } function onCalendarRemove(event) { - var nodes = $("calendarList").getSelectedNodes(); - if (nodes.length > 0) { - nodes[0].deselect(); - var folderId = nodes[0].getAttribute("id"); - var folderIdElements = folderId.split(":"); - if (folderIdElements.length > 1) { + if (removeFolderRequestCount == 0) { + var nodes = $("calendarList").getSelectedNodes(); + for (var i = 0; i < nodes.length; i++) { + nodes[i].deselect(); + var folderId = nodes[i].getAttribute("id"); + var folderIdElements = folderId.split("_"); + if (folderIdElements.length > 1) { unsubscribeFromFolder(folderId, onFolderUnsubscribeCB, folderId); - } + } + else + deletePersonalCalendar(folderIdElements[0]); + } } - + preventDefault(event); } -function configureSearchField() { - var searchValue = $("searchValue"); +function deletePersonalCalendar(folderElement) { + var folderId = folderElement.substr(1); + var label + = labels["Are you sure you want to delete the calendar \"%{0}\"?"].formatted($(folderElement).lastChild.nodeValue.strip()); + if (window.confirm(label)) { + removeFolderRequestCount++; + var url = ApplicationBaseURL + "/" + folderId + "/deleteFolder"; + triggerAjaxRequest(url, deletePersonalCalendarCallback, folderId); + } +} - Event.observe(searchValue, "mousedown", - onSearchMouseDown.bindAsEventListener(searchValue)); - Event.observe(searchValue, "click", - popupSearchMenu.bindAsEventListener(searchValue)); - Event.observe(searchValue, "blur", - onSearchBlur.bindAsEventListener(searchValue)); - Event.observe(searchValue, "focus", - onSearchFocus.bindAsEventListener(searchValue)); - Event.observe(searchValue, "keydown", - onSearchKeyDown.bindAsEventListener(searchValue)); +function deletePersonalCalendarCallback(http) { + if (http.readyState == 4) { + if (isHttpStatus204(http.status)) { + var ul = $("calendarList"); + var children = ul.childNodesWithTag("li"); + var i = 0; + var done = false; + while (!done && i < children.length) { + var currentFolderId = children[i].getAttribute("id").substr(1); + if (currentFolderId == http.callbackData) { + ul.removeChild(children[i]); + done = true; + } + else + i++; + } + removeFolderRequestCount--; + if (removeFolderRequestCount == 0) { + refreshEvents(); + refreshTasks(); + changeCalendarDisplay(); + } + } + } + else + log ("ajax problem 5: " + http.status); } function configureLists() { @@ -1442,6 +1594,8 @@ function configureLists() { list = $("eventsList"); list.multiselect = true; + //configureSortableTableHeaders(list); + TableKit.Resizable.init(list, {'trueResize' : true, 'keepWidth' : true}); Event.observe(list, "mousedown", onEventsSelectionChange.bindAsEventListener(list)); var div = list.parentNode;