7 var awaitingFreeBusyRequests = new Array();
8 var additionalDays = 2;
16 function onContactKeydown(event) {
17 if (event.keyCode == 9) {
18 preventDefault(event);
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 newRow.setAttribute("class", "");
191 tbody.insertBefore(newRow, newAttendeeRow);
192 //table.tBodies[0].appendChild(newRow);
193 var input = $(newRow.cells[0]).childNodesWithTag("input")[0];
194 input.setAttribute("autocomplete", "off");
195 input.serial = "pouet";
196 Event.observe(input, "blur", checkAttendee.bindAsEventListener(input));
197 Event.observe(input, "keydown", onContactKeydown.bindAsEventListener(input));
199 input.focussed = true;
202 function checkAttendee() {
203 this.focussed = false;
204 var th = this.parentNode.parentNode;
205 var tbody = th.parentNode;
206 if (this.value.trim().length == 0)
207 tbody.removeChild(th);
208 else if (!this.hasfreebusy) {
209 if (this.confirmedValue)
210 this.value = this.confirmedValue;
211 displayFreeBusyForNode(this);
212 this.hasfreebusy = true;
214 resetAttendeesValue();
217 function displayFreeBusyForNode(node) {
218 if (document.contactFreeBusyAjaxRequest)
219 awaitingFreeBusyRequests.push(node);
221 var nodes = node.parentNode.parentNode.cells;
223 for (var i = 1; i < nodes.length; i++) {
224 nodes[i].removeClassName("noFreeBusy");
225 nodes[i].innerHTML = ('<span class="freeBusyZoneElement"></span>'
226 + '<span class="freeBusyZoneElement"></span>'
227 + '<span class="freeBusyZoneElement"></span>'
228 + '<span class="freeBusyZoneElement"></span>');
230 if (document.contactFreeBusyAjaxRequest) {
231 document.contactFreeBusyAjaxRequest.aborted = true;
232 document.contactFreeBusyAjaxRequest.abort();
234 var sd = $('startTime_date').valueAsShortDateString();
235 var ed = $('endTime_date').valueAsShortDateString();
236 var urlstr = ( UserFolderURL + "../" + node.uid + "/freebusy.ifb/ajaxRead?"
237 + "sday=" + sd + "&eday=" + ed + "&additional=" +
239 document.contactFreeBusyAjaxRequest
240 = triggerAjaxRequest(urlstr,
244 for (var i = 1; i < nodes.length; i++) {
245 nodes[i].addClassName("noFreeBusy");
246 nodes[i].innerHTML = '';
252 function setSlot(tds, nbr, status) {
253 var tdnbr = Math.floor(nbr / 4);
254 var spannbr = nbr - (tdnbr * 4);
257 days = Math.floor(tdnbr / 24);
258 tdnbr -= (days * 24);
260 if (tdnbr > 7 && tdnbr < 19) {
261 var i = (days * 11 + tdnbr - 7);
263 var spans = $(td).childNodesWithTag("span");
265 spans[spannbr].addClassName("maybe-busy");
267 spans[spannbr].addClassName("busy");
271 function updateFreeBusyData(http) {
272 if (http.readyState == 4) {
273 if (http.status == 200) {
274 var node = http.callbackData;
275 var slots = http.responseText.split(",");
276 var tds = node.parentNode.parentNode.cells;
277 for (var i = 0; i < slots.length; i++) {
279 setSlot(tds, i, slots[i]);
282 document.contactFreeBusyAjaxRequest = null;
283 if (awaitingFreeBusyRequests.length > 0)
284 displayFreeBusyForNode(awaitingFreeBusyRequests.shift());
288 function resetAttendeesValue() {
289 var table = $("freeBusy");
290 var inputs = table.getElementsByTagName("input");
291 for (var i = 0; i < inputs.length - 2; i++) {
292 var currentInput = inputs[i];
293 var uid = currentInput.getAttribute("uid");
295 currentInput.uid = uid;
296 currentInput.setAttribute("uid", null);
298 currentInput.setAttribute("autocomplete", "off");
299 Event.observe(currentInput, "keydown", onContactKeydown.bindAsEventListener(currentInput), false);
300 Event.observe(currentInput, "blur", checkAttendee.bindAsEventListener(currentInput), false);
302 inputs[inputs.length - 2].setAttribute("autocomplete", "off");
303 Event.observe(inputs[inputs.length - 2], "click", newAttendee, false);
306 function resetAllFreeBusys() {
307 var table = $("freeBusy");
308 var inputs = table.getElementsByTagName("input");
310 for (var i = 0; i < inputs.length - 2; i++) {
311 var currentInput = inputs[i];
312 currentInput.hasfreebusy = false;
313 displayFreeBusyForNode(inputs[i]);
317 function initializeWindowButtons() {
318 var okButton = $("okButton");
319 var cancelButton = $("cancelButton");
321 Event.observe(okButton, "click", onEditorOkClick, false);
322 Event.observe(cancelButton, "click", onEditorCancelClick, false);
324 var buttons = $("freeBusyViewButtons").childNodesWithTag("a");
325 for (var i = 0; i < buttons.length; i++)
326 Event.observe(buttons[i], "click", listRowMouseDownHandler, false);
327 buttons = $("freeBusyZoomButtons").childNodesWithTag("a");
328 for (var i = 0; i < buttons.length; i++)
329 Event.observe(buttons[i], "click", listRowMouseDownHandler, false);
330 buttons = $("freeBusyButtons").childNodesWithTag("a");
331 for (var i = 0; i < buttons.length; i++)
332 Event.observe(buttons[i], "click", listRowMouseDownHandler, false);
335 function onEditorOkClick(event) {
336 preventDefault(event);
338 attendeesNames = new Array();
339 attendeesEmails = new Array();
341 var table = $("freeBusy");
342 var inputs = table.getElementsByTagName("input");
343 for (var i = 0; i < inputs.length - 2; i++) {
344 var name = extractEmailName(inputs[i].value);
345 if (!(name && name.length > 0))
346 name = inputs[i].uid;
347 var email = extractEmailAddress(inputs[i].value);
348 var pos = attendeesEmails.indexOf(email);
350 pos = attendeesEmails.length;
351 attendeesNames[pos] = name;
352 attendeesEmails[pos] = email;
355 parent$("attendeesNames").value = attendeesNames.join(",");
356 parent$("attendeesEmails").value = attendeesEmails.join(",");
357 window.opener.refreshAttendees();
359 updateParentDateFields("startTime", "startTime");
360 updateParentDateFields("endTime", "endTime");
365 function onEditorCancelClick(event) {
366 preventDefault(event);
370 function synchronizeWithParent(srcWidgetName, dstWidgetName) {
371 var srcDate = parent$(srcWidgetName + "_date");
372 var dstDate = $(dstWidgetName + "_date");
373 dstDate.value = srcDate.value;
375 var srcHour = parent$(srcWidgetName + "_time_hour");
376 var dstHour = $(dstWidgetName + "_time_hour");
377 dstHour.value = srcHour.value;
379 var srcMinute = parent$(srcWidgetName + "_time_minute");
380 var dstMinute = $(dstWidgetName + "_time_minute");
381 dstMinute.value = srcMinute.value;
384 function updateParentDateFields(srcWidgetName, dstWidgetName) {
385 var srcDate = $(srcWidgetName + "_date");
386 var dstDate = parent$(dstWidgetName + "_date");
387 dstDate.value = srcDate.value;
389 var srcHour = $(srcWidgetName + "_time_hour");
390 var dstHour = parent$(dstWidgetName + "_time_hour");
391 dstHour.value = srcHour.value;
393 var srcMinute = $(srcWidgetName + "_time_minute");
394 var dstMinute = parent$(dstWidgetName + "_time_minute");
395 dstMinute.value = srcMinute.value;
398 function initializeTimeWidgets() {
399 synchronizeWithParent("startTime", "startTime");
400 synchronizeWithParent("endTime", "endTime");
402 Event.observe($("startTime_date"), "change", onTimeDateWidgetChange, false);
403 Event.observe($("startTime_time_hour"), "change", onTimeWidgetChange, false);
404 Event.observe($("startTime_time_minute"), "change", onTimeWidgetChange, false);
406 Event.observe($("endTime_date"), "change", onTimeDateWidgetChange, false);
407 Event.observe($("endTime_time_hour"), "change", onTimeWidgetChange, false);
408 Event.observe($("endTime_time_minute"), "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);