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 var completeEmail = text[1] + " <" + text[2] + ">";
75 if (text[1].substring(0, searchField.value.length).toUpperCase()
76 == searchField.value.toUpperCase())
77 searchField.value = completeEmail;
79 searchField.value += ' >> ' + completeEmail;
81 searchField.confirmedValue = completeEmail;
82 if (searchField.focussed) {
83 var end = searchField.value.length;
84 searchField.setSelectionRange(start, end);
87 searchField.value = text[1];
90 document.contactLookupAjaxRequest = null;
94 function UIDLookupCallback(http) {
95 if (http.readyState == 4) {
96 if (http.status == 200) {
97 var searchField = http.callbackData;
98 var start = searchField.value.length;
99 var text = http.responseText.split(":");
100 if (text[0].length > 0) {
101 searchField.uid = text[0];
102 displayFreeBusyForNode(searchField);
105 searchField.uid = null
110 function resetFreeBusyZone() {
111 var table = $("freeBusy");
112 var row = table.tHead.rows[2];
113 for (var i = 1; i < row.cells.length; i++) {
114 var nodes = row.cells[i].childNodesWithTag("span");
115 for (var j = 0; j < nodes.length; j++)
116 nodes[j].removeClassName("busy");
120 function redisplayFreeBusyZone() {
121 var table = $("freeBusy");
122 var row = table.tHead.rows[2];
123 var stDay = $("startTime_date").valueAsDate();
124 var etDay = $("endTime_date").valueAsDate();
126 var days = stDay.daysUpTo(etDay);
127 var addDays = days.length - 1;
128 var stHour = parseInt($("startTime_time_hour").value);
129 var stMinute = parseInt($("startTime_time_minute").value) / 15;
130 var etHour = parseInt($("endTime_time_hour").value);
131 var etMinute = parseInt($("endTime_time_minute").value) / 15;
148 if (stHour > etHour) {
156 if (stMinute > etMinute) {
163 var deltaCells = (etHour - stHour) + (11 * addDays);
164 var deltaSpans = (deltaCells * 4 ) + (etMinute - stMinute);
165 var currentCellNbr = stHour - 7;
166 var currentCell = row.cells[currentCellNbr];
167 var currentSpanNbr = stMinute;
168 var spans = currentCell.childNodesWithTag("span");
170 while (deltaSpans > 0) {
171 var currentSpan = spans[currentSpanNbr];
172 currentSpan.addClassName("busy");
174 if (currentSpanNbr > 3) {
177 currentCell = row.cells[currentCellNbr];
178 spans = currentCell.childNodesWithTag("span");
184 function newAttendee(event) {
185 var table = $("freeBusy");
186 var tbody = table.tBodies[0];
187 var model = tbody.rows[tbody.rows.length - 1];
188 var newAttendeeRow = tbody.rows[tbody.rows.length - 2]
189 var newRow = model.cloneNode(true);
190 var input = newRow.cells[0].childNodesWithTag("input")[0];
191 input.setAttribute("autocomplete", "off");
192 newRow.setAttribute("class", "");
193 tbody.insertBefore(newRow, newAttendeeRow);
194 input.serial = "pouet";
195 input.addEventListener("blur", checkAttendee, false);
196 input.addEventListener("keydown", onContactKeydown, false);
198 input.focussed = true;
201 function checkAttendee() {
202 this.focussed = false;
203 var th = this.parentNode.parentNode;
204 var tbody = th.parentNode;
205 if (this.value.trim().length == 0)
206 tbody.removeChild(th);
207 else if (!this.hasfreebusy) {
208 if (this.confirmedValue)
209 this.value = this.confirmedValue;
210 displayFreeBusyForNode(this);
211 this.hasfreebusy = true;
213 resetAttendeesValue();
216 function displayFreeBusyForNode(node) {
217 if (document.contactFreeBusyAjaxRequest)
218 awaitingFreeBusyRequests.push(node);
220 var nodes = node.parentNode.parentNode.cells;
222 for (var i = 1; i < nodes.length; i++) {
223 nodes[i].removeClassName("noFreeBusy");
224 nodes[i].innerHTML = ('<span class="freeBusyZoneElement"></span>'
225 + '<span class="freeBusyZoneElement"></span>'
226 + '<span class="freeBusyZoneElement"></span>'
227 + '<span class="freeBusyZoneElement"></span>');
229 if (document.contactFreeBusyAjaxRequest) {
230 document.contactFreeBusyAjaxRequest.aborted = true;
231 document.contactFreeBusyAjaxRequest.abort();
233 var sd = $('startTime_date').valueAsShortDateString();
234 var ed = $('endTime_date').valueAsShortDateString();
235 var urlstr = ( UserFolderURL + "../" + node.uid + "/freebusy.ifb/ajaxRead?"
236 + "sday=" + sd + "&eday=" + ed + "&additional=" +
238 document.contactFreeBusyAjaxRequest
239 = triggerAjaxRequest(urlstr,
243 for (var i = 1; i < nodes.length; i++) {
244 nodes[i].addClassName("noFreeBusy");
245 nodes[i].innerHTML = '';
251 function setSlot(tds, nbr, status) {
252 var tdnbr = Math.floor(nbr / 4);
253 var spannbr = nbr - (tdnbr * 4);
256 days = Math.floor(tdnbr / 24);
257 tdnbr -= (days * 24);
259 if (tdnbr > 7 && tdnbr < 19) {
260 var i = (days * 11 + tdnbr - 7);
262 var spans = td.childNodesWithTag("span");
264 spans[spannbr].addClassName("maybe-busy");
266 spans[spannbr].addClassName("busy");
270 function updateFreeBusyData(http) {
271 if (http.readyState == 4) {
272 if (http.status == 200) {
273 var node = http.callbackData;
274 var slots = http.responseText.split(",");
275 var tds = node.parentNode.parentNode.cells;
276 for (var i = 0; i < slots.length; i++) {
278 setSlot(tds, i, slots[i]);
281 document.contactFreeBusyAjaxRequest = null;
282 if (awaitingFreeBusyRequests.length > 0)
283 displayFreeBusyForNode(awaitingFreeBusyRequests.shift());
287 function resetAttendeesValue() {
288 var table = $("freeBusy");
289 var inputs = table.getElementsByTagName("input");
290 for (var i = 0; i < inputs.length - 2; i++) {
291 var currentInput = inputs[i];
292 var uid = currentInput.getAttribute("uid");
294 currentInput.uid = uid;
295 currentInput.setAttribute("uid", null);
297 currentInput.setAttribute("autocomplete", "off");
298 currentInput.addEventListener("keydown", onContactKeydown, false);
299 currentInput.addEventListener("blur", checkAttendee, false);
301 inputs[inputs.length - 2].setAttribute("autocomplete", "off");
302 inputs[inputs.length - 2].addEventListener("click", newAttendee, false);
305 function resetAllFreeBusys() {
306 var table = $("freeBusy");
307 var inputs = table.getElementsByTagName("input");
309 for (var i = 0; i < inputs.length - 2; i++) {
310 var currentInput = inputs[i];
311 currentInput.hasfreebusy = false;
312 displayFreeBusyForNode(inputs[i]);
316 function initializeWindowButtons() {
317 var okButton = $("okButton");
318 var cancelButton = $("cancelButton");
320 okButton.addEventListener("click", onEditorOkClick, false);
321 cancelButton.addEventListener("click", onEditorCancelClick, false);
323 var buttons = $("freeBusyViewButtons").childNodesWithTag("a");
324 for (var i = 0; i < buttons.length; i++)
325 buttons[i].addEventListener("click", listRowMouseDownHandler, false);
326 buttons = $("freeBusyZoomButtons").childNodesWithTag("a");
327 for (var i = 0; i < buttons.length; i++)
328 buttons[i].addEventListener("click", listRowMouseDownHandler, false);
329 buttons = $("freeBusyButtons").childNodesWithTag("a");
330 for (var i = 0; i < buttons.length; i++)
331 buttons[i].addEventListener("click", listRowMouseDownHandler, false);
334 function onEditorOkClick(event) {
335 event.preventDefault();
337 attendeesNames = new Array();
338 attendeesEmails = new Array();
340 var table = $("freeBusy");
341 var inputs = table.getElementsByTagName("input");
342 for (var i = 0; i < inputs.length - 2; i++) {
343 var name = extractEmailName(inputs[i].value);
344 if (!(name && name.length > 0))
345 name = inputs[i].uid;
346 var email = extractEmailAddress(inputs[i].value);
347 var pos = attendeesEmails.indexOf(email);
349 pos = attendeesEmails.length;
350 attendeesNames[pos] = name;
351 attendeesEmails[pos] = email;
354 parent$("attendeesNames").value = attendeesNames.join(",");
355 parent$("attendeesEmails").value = attendeesEmails.join(",");
356 window.opener.refreshAttendees();
358 updateParentDateFields("startTime", "startTime");
359 updateParentDateFields("endTime", "endTime");
364 function onEditorCancelClick(event) {
365 event.preventDefault();
369 function synchronizeWithParent(srcWidgetName, dstWidgetName) {
370 var srcDate = parent$(srcWidgetName + "_date");
371 var dstDate = $(dstWidgetName + "_date");
372 dstDate.value = srcDate.value;
374 var srcHour = parent$(srcWidgetName + "_time_hour");
375 var dstHour = $(dstWidgetName + "_time_hour");
376 dstHour.value = srcHour.value;
378 var srcMinute = parent$(srcWidgetName + "_time_minute");
379 var dstMinute = $(dstWidgetName + "_time_minute");
380 dstMinute.value = srcMinute.value;
383 function updateParentDateFields(srcWidgetName, dstWidgetName) {
384 var srcDate = $(srcWidgetName + "_date");
385 var dstDate = parent$(dstWidgetName + "_date");
386 dstDate.value = srcDate.value;
388 var srcHour = $(srcWidgetName + "_time_hour");
389 var dstHour = parent$(dstWidgetName + "_time_hour");
390 dstHour.value = srcHour.value;
392 var srcMinute = $(srcWidgetName + "_time_minute");
393 var dstMinute = parent$(dstWidgetName + "_time_minute");
394 dstMinute.value = srcMinute.value;
397 function initializeTimeWidgets() {
398 synchronizeWithParent("startTime", "startTime");
399 synchronizeWithParent("endTime", "endTime");
401 $("startTime_date").addEventListener("change", onTimeDateWidgetChange, false);
402 $("startTime_time_hour").addEventListener("change", onTimeWidgetChange, false);
403 $("startTime_time_minute").addEventListener("change", onTimeWidgetChange,
406 $("endTime_date").addEventListener("change", onTimeDateWidgetChange, false);
407 $("endTime_time_hour").addEventListener("change", onTimeWidgetChange, false);
408 $("endTime_time_minute").addEventListener("change", onTimeWidgetChange, false);
411 function onTimeWidgetChange() {
412 redisplayFreeBusyZone();
415 function onTimeDateWidgetChange(event) {
416 var table = $("freeBusy");
418 var rows = table.tHead.rows;
419 for (var i = 0; i < rows.length; i++) {
420 for (var j = rows[i].cells.length - 1; j > 0; j--) {
421 rows[i].deleteCell(j);
425 rows = table.tBodies[0].rows;
426 for (var i = 0; i < rows.length; i++) {
427 for (var j = rows[i].cells.length - 1; j > 0; j--) {
428 rows[i].deleteCell(j);
432 prepareTableHeaders();
434 redisplayFreeBusyZone();
435 resetAttendeesValue();
439 function prepareTableHeaders() {
440 var startTimeDate = $("startTime_date");
441 var startDate = startTimeDate.valueAsDate();
443 var endTimeDate = $("endTime_date");
444 var endDate = endTimeDate.valueAsDate();
445 endDate.setTime(endDate.getTime() + (additionalDays * 86400000));
447 var rows = $("freeBusy").tHead.rows;
448 var days = startDate.daysUpTo(endDate);
449 for (var i = 0; i < days.length; i++) {
450 var header1 = document.createElement("th");
451 header1.colSpan = (dayEndHour - dayStartHour) + 1;
452 header1.appendChild(document.createTextNode(days[i].toLocaleDateString()));
453 rows[0].appendChild(header1);
454 for (var hour = dayStartHour; hour < (dayEndHour + 1); hour++) {
455 var header2 = document.createElement("th");
456 var text = hour + ":00";
459 header2.appendChild(document.createTextNode(text));
460 rows[1].appendChild(header2);
462 var header3 = document.createElement("th");
463 for (var span = 0; span < 4; span++) {
464 var spanElement = document.createElement("span");
465 spanElement.addClassName("freeBusyZoneElement");
466 header3.appendChild(spanElement);
468 rows[2].appendChild(header3);
473 function prepareTableRows() {
474 var startTimeDate = $("startTime_date");
475 var startDate = startTimeDate.valueAsDate();
477 var endTimeDate = $("endTime_date");
478 var endDate = endTimeDate.valueAsDate();
479 endDate.setTime(endDate.getTime() + (additionalDays * 86400000));
481 var rows = $("freeBusy").tBodies[0].rows;
482 var days = startDate.daysUpTo(endDate);
483 for (var i = 0; i < days.length; i++)
484 for (var rowNbr = 0; rowNbr < rows.length; rowNbr++)
485 for (var hour = dayStartHour; hour < (dayEndHour + 1); hour++)
486 rows[rowNbr].appendChild(document.createElement("td"));
489 function prepareAttendees() {
490 var value = parent$("attendeesNames").value;
491 if (value.length > 0) {
492 attendeesNames = parent$("attendeesNames").value.split(",");
493 attendeesEmails = parent$("attendeesEmails").value.split(",");
495 var body = $("freeBusy").tBodies[0];
496 for (var i = 0; i < attendeesNames.length; i++) {
497 var tr = body.insertRow(i);
498 var td = document.createElement("td");
499 td.addClassName("attendees");
500 var input = document.createElement("input");
502 if (attendeesNames[i].length > 0)
503 value += attendeesNames[i] + " ";
504 value += "<" + attendeesEmails[i] + ">";
506 input.addClassName("textField");
507 input.setAttribute("modified", "0");
509 td.appendChild(input);
510 displayFreeBusyForNode(input);
514 attendeesNames = new Array();
515 attendeesEmails = new Array();
519 function initializeFreebusys() {
520 var inputs = $("freeBusy").getElementsByTagName("input");
521 var baseUrl = UserFolderURL + "Contacts/contactSearch?search=";
522 for (var i = 0; i < attendeesEmails.length; i++)
523 triggerAjaxRequest(baseUrl + attendeesEmails[i],
524 UIDLookupCallback, inputs[i]);
527 function onFreeBusyLoadHandler() {
528 initializeWindowButtons();
529 initializeTimeWidgets();
531 prepareTableHeaders();
533 redisplayFreeBusyZone();
534 resetAttendeesValue();
535 initializeFreebusys();
538 window.addEventListener("load", onFreeBusyLoadHandler, false);