]> err.no Git - scalable-opengroupware.org/blob - UI/WebServerResources/UIxAttendeesEditor.js
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1036 d1b88da0-ebda-0310...
[scalable-opengroupware.org] / UI / WebServerResources / UIxAttendeesEditor.js
1 var resultsDiv;
2 var searchField;
3 var running = false;
4 var address;
5 var delay = 500;
6 var requestField;
7 var awaitingFreeBusyRequests = new Array();
8 var additionalDays = 2;
9
10 var dayStartHour = 8;
11 var dayEndHour = 18;
12
13 var attendeesNames;
14 var attendeesEmails;
15
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;
24     this.blur();
25     var input = row.cells[0].childNodesWithTag("input")[0];
26     if (input.readOnly)
27       newAttendee(null);
28     else {
29       input.focus();
30       input.select();
31       input.focussed = true;
32     }
33   }
34   else if (!running) {
35     if (event.keyCode == 8
36         || event.keyCode == 32
37         || event.keyCode > 47) {
38       running = true;
39       requestField = this;
40       requestField.setAttribute("modified", "1");
41       setTimeout("triggerRequest()", delay);
42     }
43     else if (this.confirmedValue) {
44       if (event.keyCode == 13) {
45         this.setSelectionRange(this.value.length, this.value.length);
46       }
47     }
48   }
49 }
50
51 function triggerRequest() {
52   if (document.contactLookupAjaxRequest) {
53     document.contactLookupAjaxRequest.aborted = yes;
54     document.contactLookupAjaxRequest.abort();
55   }
56   var urlstr = ( UserFolderURL + "Contacts/contactSearch?search="
57                  + requestField.value );
58   document.contactLookupAjaxRequest = triggerAjaxRequest(urlstr,
59                                                          updateResults,
60                                                          requestField);
61 }
62
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];
71       else
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];
77       else {
78         searchField.value += ' >> ' + text[1];
79       }
80       searchField.confirmedValue = text[1];
81       if (searchField.focussed) {
82         var end = searchField.value.length;
83         searchField.setSelectionRange(start, end);
84       }
85       else
86         searchField.value = text[1];
87     }
88     running = false;
89     document.contactLookupAjaxRequest = null;
90   }
91 }
92
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");
100   }
101 }
102
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();
108
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;
115   if (stHour < 8) {
116     stHour = 8;
117     stMinute = 0;
118   }
119   if (stHour > 19) {
120     stHour = 19
121     stMinute = 0;
122   }
123   if (etHour < 8) {
124     etHour = 8;
125     etMinute = 0;
126   }
127   if (etHour > 19) {
128     etHour = 19;
129     etMinute = 0;
130   }
131   if (stHour > etHour) {
132     var swap = etHour;
133     etHour = stHour;
134     stHour = swap;
135     swap = etMinute;
136     etMinute = stMinute;
137     stMinute = etMinute;
138   } else {
139     if (stMinute > etMinute) {
140       var swap = etMinute;
141       etMinute = stMinute;
142       stMinute = swap;
143     }
144   }
145
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");
152   resetFreeBusyZone();
153   while (deltaSpans > 0) {
154     var currentSpan = spans[currentSpanNbr];
155     currentSpan.addClassName("busy");
156     currentSpanNbr++;
157     if (currentSpanNbr > 3) {
158       currentSpanNbr = 0;
159       currentCellNbr++;
160       currentCell = row.cells[currentCellNbr];
161       spans = currentCell.childNodesWithTag("span");
162     }
163     deltaSpans--;
164   }
165 }
166
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);
180   input.focus();
181   input.focussed = true;
182 }
183
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;
195   }
196   resetAttendeesValue();
197 }
198
199 function displayFreeBusyForNode(node) {
200   var nodes = node.parentNode.parentNode.cells;
201   if (node.uid) {
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>');
208     }
209     if (document.contactFreeBusyAjaxRequest) {
210       document.contactFreeBusyAjaxRequest.aborted = true;
211       document.contactFreeBusyAjaxRequest.abort();
212     }
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,
219                            updateFreeBusyData,
220                            node);
221   } else {
222     for (var i = 1; i < nodes.length; i++) {
223       nodes[i].addClassName("noFreeBusy");
224       nodes[i].innerHTML = '';
225     }
226   }
227 }
228
229 function setSlot(tds, nbr, status) {
230   var tdnbr = Math.floor(nbr / 4);
231   var spannbr = nbr - (tdnbr * 4);
232   var days = 0;
233   if (tdnbr > 24) {
234     days = Math.floor(tdnbr / 24);
235     tdnbr -= (days * 24);
236   }
237   if (tdnbr > 7 && tdnbr < 19) {
238     var i = (days * 11 + tdnbr - 7);
239     var td = tds[i];
240     var spans = td.childNodesWithTag("span");
241     if (status == '2')
242       spans[spannbr].addClassName("maybe-busy");
243     else
244       spans[spannbr].addClassName("busy");
245   }
246 }
247
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++) {
255         if (slots[i] != '0')
256           setSlot(tds, i, slots[i]);
257       }
258     }
259     document.contactFreeBusyAjaxRequest = null;
260     if (awaitingFreeBusyRequests.length > 0)
261       displayFreeBusyForNode(awaitingFreeBusyRequests.shift());
262   }
263 }
264
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");
272     if (uid) {
273       currentInput.uid = uid;
274       currentInput.setAttribute("uid", null);
275     }
276     uids.push(currentInput.uid);
277     currentInput.setAttribute("autocomplete", "off");
278     currentInput.addEventListener("keydown", onContactKeydown, false);
279     currentInput.addEventListener("blur", checkAttendee, false);
280   }
281   inputs[inputs.length - 2].setAttribute("autocomplete", "off");
282   inputs[inputs.length - 2].addEventListener("click", newAttendee, false);
283 }
284
285 function resetAllFreeBusys() {
286   var table = $("freeBusy");
287   var inputs = table.getElementsByTagName("input");
288
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);
294   }
295   if (awaitingFreeBusyRequests.length > 0)
296     displayFreeBusyForNode(awaitingFreeBusyRequests.shift());
297 }
298
299 function initializeWindowButtons() {
300    var okButton = $("okButton");
301    var cancelButton = $("cancelButton");
302
303    okButton.addEventListener("click", onEditorOkClick, false);
304    cancelButton.addEventListener("click", onEditorCancelClick, false);
305
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);
315 }
316
317 function onEditorOkClick(event) {
318    event.preventDefault();
319
320    attendeesNames = new Array();
321    attendeesEmails = new Array();
322
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);
330      }
331      var email = extractEmailAddress(inputs[i].value);
332      var pos = attendeesEmails.indexOf(email);
333      if (pos == -1)
334        pos = attendeesEmails.length;
335      attendeesNames[pos] = name;
336      attendeesEmails[pos] = email;
337    }
338
339    parent$("attendeesNames").value = attendeesNames.join(",");
340    parent$("attendeesEmails").value = attendeesEmails.join(",");
341    window.opener.refreshAttendees();
342
343    updateParentDateFields("startTime", "startTime");
344    updateParentDateFields("endTime", "endTime");
345
346    window.close();
347 }
348
349 function onEditorCancelClick(event) {
350    event.preventDefault();
351    window.close();
352 }
353
354 function synchronizeWithParent(srcWidgetName, dstWidgetName) {
355    var srcDate = parent$(srcWidgetName + "_date");
356    var dstDate = $(dstWidgetName + "_date");
357    dstDate.value = srcDate.value;
358
359    var srcHour = parent$(srcWidgetName + "_time_hour");
360    var dstHour = $(dstWidgetName + "_time_hour");
361    dstHour.value = srcHour.value;
362
363    var srcMinute = parent$(srcWidgetName + "_time_minute");
364    var dstMinute = $(dstWidgetName + "_time_minute");
365    dstMinute.value = srcMinute.value;
366 }
367
368 function updateParentDateFields(srcWidgetName, dstWidgetName) {
369    var srcDate = $(srcWidgetName + "_date");
370    var dstDate = parent$(dstWidgetName + "_date");
371    dstDate.value = srcDate.value;
372
373    var srcHour = $(srcWidgetName + "_time_hour");
374    var dstHour = parent$(dstWidgetName + "_time_hour");
375    dstHour.value = srcHour.value;
376
377    var srcMinute = $(srcWidgetName + "_time_minute");
378    var dstMinute = parent$(dstWidgetName + "_time_minute");
379    dstMinute.value = srcMinute.value;
380 }
381
382 function initializeTimeWidgets() {
383    synchronizeWithParent("startTime", "startTime");
384    synchronizeWithParent("endTime", "endTime");
385
386    $("startTime_date").addEventListener("change", onTimeDateWidgetChange, false);
387    $("startTime_time_hour").addEventListener("change", onTimeWidgetChange, false);
388    $("startTime_time_minute").addEventListener("change", onTimeWidgetChange,
389                                                false);
390
391    $("endTime_date").addEventListener("change", onTimeDateWidgetChange, false);
392    $("endTime_time_hour").addEventListener("change", onTimeWidgetChange, false);
393    $("endTime_time_minute").addEventListener("change", onTimeWidgetChange, false);
394 }
395
396 function onTimeWidgetChange() {
397    redisplayFreeBusyZone();
398 }
399
400 function onTimeDateWidgetChange(event) {
401   var table = $("freeBusy");
402
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);
407      }
408   }
409
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);
414      }
415   }
416
417   prepareTableHeaders();
418   prepareTableRows();
419   redisplayFreeBusyZone();
420   resetAttendeesValue();
421   resetAllFreeBusys();
422 }
423
424 function prepareTableHeaders() {
425    var startTimeDate = $("startTime_date");
426    var startDate = startTimeDate.valueAsDate();
427
428    var endTimeDate = $("endTime_date");
429    var endDate = endTimeDate.valueAsDate();
430    endDate.setTime(endDate.getTime() + (additionalDays * 86400000));
431
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";
442          if (hour < 10)
443             text = "0" + text;
444          header2.appendChild(document.createTextNode(text));
445          rows[1].appendChild(header2);
446
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);
452          }
453          rows[2].appendChild(header3);
454       }
455    }
456 }
457
458 function prepareTableRows() {
459    var startTimeDate = $("startTime_date");
460    var startDate = startTimeDate.valueAsDate();
461
462    var endTimeDate = $("endTime_date");
463    var endDate = endTimeDate.valueAsDate();
464    endDate.setTime(endDate.getTime() + (additionalDays * 86400000));
465
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);
473          }
474       }
475    }
476 }
477
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(",");
483
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");
490          var value = "";
491          if (attendeesNames[i].length > 0)
492             value += attendeesNames[i] + " ";
493          value += "<" + attendeesEmails[i] + ">";
494          input.value = value;
495          input.setAttribute("uid", attendeesNames[i]);
496          input.addClassName("textField");
497          input.setAttribute("modified", "0");
498          tr.appendChild(td)
499          td.appendChild(input)
500       }
501    }
502    else {
503       attendeesNames = new Array();
504       attendeesEmails = new Array();
505    }
506 }
507
508 function onFreeBusyLoadHandler() {
509    initializeWindowButtons();
510    initializeTimeWidgets();
511    prepareAttendees();
512    prepareTableHeaders();
513    prepareTableRows();
514    redisplayFreeBusyZone();
515    resetAttendeesValue();
516    resetAllFreeBusys();
517 }
518
519 window.addEventListener("load", onFreeBusyLoadHandler, false);