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];
103 searchField.uid = null;
108 function resetFreeBusyZone() {
109 var table = $("freeBusy");
110 var row = table.tHead.rows[2];
111 for (var i = 1; i < row.cells.length; i++) {
112 var nodes = row.cells[i].childNodesWithTag("span");
113 for (var j = 0; j < nodes.length; j++)
114 nodes[j].removeClassName("busy");
118 function redisplayFreeBusyZone() {
119 var table = $("freeBusy");
120 var row = table.tHead.rows[2];
121 var stDay = $("startTime_date").valueAsDate();
122 var etDay = $("endTime_date").valueAsDate();
124 var days = stDay.daysUpTo(etDay);
125 var addDays = days.length - 1;
126 var stHour = parseInt($("startTime_time_hour").value);
127 var stMinute = parseInt($("startTime_time_minute").value) / 15;
128 var etHour = parseInt($("endTime_time_hour").value);
129 var etMinute = parseInt($("endTime_time_minute").value) / 15;
146 if (stHour > etHour) {
154 if (stMinute > etMinute) {
161 var deltaCells = (etHour - stHour) + (11 * addDays);
162 var deltaSpans = (deltaCells * 4 ) + (etMinute - stMinute);
163 var currentCellNbr = stHour - 7;
164 var currentCell = row.cells[currentCellNbr];
165 var currentSpanNbr = stMinute;
166 var spans = currentCell.childNodesWithTag("span");
168 while (deltaSpans > 0) {
169 var currentSpan = spans[currentSpanNbr];
170 currentSpan.addClassName("busy");
172 if (currentSpanNbr > 3) {
175 currentCell = row.cells[currentCellNbr];
176 spans = currentCell.childNodesWithTag("span");
182 function newAttendee(event) {
183 var table = $("freeBusy");
184 var tbody = table.tBodies[0];
185 var model = tbody.rows[tbody.rows.length - 1];
186 var newAttendeeRow = tbody.rows[tbody.rows.length - 2]
187 var newRow = model.cloneNode(true);
188 var input = newRow.cells[0].childNodesWithTag("input")[0];
189 input.setAttribute("autocomplete", "off");
190 newRow.setAttribute("class", "");
191 tbody.insertBefore(newRow, newAttendeeRow);
192 input.serial = "pouet";
193 input.addEventListener("blur", checkAttendee, false);
194 input.addEventListener("keydown", onContactKeydown, false);
196 input.focussed = true;
199 function checkAttendee() {
200 this.focussed = false;
201 var th = this.parentNode.parentNode;
202 var tbody = th.parentNode;
203 if (this.value.trim().length == 0)
204 tbody.removeChild(th);
205 else if (!this.hasfreebusy) {
206 if (this.confirmedValue)
207 this.value = this.confirmedValue;
208 displayFreeBusyForNode(this);
209 this.hasfreebusy = true;
211 resetAttendeesValue();
214 function displayFreeBusyForNode(node) {
215 var nodes = node.parentNode.parentNode.cells;
217 for (var i = 1; i < nodes.length; i++) {
218 nodes[i].removeClassName("noFreeBusy");
219 nodes[i].innerHTML = ('<span class="freeBusyZoneElement"></span>'
220 + '<span class="freeBusyZoneElement"></span>'
221 + '<span class="freeBusyZoneElement"></span>'
222 + '<span class="freeBusyZoneElement"></span>');
224 if (document.contactFreeBusyAjaxRequest) {
225 document.contactFreeBusyAjaxRequest.aborted = true;
226 document.contactFreeBusyAjaxRequest.abort();
228 var sd = $('startTime_date').valueAsShortDateString();
229 var ed = $('endTime_date').valueAsShortDateString();
230 var urlstr = ( UserFolderURL + "../" + node.uid + "/freebusy.ifb/ajaxRead?"
231 + "sday=" + sd + "&eday=" + ed + "&additional=" + additionalDays );
232 document.contactFreeBusyAjaxRequest
233 = triggerAjaxRequest(urlstr,
237 for (var i = 1; i < nodes.length; i++) {
238 nodes[i].addClassName("noFreeBusy");
239 nodes[i].innerHTML = '';
244 function setSlot(tds, nbr, status) {
245 var tdnbr = Math.floor(nbr / 4);
246 var spannbr = nbr - (tdnbr * 4);
249 days = Math.floor(tdnbr / 24);
250 tdnbr -= (days * 24);
252 if (tdnbr > 7 && tdnbr < 19) {
253 var i = (days * 11 + tdnbr - 7);
255 var spans = td.childNodesWithTag("span");
257 spans[spannbr].addClassName("maybe-busy");
259 spans[spannbr].addClassName("busy");
263 function updateFreeBusyData(http) {
264 if (http.readyState == 4) {
265 if (http.status == 200) {
266 var node = http.callbackData;
267 var slots = http.responseText.split(",");
268 var tds = node.parentNode.parentNode.cells;
269 for (var i = 0; i < slots.length; i++) {
271 setSlot(tds, i, slots[i]);
274 document.contactFreeBusyAjaxRequest = null;
275 if (awaitingFreeBusyRequests.length > 0)
276 displayFreeBusyForNode(awaitingFreeBusyRequests.shift());
280 function resetAttendeesValue() {
281 var table = $("freeBusy");
282 var inputs = table.getElementsByTagName("input");
283 var uids = new Array();
284 for (var i = 0; i < inputs.length - 2; i++) {
285 var currentInput = inputs[i];
286 var uid = currentInput.getAttribute("uid");
288 currentInput.uid = uid;
289 currentInput.setAttribute("uid", null);
291 uids.push(currentInput.uid);
292 currentInput.setAttribute("autocomplete", "off");
293 currentInput.addEventListener("keydown", onContactKeydown, false);
294 currentInput.addEventListener("blur", checkAttendee, false);
296 inputs[inputs.length - 2].setAttribute("autocomplete", "off");
297 inputs[inputs.length - 2].addEventListener("click", newAttendee, false);
300 function resetAllFreeBusys() {
301 var table = $("freeBusy");
302 var inputs = table.getElementsByTagName("input");
304 for (var i = 0; i < inputs.length - 2; i++) {
305 var currentInput = inputs[i];
306 currentInput.hasfreebusy = false;
307 // log ("input: " + currentInput.uid);
308 awaitingFreeBusyRequests.push(currentInput);
310 if (awaitingFreeBusyRequests.length > 0)
311 displayFreeBusyForNode(awaitingFreeBusyRequests.shift());
314 function initializeWindowButtons() {
315 var okButton = $("okButton");
316 var cancelButton = $("cancelButton");
318 okButton.addEventListener("click", onEditorOkClick, false);
319 cancelButton.addEventListener("click", onEditorCancelClick, false);
321 var buttons = $("freeBusyViewButtons").childNodesWithTag("a");
322 for (var i = 0; i < buttons.length; i++)
323 buttons[i].addEventListener("click", listRowMouseDownHandler, false);
324 buttons = $("freeBusyZoomButtons").childNodesWithTag("a");
325 for (var i = 0; i < buttons.length; i++)
326 buttons[i].addEventListener("click", listRowMouseDownHandler, false);
327 buttons = $("freeBusyButtons").childNodesWithTag("a");
328 for (var i = 0; i < buttons.length; i++)
329 buttons[i].addEventListener("click", listRowMouseDownHandler, false);
332 function onEditorOkClick(event) {
333 event.preventDefault();
335 attendeesNames = new Array();
336 attendeesEmails = new Array();
338 var table = $("freeBusy");
339 var inputs = table.getElementsByTagName("input");
340 for (var i = 0; i < inputs.length - 2; i++) {
341 var name = extractEmailName(inputs[i].value);
342 if (!(name && name.length > 0))
343 name = inputs[i].uid;
344 var email = extractEmailAddress(inputs[i].value);
345 var pos = attendeesEmails.indexOf(email);
347 pos = attendeesEmails.length;
348 attendeesNames[pos] = name;
349 attendeesEmails[pos] = email;
352 parent$("attendeesNames").value = attendeesNames.join(",");
353 parent$("attendeesEmails").value = attendeesEmails.join(",");
354 window.opener.refreshAttendees();
356 updateParentDateFields("startTime", "startTime");
357 updateParentDateFields("endTime", "endTime");
362 function onEditorCancelClick(event) {
363 event.preventDefault();
367 function synchronizeWithParent(srcWidgetName, dstWidgetName) {
368 var srcDate = parent$(srcWidgetName + "_date");
369 var dstDate = $(dstWidgetName + "_date");
370 dstDate.value = srcDate.value;
372 var srcHour = parent$(srcWidgetName + "_time_hour");
373 var dstHour = $(dstWidgetName + "_time_hour");
374 dstHour.value = srcHour.value;
376 var srcMinute = parent$(srcWidgetName + "_time_minute");
377 var dstMinute = $(dstWidgetName + "_time_minute");
378 dstMinute.value = srcMinute.value;
381 function updateParentDateFields(srcWidgetName, dstWidgetName) {
382 var srcDate = $(srcWidgetName + "_date");
383 var dstDate = parent$(dstWidgetName + "_date");
384 dstDate.value = srcDate.value;
386 var srcHour = $(srcWidgetName + "_time_hour");
387 var dstHour = parent$(dstWidgetName + "_time_hour");
388 dstHour.value = srcHour.value;
390 var srcMinute = $(srcWidgetName + "_time_minute");
391 var dstMinute = parent$(dstWidgetName + "_time_minute");
392 dstMinute.value = srcMinute.value;
395 function initializeTimeWidgets() {
396 synchronizeWithParent("startTime", "startTime");
397 synchronizeWithParent("endTime", "endTime");
399 $("startTime_date").addEventListener("change", onTimeDateWidgetChange, false);
400 $("startTime_time_hour").addEventListener("change", onTimeWidgetChange, false);
401 $("startTime_time_minute").addEventListener("change", onTimeWidgetChange,
404 $("endTime_date").addEventListener("change", onTimeDateWidgetChange, false);
405 $("endTime_time_hour").addEventListener("change", onTimeWidgetChange, false);
406 $("endTime_time_minute").addEventListener("change", onTimeWidgetChange, false);
409 function onTimeWidgetChange() {
410 redisplayFreeBusyZone();
413 function onTimeDateWidgetChange(event) {
414 var table = $("freeBusy");
416 var rows = table.tHead.rows;
417 for (var i = 0; i < rows.length; i++) {
418 for (var j = rows[i].cells.length - 1; j > 0; j--) {
419 rows[i].deleteCell(j);
423 rows = table.tBodies[0].rows;
424 for (var i = 0; i < rows.length; i++) {
425 for (var j = rows[i].cells.length - 1; j > 0; j--) {
426 rows[i].deleteCell(j);
430 prepareTableHeaders();
432 redisplayFreeBusyZone();
433 resetAttendeesValue();
437 function prepareTableHeaders() {
438 var startTimeDate = $("startTime_date");
439 var startDate = startTimeDate.valueAsDate();
441 var endTimeDate = $("endTime_date");
442 var endDate = endTimeDate.valueAsDate();
443 endDate.setTime(endDate.getTime() + (additionalDays * 86400000));
445 var rows = $("freeBusy").tHead.rows;
446 var days = startDate.daysUpTo(endDate);
447 for (var i = 0; i < days.length; i++) {
448 var header1 = document.createElement("th");
449 header1.colSpan = (dayEndHour - dayStartHour) + 1;
450 header1.appendChild(document.createTextNode(days[i].toLocaleDateString()));
451 rows[0].appendChild(header1);
452 for (var hour = dayStartHour; hour < (dayEndHour + 1); hour++) {
453 var header2 = document.createElement("th");
454 var text = hour + ":00";
457 header2.appendChild(document.createTextNode(text));
458 rows[1].appendChild(header2);
460 var header3 = document.createElement("th");
461 for (var span = 0; span < 4; span++) {
462 var spanElement = document.createElement("span");
463 spanElement.addClassName("freeBusyZoneElement");
464 header3.appendChild(spanElement);
466 rows[2].appendChild(header3);
471 function prepareTableRows() {
472 var startTimeDate = $("startTime_date");
473 var startDate = startTimeDate.valueAsDate();
475 var endTimeDate = $("endTime_date");
476 var endDate = endTimeDate.valueAsDate();
477 endDate.setTime(endDate.getTime() + (additionalDays * 86400000));
479 var rows = $("freeBusy").tBodies[0].rows;
480 var days = startDate.daysUpTo(endDate);
481 for (var i = 0; i < days.length; i++) {
482 for (var rowNbr = 0; rowNbr < rows.length; rowNbr++) {
483 for (var hour = dayStartHour; hour < (dayEndHour + 1); hour++) {
484 var cell = document.createElement("td");
485 rows[rowNbr].appendChild(cell);
491 function prepareAttendees() {
492 var value = parent$("attendeesNames").value;
493 if (value.length > 0) {
494 attendeesNames = parent$("attendeesNames").value.split(",");
495 attendeesEmails = parent$("attendeesEmails").value.split(",");
497 var baseUrl = UserFolderURL + "Contacts/contactSearch?search=";
499 var body = $("freeBusy").tBodies[0];
500 for (var i = 0; i < attendeesNames.length; i++) {
501 var tr = body.insertRow(i);
502 var td = document.createElement("td");
503 td.addClassName("attendees");
504 var input = document.createElement("input");
506 if (attendeesNames[i].length > 0)
507 value += attendeesNames[i] + " ";
508 value += "<" + attendeesEmails[i] + ">";
510 input.addClassName("textField");
511 input.setAttribute("modified", "0");
512 triggerAjaxRequest(baseUrl + attendeesEmails[i],
513 UIDLookupCallback, input);
514 input.setAttribute("uid", attendeesNames[i]);
516 td.appendChild(input)
520 attendeesNames = new Array();
521 attendeesEmails = new Array();
525 function onFreeBusyLoadHandler() {
526 initializeWindowButtons();
527 initializeTimeWidgets();
529 prepareTableHeaders();
531 redisplayFreeBusyZone();
532 resetAttendeesValue();
536 window.addEventListener("load", onFreeBusyLoadHandler, false);