]> err.no Git - scalable-opengroupware.org/blob - UI/WebServerResources/ContactsUI.js
initial sync
[scalable-opengroupware.org] / UI / WebServerResources / ContactsUI.js
1 /*
2   Copyright (C) 2005 SKYRIX Software AG
3
4   This file is part of OpenGroupware.org.
5
6   OGo is free software; you can redistribute it and/or modify it under
7   the terms of the GNU Lesser General Public License as published by the
8   Free Software Foundation; either version 2, or (at your option) any
9   later version.
10
11   OGo is distributed in the hope that it will be useful, but WITHOUT ANY
12   WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14   License for more details.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with OGo; see the file COPYING.  If not, write to the
18   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19   02111-1307, USA.
20 */
21 /* JavaScript for SOGo Mailer */
22
23 /*
24   DOM ids available in mail list view:
25     row_$msgid
26     div_$msgid
27     readdiv_$msgid
28     unreaddiv_$msgid
29
30   Window Properties:
31     width, height
32     bool: resizable, scrollbars, toolbar, location, directories, status,
33           menubar, copyhistory
34 */
35
36 var cachedContacts = new Array();
37 var currentContactFolder = '';
38 var currentFolderIsExternal = false;
39 var contactSelectorAction = 'addressbooks-contacts';
40
41 function openContactWindow(sender, url) {
42   var msgWin = window.open(url, null, "width=545,height=545,resizable=0");
43   msgWin.focus();
44 }
45
46 function clickedUid(sender, contactuid) {
47   resetSelection(window);
48   openContactWindow(sender, contactuid,
49                     CurrentContactFolderURL()
50                     + "/" + contactuid + "/edit");
51   return true;
52 }
53
54 function doubleClickedUid(sender, contactuid) {
55   alert("DOUBLE Clicked " + contactuid);
56
57   return false;
58 }
59
60 function toggleMailSelect(sender) {
61   var row;
62   row = $(sender.name);
63   row.className = sender.checked ? "tableview_selected" : "tableview";
64 }
65
66 /* mail editor */
67
68 function validateEditorInput(sender) {
69   var errortext = "";
70   var field;
71   
72   field = document.pageform.subject;
73   if (field.value == "")
74     errortext = errortext + labels.error_missingsubject + "\n";
75
76   if (!UIxRecipientSelectorHasRecipients())
77     errortext = errortext + labels.error_missingrecipients + "\n";
78   
79   if (errortext.length > 0) {
80     alert(labels.error_validationfailed.decodeEntities() + ":\n"
81           + errortext.decodeEntities());
82     return false;
83   }
84   return true;
85 }
86
87 function onContactsFolderTreeItemClick(element)
88 {
89   var topNode = $('d');
90   var contactsFolder = element.parentNode.getAttribute("dataname");
91
92   if (topNode.selectedEntry)
93     topNode.selectedEntry.deselect();
94   element.select();
95   topNode.selectedEntry = element;
96
97   openContactsFolder(contactsFolder);
98 }
99
100 function CurrentContactFolderURL() {
101   return ((currentFolderIsExternal)
102           ? UserFolderURL + "../" + currentContactFolder + "/Contacts/personal"
103           : ApplicationBaseURL + currentContactFolder);
104 }
105
106 function openContactsFolder(contactsFolder, params, external)
107 {
108   if (contactsFolder != currentContactFolder || params) {
109     if (contactsFolder == currentContactFolder)
110       selection = $("contactsList").getSelectedRowsId();
111     else
112       selection = null;
113
114     currentContactFolder = contactsFolder;
115     if (external)
116       currentFolderIsExternal = true;
117     else
118       currentFolderIsExternal = false;
119     var url = CurrentContactFolderURL() + "/view?noframe=1&sort=cn&desc=0";
120     if (params)
121       url += '&' + params;
122
123     var selection;
124     if (document.contactsListAjaxRequest) {
125       document.contactsListAjaxRequest.aborted = true;
126       document.contactsListAjaxRequest.abort();
127     }
128     document.contactsListAjaxRequest
129       = triggerAjaxRequest(url, contactsListCallback, selection);
130   }
131 }
132
133 function openContactsFolderAtIndex(element) {
134   var idx = element.getAttribute("idx");
135   var url = CurrentContactFolderURL() + "/view?noframe=1&idx=" + idx;
136
137   if (document.contactsListAjaxRequest) {
138     document.contactsListAjaxRequest.aborted = true;
139     document.contactsListAjaxRequest.abort();
140   }
141   document.contactsListAjaxRequest
142     = triggerAjaxRequest(url, contactsListCallback);
143 }
144
145 function contactsListCallback(http)
146 {
147   var div = $("contactsListContent");
148
149   if (http.readyState == 4
150       && http.status == 200) {
151     document.contactsListAjaxRequest = null;
152     div.innerHTML = http.responseText;
153     var selected = http.callbackData;
154     if (selected) {
155         for (var i = 0; i < selected.length; i++)
156           $(selected[i]).select();
157     }
158     configureSortableTableHeaders();
159   }
160   else
161     log ("ajax fuckage");
162 }
163
164 function onContactFoldersContextMenu(event)
165 {
166   var menu = $("contactFoldersMenu");
167   menu.addEventListener("hideMenu", onContactFoldersContextMenuHide, false);
168   onMenuClick(event, "contactFoldersMenu");
169
170   var topNode = $("contactFolders");
171   var selectedNodes = topNode.getSelectedRows();
172   topNode.menuSelectedRows = selectedNodes;
173   for (var i = 0; i < selectedNodes.length; i++)
174     selectedNodes[i].deselect();
175   topNode.menuSelectedEntry = this;
176   this.select();
177 }
178
179 function onContactContextMenu(event, element)
180 {
181   var menu = $("contactMenu");
182   menu.addEventListener("hideMenu", onContactContextMenuHide, false);
183   onMenuClick(event, "contactMenu");
184
185   var topNode = $("contactsList");
186   var selectedNodes = topNode.getSelectedRows();
187   topNode.menuSelectedRows = selectedNodes;
188   for (var i = 0; i < selectedNodes.length; i++)
189     selectedNodes[i].deselect();
190   topNode.menuSelectedEntry = element;
191   element.select();
192 }
193
194 function onContactContextMenuHide(event)
195 {
196   var topNode = $("contactsList");
197
198   if (topNode.menuSelectedEntry) {
199     topNode.menuSelectedEntry.deselect();
200     topNode.menuSelectedEntry = null;
201   }
202   if (topNode.menuSelectedRows) {
203     var nodes = topNode.menuSelectedRows;
204     for (var i = 0; i < nodes.length; i++)
205       nodes[i].select();
206     topNode.menuSelectedRows = null;
207   }
208 }
209
210 function onContactFoldersContextMenuHide(event)
211 {
212   var topNode = $("contactFolders");
213
214   if (topNode.menuSelectedEntry) {
215     topNode.menuSelectedEntry.deselect();
216     topNode.menuSelectedEntry = null;
217   }
218   if (topNode.menuSelectedRows) {
219     var nodes = topNode.menuSelectedRows;
220     for (var i = 0; i < nodes.length; i++)
221       nodes[i].select();
222     topNode.menuSelectedRows = null;
223   }
224 }
225
226 function onFolderMenuHide(event)
227 {
228   var topNode = $('d');
229
230   if (topNode.menuSelectedEntry) {
231     topNode.menuSelectedEntry.deselect();
232     topNode.menuSelectedEntry = null;
233   }
234   if (topNode.selectedEntry)
235     topNode.selectedEntry.select();
236 }
237
238 function loadContact(idx)
239 {
240   if (document.contactAjaxRequest) {
241     document.contactAjaxRequest.aborted = true;
242     document.contactAjaxRequest.abort();
243   }
244
245   if (cachedContacts[currentContactFolder + "/" + idx]) {
246     var div = $('contactView');
247     div.innerHTML = cachedContacts[currentContactFolder + "/" + idx];
248   }
249   else {
250     var url = (CurrentContactFolderURL() + "/"
251                + idx + "/view?noframe=1");
252     document.contactAjaxRequest
253       = triggerAjaxRequest(url, contactLoadCallback, idx);
254   }
255 }
256
257 function contactLoadCallback(http)
258 {
259   var div = $('contactView');
260
261   if (http.readyState == 4
262       && http.status == 200) {
263     document.contactAjaxRequest = null;
264     var content = http.responseText;
265     cachedContacts[currentContactFolder + "/" + http.callbackData] = content;
266     div.innerHTML = content;
267   }
268   else
269     log ("ajax fuckage");
270 }
271
272 var rowSelectionCount = 0;
273
274 validateControls();
275
276 function showElement(e, shouldShow) {
277   e.style.display = shouldShow ? "" : "none";
278 }
279
280 function enableElement(e, shouldEnable) {
281   if(!e)
282     return;
283   if(shouldEnable) {
284     if(e.hasAttribute("disabled"))
285       e.removeAttribute("disabled");
286   }
287   else {
288     e.setAttribute("disabled", "1");
289   }
290 }
291
292 function validateControls() {
293   var e = $("moveto");
294   this.enableElement(e, rowSelectionCount > 0);
295 }
296
297 function moveTo(uri) {
298   alert("MoveTo: " + uri);
299 }
300
301 /* contact menu entries */
302 function onContactRowClick(event, node)
303 {
304   loadContact(node.getAttribute('id'));
305
306   return onRowClick(event);
307 }
308
309 function onContactRowDblClick(event, node)
310 {
311   var contactId = node.getAttribute('id');
312
313   openContactWindow(null,
314                     CurrentContactFolderURL()
315                     + "/" + contactId + "/edit");
316
317   return false;
318 }
319
320 function onMenuEditContact(event, node)
321 {
322   var node = getParentMenu(node).menuTarget.parentNode;
323   var contactId = node.getAttribute('id');
324
325   openContactWindow(null,
326                     CurrentContactFolderURL()
327                     + "/" + contactId + "/edit");
328
329   return false;
330 }
331
332 function onMenuWriteToContact(event, node)
333 {
334   var node = getParentMenu(node).menuTarget.parentNode;
335   var contactId = node.getAttribute('id');
336
337   openMailComposeWindow(CurrentContactFolderURL()
338                         + "/" + contactId + "/write");
339
340   return false;
341 }
342
343 function onMenuDeleteContact(event, node)
344 {
345   uixDeleteSelectedContacts(node);
346
347   return false;
348 }
349
350 function onToolbarEditSelectedContacts(event)
351 {
352   var contactsList = $('contactsList');
353   var rows = contactsList.getSelectedRowsId();
354
355   for (var i = 0; i < rows.length; i++) {
356     openContactWindow(null,
357                       CurrentContactFolderURL()
358                       + "/" + rows[i] + "/edit");
359   }
360
361   return false;
362 }
363
364 function onToolbarWriteToSelectedContacts(event)
365 {
366   var contactsList = $('contactsList');
367   var rows = contactsList.getSelectedRowsId();
368
369   for (var i = 0; i < rows.length; i++)
370     openMailComposeWindow(CurrentContactFolderURL()
371                           + "/" + rows[i] + "/write");
372
373   return false;
374 }
375
376 function uixDeleteSelectedContacts(sender)
377 {
378   var failCount = 0;
379   var contactsList = $('contactsList');
380   var rows = contactsList.getSelectedRowsId();
381
382   var contactView = $('contactView');
383   contactView.innerHTML = '';
384
385   for (var i = 0; i < rows.length; i++) {
386     var url, http, rowElem;
387     
388     /* send AJAX request (synchronously) */
389     
390     url = (CurrentContactFolderURL() + "/"
391            + rows[i] + "/delete");
392     http = createHTTPClient();
393     http.open("POST", url, false /* not async */);
394     http.send("");
395     if (http.status != 200) { /* request failed */
396       failCount++;
397       http = null;
398       continue;
399     }
400     http = null;
401
402     /* remove from page */
403
404     /* line-through would be nicer, but hiding is OK too */
405     rowElem = $(rows[i]);
406     rowElem.parentNode.removeChild(rowElem);
407   }
408
409   if (failCount > 0)
410     alert("Could not delete " + failCount + " messages!");
411   
412   return false;
413 }
414
415 function newEmailTo(sender) {
416   var mailto = sanitizeMailTo(sender.parentNode.parentNode.menuTarget.innerHTML);
417
418   if (mailto.length > 0)
419     {
420       w = window.open("compose?mailto=" + mailto,
421                       "SOGo_compose",
422                       "width=680,height=520,resizable=1,scrollbars=1,toolbar=0," +
423                       "location=0,directories=0,status=0,menubar=0,copyhistory=0");
424       w.focus();
425     }
426
427   return false; /* stop following the link */
428 }
429
430 function onHeaderClick(event)
431 {
432   if (document.contactsListAjaxRequest) {
433     document.contactsListAjaxRequest.aborted = true;
434     document.contactsListAjaxRequest.abort();
435   }
436   url = CurrentContactFolderURL() + "/" + this.link;
437   if (!this.link.match(/noframe=/))
438     url += "&noframe=1";
439   document.contactsListAjaxRequest
440     = triggerAjaxRequest(url, contactsListCallback);
441
442   event.preventDefault();
443 }
444
445 function registerDraggableMessageNodes()
446 {
447   log ("can we drag...");
448 }
449
450 function newContact(sender) {
451   openContactWindow(sender,
452                     CurrentContactFolderURL() + "/new");
453
454   return false; /* stop following the link */
455 }
456
457 function onFolderSelectionChange()
458 {
459   var folderList = $("contactFolders");
460   var nodes = folderList.getSelectedNodes();
461   $("contactView").innerHTML = '';
462
463   if (nodes[0].hasClassName("denied")) {
464     var div = $("contactsListContent");
465     div.innerHTML = "";
466   }
467   else {
468     var newFolder;
469     var externalFolder = nodes[0].getAttribute("external-addressbook");
470     if (externalFolder)
471       newFolder = externalFolder;
472     else
473       newFolder = nodes[0].getAttribute("id");
474
475     openContactsFolder(newFolder, null, externalFolder);
476   }
477 }
478
479 function onSearchFormSubmit()
480 {
481   var searchValue = $("searchValue");
482
483   openContactsFolder(currentContactFolder, "search=" + searchValue.value);
484
485   return false;
486 }
487
488 function onConfirmContactSelection(tag)
489 {
490   var folderLi = $(currentContactFolder);
491   var currentContactFolderName = folderLi.innerHTML;
492   var selectorList = null;
493   var initialValues = null;
494
495   if (selector)
496     {
497       var selectorId = selector.getAttribute("id");
498       selectorList = opener.window.document.getElementById('uixselector-'
499                                                            + selectorId
500                                                            + '-uidList');
501       initialValues = selectorList.value;
502     }
503
504   var contactsList = $("contactsList");
505   var rows = contactsList.getSelectedRows();
506   for (i = 0; i < rows.length; i++) {
507     var cid = rows[i].getAttribute("contactid");
508     var cname = '' + rows[i].getAttribute("contactname");
509     var email = '' + rows[i].cells[1].innerHTML;
510     opener.window.addContact(tag, currentContactFolderName + '/' + cname,
511                              cid, cname, email);
512   }
513
514   if (selector && selector.changeNotification
515       && selectorList.value != initialValues)
516     selector.changeNotification("addition");
517
518   return false;
519 }
520
521 function onConfirmAddressBookSelection() {
522   var folderLi = $(currentContactFolder);
523   var currentContactFolderName = folderLi.innerHTML;
524
525   var selector = window.opener.document.getElementById("contactFolders");
526   var initialValues = selector.getAttribute("additional-addressbooks");
527   if (!initialValues)
528     initialValues = "";
529   var newValues = initialValues;
530
531   var contactsList = $("contactsList");
532   var rows = contactsList.getSelectedRows();
533   for (i = 0; i < rows.length; i++) {
534     var cid = rows[i].getAttribute("contactid");
535     var cname = '' + rows[i].getAttribute("contactname");
536     var email = '' + rows[i].cells[1].innerHTML;
537     var re = new RegExp("(^|,)" + cid + "($|,)");
538     if (!re.test(newValues)) {
539       if (newValues.length)
540         newValues += "," + cid;
541       else
542         newValues = cid;
543     }
544   }
545
546   if (newValues != initialValues)
547     window.opener.setTimeout("setAdditionalAddressBooks(\""
548                              + newValues + "\");", 100);
549
550   return false;
551 }
552
553 function setAdditionalAddressBooks(additionalAddressBooks) {
554   var urlstr = (ApplicationBaseURL + "/updateAdditionalAddressBooks?ids="
555                 + additionalAddressBooks);
556   if (document.addressBooksAjaxRequest) {
557     document.addressBooksAjaxRequest.aborted = true;
558     document.addressBooksAjaxRequest.abort();
559   }
560   document.addressBooksAjaxRequest
561     = triggerAjaxRequest(urlstr,
562                          addressBooksCallback, additionalAddressBooks);
563 }
564
565 function addressBooksCallback(http) {
566   if (http.readyState == 4) {
567     if (http.status == 200) {
568       var ul = $("contactFolders");
569
570       var children = ul.childNodesWithTag("li");
571       for (var i = 0; i < children.length; i++)
572         if (children[i].getAttribute("external-addressbook"))
573           ul.removeChild(children[i]);
574
575       ul.setAttribute("additional-addressbooks", http.callbackData);
576       if (http.callbackData.length > 0) {
577         var list = http.callbackData.split(",");
578         var newCode = "";
579         for (var i = 0; i < list.length; i++) {
580           var username = list[i];
581           newCode += ( "<li external-addressbook=\"" + username + "\""
582                        + " onmousedown=\"return false;\""
583                        + " onclick=\"return onRowClick(event);\""
584                        + " oncontextmenu=\"return onContactFolderContextMenu(event);\">" );
585           newCode += ( username + "</li>" );
586         }
587         ul.innerHTML += newCode;
588       }
589     }
590     document.addressBooksAjaxRequest = null;
591   }
592   else
593     log ("ajax fuckage");
594 }
595
596 function onContactMailTo(node) {
597   return openMailTo(node.innerHTML);
598 }
599
600 function refreshContacts(contactId) {
601   openContactsFolder(currentContactFolder, "reload=true", currentFolderIsExternal);
602   cachedContacts[currentContactFolder + "/" + contactId] = null;
603   loadContact(contactId);
604
605   return false;
606 }
607
608 function onAddressBookAdd(node) {
609   var selector = $("contactFolders");
610   var selectorURL = '?popup=YES&selectorId=contactFolders';
611
612   urlstr = ApplicationBaseURL;
613   if (urlstr[urlstr.length-1] != '/')
614     urlstr += '/';
615   urlstr += ("../../" + UserLogin + "/Contacts/"
616              + contactSelectorAction + selectorURL);
617 //   log (urlstr);
618   var w = window.open(urlstr, "Addressbook",
619                       "width=640,height=400,resizable=1,scrollbars=0");
620   w.selector = selector;
621   w.opener = this;
622   w.focus();
623
624   return false;
625 }
626
627 function onAddressBookRemove(node) {
628   var selector = $("contactFolders");
629   var nodes = selector.getSelectedNodes();
630   if (nodes.length > 0) {
631     var cid = nodes[0].getAttribute("external-addressbook");
632     if (cid) {
633       var initialValues = selector.getAttribute("additional-addressbooks");
634       var re = new RegExp("(^|,)" + cid + "($|,)");
635       var newValues = initialValues.replace(re, "");
636       if (initialValues != newValues)
637         setAdditionalAddressBooks(newValues);
638       
639       var personal = $("/personal");
640       personal.select();
641       onFolderSelectionChange();
642     }
643   }
644
645   return false;
646 }
647
648 function configureDragHandles() {
649   var handle = $("dragHandle");
650   if (handle) {
651     handle.addInterface(SOGoDragHandlesInterface);
652     handle.leftBlock=$("contactFoldersList");
653     handle.rightBlock=$("rightPanel");
654   }
655
656   handle = $("rightDragHandle");
657   if (handle) {
658     handle.addInterface(SOGoDragHandlesInterface);
659     handle.upperBlock=$("contactsListContent");
660     handle.lowerBlock=$("contactView");
661   }
662 }
663
664 function lookupDeniedFolders() {
665   var rights;
666   var http = createHTTPClient();
667   if (http) {
668     http.url = ApplicationBaseURL + "/checkRights";
669     http.open("GET", http.url, false /* not async */);
670     http.send("");
671     if (http.status == 200
672         && http.responseText.length > 0) {
673       rights = http.responseText.split(",");
674     }
675   }
676
677   return rights;
678 }
679
680 function configureContactFolders() {
681   var contactFolders = $("contactFolders");
682   if (contactFolders) {
683     contactFolders.addEventListener("selectionchange",
684                                     onFolderSelectionChange, false);
685     var lis = contactFolders.childNodesWithTag("li");
686     for (var i = 0; i < lis.length; i++) {
687       lis[i].addEventListener("mousedown", listRowMouseDownHandler, false);
688       lis[i].addEventListener("click", onRowClick, false);
689       lis[i].addEventListener("contextmenu", onContactFoldersContextMenu, false);
690     }
691
692     var denieds = lookupDeniedFolders();
693     if (denieds) {
694       var start = (lis.length - denieds.length);
695       for (var i = start; i < lis.length; i++) {
696         if (denieds[i-start] == "1")
697           lis[i].removeClassName("denied");
698         else
699           lis[i].addClassName("denied");
700       }
701     }
702     contactFolders.style.visibility = "visible;";
703   }
704 }
705
706 function onAccessRightsMenuEntryMouseUp(event) {
707   var folders = $("contactFolders");
708   var selected = folders.getSelectedNodes()[0];
709   var external = selected.getAttribute("external-addressbook");
710   var title = this.innerHTML;
711   if (external)
712     url = UserFolderURL + "../" + external + "/Contacts/personal/acls";
713   else
714     url = ApplicationBaseURL + selected.getAttribute("id") + "/acls";
715
716   openAclWindow(url, title);
717 }
718
719 function initializeMenus() {
720   var menus = new Array("contactFoldersMenu", "contactMenu", "searchMenu");
721   initMenusNamed(menus);
722
723   var menuEntry = $("accessRightsMenuEntry");
724   menuEntry.addEventListener("mouseup", onAccessRightsMenuEntryMouseUp, false);
725 }
726
727 var initContacts = {
728   handleEvent: function (event) {
729     configureContactFolders();
730 //     initDnd();
731   }
732 }
733
734 window.addEventListener("load", initContacts, false);