7 var awaitingFreeBusyRequests = new Array();
8 var additionalDays = 2;
16 function onContactKeydown(event) {
17 if (event.keyCode == 9) {
18 event.preventDefault();
19 if (this.confirmedValue)
20 this.value = this.confirmedValue;
21 var row = this.parentNode.parentNode.nextSibling;
22 while (!(row instanceof HTMLTableRowElement))
23 row = row.nextSibling;
25 var input = row.cells[0].childNodesWithTag("input")[0];
31 input.focussed = true;
35 if (event.keyCode == 8
36 || event.keyCode == 32
37 || event.keyCode > 47) {
40 requestField.setAttribute("modified", "1");
41 setTimeout("triggerRequest()", delay);
43 else if (this.confirmedValue) {
44 if (event.keyCode == 13) {
45 this.setSelectionRange(this.value.length, this.value.length);
51 function triggerRequest() {
52 if (document.contactLookupAjaxRequest) {
53 document.contactLookupAjaxRequest.aborted = yes;
54 document.contactLookupAjaxRequest.abort();
56 var urlstr = ( UserFolderURL + "Contacts/contactSearch?search="
57 + requestField.value );
58 document.contactLookupAjaxRequest = triggerAjaxRequest(urlstr,
63 function updateResults(http) {
64 if (http.readyState == 4) {
65 if (http.status == 200) {
66 var searchField = http.callbackData;
67 var start = searchField.value.length;
68 var text = http.responseText.split(":");
69 if (text[0].length > 0)
70 searchField.uid = text[0];
72 searchField.uid = null;
73 searchField.hasfreebusy = false;
74 if (text[1].substring(0, searchField.value.length).toUpperCase()
75 == searchField.value.toUpperCase())
76 searchField.value = text[1];
78 searchField.value += ' >> ' + text[1];
80 searchField.confirmedValue = text[1];
81 if (searchField.focussed) {
82 var end = searchField.value.length;
83 searchField.setSelectionRange(start, end);
86 searchField.value = text[1];
89 document.contactLookupAjaxRequest = null;
93 function resetFreeBusyZone() {
94 var table = $("freeBusy");
95 var row = table.tHead.rows[2];
96 for (var i = 1; i < row.cells.length; i++) {
97 var nodes = row.cells[i].childNodesWithTag("span");
98 for (var j = 0; j < nodes.length; j++)
99 nodes[j].removeClassName("busy");
103 function redisplayFreeBusyZone() {
104 var table = $("freeBusy");
105 var row = table.tHead.rows[2];
106 var stDay = $("startTime_date").valueAsDate();
107 var etDay = $("endTime_date").valueAsDate();
109 var days = stDay.daysUpTo(etDay);
110 var addDays = days.length - 1;
111 var stHour = parseInt($("startTime_time_hour").value);
112 var stMinute = parseInt($("startTime_time_minute").value) / 15;
113 var etHour = parseInt($("endTime_time_hour").value);
114 var etMinute = parseInt($("endTime_time_minute").value) / 15;
131 if (stHour > etHour) {
139 if (stMinute > etMinute) {
146 var deltaCells = (etHour - stHour) + (11 * addDays);
147 var deltaSpans = (deltaCells * 4 ) + (etMinute - stMinute);
148 var currentCellNbr = stHour - 7;
149 var currentCell = row.cells[currentCellNbr];
150 var currentSpanNbr = stMinute;
151 var spans = currentCell.childNodesWithTag("span");
153 while (deltaSpans > 0) {
154 var currentSpan = spans[currentSpanNbr];
155 currentSpan.addClassName("busy");
157 if (currentSpanNbr > 3) {
160 currentCell = row.cells[currentCellNbr];
161 spans = currentCell.childNodesWithTag("span");
167 function newAttendee(event) {
168 var table = $("freeBusy");
169 var tbody = table.tBodies[0];
170 var model = tbody.rows[tbody.rows.length - 1];
171 var newAttendeeRow = tbody.rows[tbody.rows.length - 2]
172 var newRow = model.cloneNode(true);
173 var input = newRow.cells[0].childNodesWithTag("input")[0];
174 input.setAttribute("autocomplete", "off");
175 newRow.setAttribute("class", "");
176 tbody.insertBefore(newRow, newAttendeeRow);
177 input.serial = "pouet";
178 input.addEventListener("blur", checkAttendee, false);
179 input.addEventListener("keydown", onContactKeydown, false);
181 input.focussed = true;
184 function checkAttendee() {
185 this.focussed = false;
186 var th = this.parentNode.parentNode;
187 var tbody = th.parentNode;
188 if (this.value.trim().length == 0)
189 tbody.removeChild(th);
190 else if (!this.hasfreebusy) {
191 if (this.confirmedValue)
192 this.value = this.confirmedValue;
193 displayFreeBusyForNode(this);
194 this.hasfreebusy = true;
196 resetAttendeesValue();
199 function displayFreeBusyForNode(node) {
200 var nodes = node.parentNode.parentNode.cells;
202 for (var i = 1; i < nodes.length; i++) {
203 nodes[i].removeClassName("noFreeBusy");
204 nodes[i].innerHTML = ('<span class="freeBusyZoneElement"></span>'
205 + '<span class="freeBusyZoneElement"></span>'
206 + '<span class="freeBusyZoneElement"></span>'
207 + '<span class="freeBusyZoneElement"></span>');
209 if (document.contactFreeBusyAjaxRequest) {
210 document.contactFreeBusyAjaxRequest.aborted = true;
211 document.contactFreeBusyAjaxRequest.abort();
213 var sd = $('startTime_date').valueAsShortDateString();
214 var ed = $('endTime_date').valueAsShortDateString();
215 var urlstr = ( UserFolderURL + "../" + node.uid + "/freebusy.ifb/ajaxRead?"
216 + "sday=" + sd + "&eday=" + ed + "&additional=" + additionalDays );
217 document.contactFreeBusyAjaxRequest
218 = triggerAjaxRequest(urlstr,
222 for (var i = 1; i < nodes.length; i++) {
223 nodes[i].addClassName("noFreeBusy");
224 nodes[i].innerHTML = '';
229 function setSlot(tds, nbr, status) {
230 var tdnbr = Math.floor(nbr / 4);
231 var spannbr = nbr - (tdnbr * 4);
234 days = Math.floor(tdnbr / 24);
235 tdnbr -= (days * 24);
237 if (tdnbr > 7 && tdnbr < 19) {
238 var i = (days * 11 + tdnbr - 7);
240 var spans = td.childNodesWithTag("span");
242 spans[spannbr].addClassName("maybe-busy");
244 spans[spannbr].addClassName("busy");
248 function updateFreeBusyData(http) {
249 if (http.readyState == 4) {
250 if (http.status == 200) {
251 var node = http.callbackData;
252 var slots = http.responseText.split(",");
253 var tds = node.parentNode.parentNode.cells;
254 for (var i = 0; i < slots.length; i++) {
256 setSlot(tds, i, slots[i]);
259 document.contactFreeBusyAjaxRequest = null;
260 if (awaitingFreeBusyRequests.length > 0)
261 displayFreeBusyForNode(awaitingFreeBusyRequests.shift());
265 function resetAttendeesValue() {
266 var table = $("freeBusy");
267 var inputs = table.getElementsByTagName("input");
268 var uids = new Array();
269 for (var i = 0; i < inputs.length - 2; i++) {
270 var currentInput = inputs[i];
271 var uid = currentInput.getAttribute("uid");
273 currentInput.uid = uid;
274 currentInput.setAttribute("uid", null);
276 uids.push(currentInput.uid);
277 currentInput.setAttribute("autocomplete", "off");
278 currentInput.addEventListener("keydown", onContactKeydown, false);
279 currentInput.addEventListener("blur", checkAttendee, false);
281 inputs[inputs.length - 2].setAttribute("autocomplete", "off");
282 inputs[inputs.length - 2].addEventListener("click", newAttendee, false);
285 function resetAllFreeBusys() {
286 var table = $("freeBusy");
287 var inputs = table.getElementsByTagName("input");
289 for (var i = 0; i < inputs.length - 2; i++) {
290 var currentInput = inputs[i];
291 currentInput.hasfreebusy = false;
292 // log ("input: " + currentInput.uid);
293 awaitingFreeBusyRequests.push(currentInput);
295 if (awaitingFreeBusyRequests.length > 0)
296 displayFreeBusyForNode(awaitingFreeBusyRequests.shift());
299 function initializeWindowButtons() {
300 var okButton = $("okButton");
301 var cancelButton = $("cancelButton");
303 okButton.addEventListener("click", onEditorOkClick, false);
304 cancelButton.addEventListener("click", onEditorCancelClick, false);
306 var buttons = $("freeBusyViewButtons").childNodesWithTag("a");
307 for (var i = 0; i < buttons.length; i++)
308 buttons[i].addEventListener("click", listRowMouseDownHandler, false);
309 buttons = $("freeBusyZoomButtons").childNodesWithTag("a");
310 for (var i = 0; i < buttons.length; i++)
311 buttons[i].addEventListener("click", listRowMouseDownHandler, false);
312 buttons = $("freeBusyButtons").childNodesWithTag("a");
313 for (var i = 0; i < buttons.length; i++)
314 buttons[i].addEventListener("click", listRowMouseDownHandler, false);
317 function onEditorOkClick(event) {
318 event.preventDefault();
320 attendeesNames = new Array();
321 attendeesEmails = new Array();
323 var table = $("freeBusy");
324 var inputs = table.getElementsByTagName("input");
325 for (var i = 0; i < inputs.length - 2; i++) {
326 var name = inputs[i].uid;
327 if (!(name && name.length > 0)) {
328 name = extractEmailName(inputs[i].value);
329 log ("name: " + name);
331 var email = extractEmailAddress(inputs[i].value);
332 var pos = attendeesEmails.indexOf(email);
334 pos = attendeesEmails.length;
335 attendeesNames[pos] = name;
336 attendeesEmails[pos] = email;
339 parent$("attendeesNames").value = attendeesNames.join(",");
340 parent$("attendeesEmails").value = attendeesEmails.join(",");
341 window.opener.refreshAttendees();
343 updateParentDateFields("startTime", "startTime");
344 updateParentDateFields("endTime", "endTime");
349 function onEditorCancelClick(event) {
350 event.preventDefault();
354 function synchronizeWithParent(srcWidgetName, dstWidgetName) {
355 var srcDate = parent$(srcWidgetName + "_date");
356 var dstDate = $(dstWidgetName + "_date");
357 dstDate.value = srcDate.value;
359 var srcHour = parent$(srcWidgetName + "_time_hour");
360 var dstHour = $(dstWidgetName + "_time_hour");
361 dstHour.value = srcHour.value;
363 var srcMinute = parent$(srcWidgetName + "_time_minute");
364 var dstMinute = $(dstWidgetName + "_time_minute");
365 dstMinute.value = srcMinute.value;
368 function updateParentDateFields(srcWidgetName, dstWidgetName) {
369 var srcDate = $(srcWidgetName + "_date");
370 var dstDate = parent$(dstWidgetName + "_date");
371 dstDate.value = srcDate.value;
373 var srcHour = $(srcWidgetName + "_time_hour");
374 var dstHour = parent$(dstWidgetName + "_time_hour");
375 dstHour.value = srcHour.value;
377 var srcMinute = $(srcWidgetName + "_time_minute");
378 var dstMinute = parent$(dstWidgetName + "_time_minute");
379 dstMinute.value = srcMinute.value;
382 function initializeTimeWidgets() {
383 synchronizeWithParent("startTime", "startTime");
384 synchronizeWithParent("endTime", "endTime");
386 $("startTime_date").addEventListener("change", onTimeDateWidgetChange, false);
387 $("startTime_time_hour").addEventListener("change", onTimeWidgetChange, false);
388 $("startTime_time_minute").addEventListener("change", onTimeWidgetChange,
391 $("endTime_date").addEventListener("change", onTimeDateWidgetChange, false);
392 $("endTime_time_hour").addEventListener("change", onTimeWidgetChange, false);
393 $("endTime_time_minute").addEventListener("change", onTimeWidgetChange, false);
396 function onTimeWidgetChange() {
397 redisplayFreeBusyZone();
400 function onTimeDateWidgetChange(event) {
401 var table = $("freeBusy");
403 var rows = table.tHead.rows;
404 for (var i = 0; i < rows.length; i++) {
405 for (var j = rows[i].cells.length - 1; j > 0; j--) {
406 rows[i].deleteCell(j);
410 rows = table.tBodies[0].rows;
411 for (var i = 0; i < rows.length; i++) {
412 for (var j = rows[i].cells.length - 1; j > 0; j--) {
413 rows[i].deleteCell(j);
417 prepareTableHeaders();
419 redisplayFreeBusyZone();
420 resetAttendeesValue();
424 function prepareTableHeaders() {
425 var startTimeDate = $("startTime_date");
426 var startDate = startTimeDate.valueAsDate();
428 var endTimeDate = $("endTime_date");
429 var endDate = endTimeDate.valueAsDate();
430 endDate.setTime(endDate.getTime() + (additionalDays * 86400000));
432 var rows = $("freeBusy").tHead.rows;
433 var days = startDate.daysUpTo(endDate);
434 for (var i = 0; i < days.length; i++) {
435 var header1 = document.createElement("th");
436 header1.colSpan = (dayEndHour - dayStartHour) + 1;
437 header1.appendChild(document.createTextNode(days[i].toLocaleDateString()));
438 rows[0].appendChild(header1);
439 for (var hour = dayStartHour; hour < (dayEndHour + 1); hour++) {
440 var header2 = document.createElement("th");
441 var text = hour + ":00";
444 header2.appendChild(document.createTextNode(text));
445 rows[1].appendChild(header2);
447 var header3 = document.createElement("th");
448 for (var span = 0; span < 4; span++) {
449 var spanElement = document.createElement("span");
450 spanElement.addClassName("freeBusyZoneElement");
451 header3.appendChild(spanElement);
453 rows[2].appendChild(header3);
458 function prepareTableRows() {
459 var startTimeDate = $("startTime_date");
460 var startDate = startTimeDate.valueAsDate();
462 var endTimeDate = $("endTime_date");
463 var endDate = endTimeDate.valueAsDate();
464 endDate.setTime(endDate.getTime() + (additionalDays * 86400000));
466 var rows = $("freeBusy").tBodies[0].rows;
467 var days = startDate.daysUpTo(endDate);
468 for (var i = 0; i < days.length; i++) {
469 for (var rowNbr = 0; rowNbr < rows.length; rowNbr++) {
470 for (var hour = dayStartHour; hour < (dayEndHour + 1); hour++) {
471 var cell = document.createElement("td");
472 rows[rowNbr].appendChild(cell);
478 function prepareAttendees() {
479 var value = parent$("attendeesNames").value;
480 if (value.length > 0) {
481 attendeesNames = parent$("attendeesNames").value.split(",");
482 attendeesEmails = parent$("attendeesEmails").value.split(",");
484 var body = $("freeBusy").tBodies[0];
485 for (var i = 0; i < attendeesNames.length; i++) {
486 var tr = body.insertRow(i);
487 var td = document.createElement("td");
488 td.addClassName("attendees");
489 var input = document.createElement("input");
491 if (attendeesNames[i].length > 0)
492 value += attendeesNames[i] + " ";
493 value += "<" + attendeesEmails[i] + ">";
495 input.setAttribute("uid", attendeesNames[i]);
496 input.addClassName("textField");
497 input.setAttribute("modified", "0");
499 td.appendChild(input)
503 attendeesNames = new Array();
504 attendeesEmails = new Array();
508 function onFreeBusyLoadHandler() {
509 initializeWindowButtons();
510 initializeTimeWidgets();
512 prepareTableHeaders();
514 redisplayFreeBusyZone();
515 resetAttendeesValue();
519 window.addEventListener("load", onFreeBusyLoadHandler, false);