]> err.no Git - scalable-opengroupware.org/blob - UI/WebServerResources/ContactsUI.js
ab4ab2a12232fdaed2da9363ccf80a8309edc757
[scalable-opengroupware.org] / UI / WebServerResources / ContactsUI.js
1 /* JavaScript for SOGoContacts */
2
3 var cachedContacts = new Array();
4 var currentContactFolder = null;
5
6 var usersRightsWindowHeight = 200;
7 var usersRightsWindowWidth = 450;
8
9 function openContactWindow(sender, url) {
10   var msgWin = window.open(url, null, "width=450,height=600,resizable=0");
11   msgWin.focus();
12 }
13
14 function validateEditorInput(sender) {
15   var errortext = "";
16   var field;
17   
18   field = document.pageform.subject;
19   if (field.value == "")
20     errortext = errortext + labels.error_missingsubject + "\n";
21
22   if (!UIxRecipientSelectorHasRecipients())
23     errortext = errortext + labels.error_missingrecipients + "\n";
24   
25   if (errortext.length > 0) {
26     alert(labels.error_validationfailed.decodeEntities() + ":\n"
27           + errortext.decodeEntities());
28     return false;
29   }
30   return true;
31 }
32
33 function openContactsFolder(contactsFolder, reload, idx) {
34   if ((contactsFolder && contactsFolder != currentContactFolder)
35       || reload) {
36      currentContactFolder = contactsFolder;
37      var url = URLForFolderID(currentContactFolder) +
38         "/view?noframe=1";
39
40      var searchValue = search["value"];
41      if (searchValue && searchValue.length > 0)
42         url += ("&search=" + search["criteria"]
43                 + "&value=" + escape(searchValue));
44      var sortAttribute = sorting["attribute"];
45      if (sortAttribute && sortAttribute.length > 0)
46         url += ("&sort=" + sorting["attribute"]
47                 + "&asc=" + sorting["ascending"]);
48
49      var selection;
50      if (contactsFolder == currentContactFolder) {
51         var contactsList = $("contactsList");
52         if (contactsList)
53            selection = contactsList.getSelectedRowsId();
54         else
55            window.alert("no contactsList");
56      }
57      else
58         selection = null;
59
60      if (document.contactsListAjaxRequest) {
61         document.contactsListAjaxRequest.aborted = true;
62         document.contactsListAjaxRequest.abort();
63      }
64      document.contactsListAjaxRequest
65         = triggerAjaxRequest(url, contactsListCallback, selection);
66   }
67 }
68
69 function openContactsFolderAtIndex(element) {
70   var idx = element.getAttribute("idx");
71   var url = URLForFolderID(currentContactFolder) + "/view?noframe=1&idx=" + idx;
72
73   if (document.contactsListAjaxRequest) {
74     document.contactsListAjaxRequest.aborted = true;
75     document.contactsListAjaxRequest.abort();
76   }
77   document.contactsListAjaxRequest
78     = triggerAjaxRequest(url, contactsListCallback);
79 }
80
81 function configureContactsListHeaders(cells) {
82    for (var i = 0; i < cells.length; i++) {
83       var currentCell = $(cells[i]);
84       Event.observe(currentCell, "click",
85                     onHeaderClick.bindAsEventListener(currentCell));
86       Event.observe(currentCell, "mousedown", listRowMouseDownHandler);
87    }
88 }
89
90 function contactsListCallback(http) {
91   var div = $("contactsListContent");
92
93   if (http.readyState == 4
94       && http.status == 200) {
95     document.contactsListAjaxRequest = null;
96     div.innerHTML = http.responseText;
97
98     var table = $("contactsList");
99     if (table)
100        configureContactsListHeaders(table.tBodies[0].rows[0].cells);
101
102     if (sorting["attribute"] && sorting["attribute"].length > 0) {
103        var sortHeader;
104        if (sorting["attribute"] == "cn")
105           sortHeader = $("nameHeader");
106        else if (sorting["attribute"] == "mail")
107           sortHeader = $("mailHeader");
108        else if (sorting["attribute"] == "screenname")
109           sortHeader = $("screenNameHeader");
110        else if (sorting["attribute"] == "o")
111           sortHeader = $("orgHeader");
112        else if (sorting["attribute"] == "telephonenumber")
113           sortHeader = $("phoneHeader");
114        else
115           sortHeader = null;
116        
117        if (sortHeader) {
118           var sortImage = createElement("img", "messageSortImage", "sortImage");
119           sortHeader.insertBefore(sortImage, sortHeader.firstChild);
120           if (sorting["ascending"])
121              sortImage.src = ResourcesURL + "/title_sortdown_12x12.png";
122           else
123              sortImage.src = ResourcesURL + "/title_sortup_12x12.png";
124        }
125     }
126
127     var selected = http.callbackData;
128     if (selected) {
129        for (var i = 0; i < selected.length; i++) {
130           var row = $(selected[i]);
131           if (row)
132              row.select();
133        }
134     }
135   }
136   else
137     log ("ajax problem 1: status = " + http.status);
138 }
139
140 function onContactFoldersContextMenu(event) {
141   var menu = $("contactFoldersMenu");
142   //Event.observe(menu, "hideMenu", onContactFoldersContextMenuHide, false);
143   Event.observe(menu, "mousedown", onContactFoldersContextMenuHide, false);
144   popupMenu(event, "contactFoldersMenu", this);
145
146   var topNode = $("contactFolders");
147   var selectedNodes = topNode.getSelectedRows();
148   topNode.menuSelectedRows = selectedNodes;
149   for (var i = 0; i < selectedNodes.length; i++)
150     $(selectedNodes[i]).deselect();
151   topNode.menuSelectedEntry = this;
152   $(this).select();
153 }
154
155 function onContactContextMenu(event, element) {
156   var menu = $("contactMenu");
157   //Event.observe(menu, "hideMenu", onContactContextMenuHide, false);
158   Event.observe(menu, "mousedown", onContactContextMenuHide, false);
159   //document.documentElement.onclick = onContactContextMenuHide;
160   popupMenu(event, "contactMenu", element);
161
162   var topNode = $("contactsList");
163   var selectedNodes = topNode.getSelectedRows();
164   topNode.menuSelectedRows = selectedNodes;
165   for (var i = 0; i < selectedNodes.length; i++)
166     $(selectedNodes[i]).deselect();
167   topNode.menuSelectedEntry = element;
168   $(element).select();
169 }
170
171 function onContactContextMenuHide(event) {
172   var topNode = $("contactsList");
173
174   if (topNode.menuSelectedEntry) {
175     $(topNode.menuSelectedEntry).deselect();
176     topNode.menuSelectedEntry = null;
177   }
178   if (topNode.menuSelectedRows) {
179     var nodes = topNode.menuSelectedRows;
180     for (var i = 0; i < nodes.length; i++)
181       $(nodes[i]).select();
182     topNode.menuSelectedRows = null;
183   }
184 }
185
186 function onContactFoldersContextMenuHide(event) {
187   var topNode = $("contactFolders");
188
189   if (topNode.menuSelectedEntry) {
190     topNode.menuSelectedEntry.deselect();
191     topNode.menuSelectedEntry = null;
192   }
193   if (topNode.menuSelectedRows) {
194     var nodes = topNode.menuSelectedRows;
195     for (var i = 0; i < nodes.length; i++)
196       nodes[i].select();
197     topNode.menuSelectedRows = null;
198   }
199 }
200
201 function onFolderMenuHide(event) {
202   var topNode = $('d');
203
204   if (topNode.menuSelectedEntry) {
205     topNode.menuSelectedEntry.deselect();
206     topNode.menuSelectedEntry = null;
207   }
208   if (topNode.selectedEntry)
209     topNode.selectedEntry.select();
210 }
211
212 function loadContact(idx) {
213   if (document.contactAjaxRequest) {
214     document.contactAjaxRequest.aborted = true;
215     document.contactAjaxRequest.abort();
216   }
217
218   if (cachedContacts[currentContactFolder + "/" + idx]) {
219     var div = $('contactView');
220     div.innerHTML = cachedContacts[currentContactFolder + "/" + idx];
221   }
222   else {
223     var url = (URLForFolderID(currentContactFolder)
224                + "/" + idx + "/view?noframe=1");
225     document.contactAjaxRequest
226       = triggerAjaxRequest(url, contactLoadCallback, idx);
227   }
228 }
229
230 function contactLoadCallback(http) {
231   var div = $('contactView');
232
233   if (http.readyState == 4
234       && http.status == 200) {
235     document.contactAjaxRequest = null;
236     var content = http.responseText;
237     cachedContacts[currentContactFolder + "/" + http.callbackData] = content;
238     div.innerHTML = content;
239   }
240   else
241     log ("ajax problem 2: " + http.status);
242 }
243
244 var rowSelectionCount = 0;
245
246 validateControls();
247
248 function showElement(e, shouldShow) {
249   e.style.display = shouldShow ? "" : "none";
250 }
251
252 function enableElement(e, shouldEnable) {
253   if(!e)
254     return;
255   if(shouldEnable) {
256     if(e.hasAttribute("disabled"))
257       e.removeAttribute("disabled");
258   }
259   else {
260     e.setAttribute("disabled", "1");
261   }
262 }
263
264 function validateControls() {
265   var e = $("moveto");
266   this.enableElement(e, rowSelectionCount > 0);
267 }
268
269 function moveTo(uri) {
270   alert("MoveTo: " + uri);
271 }
272
273 /* contact menu entries */
274 function onContactRowClick(event, node) {
275   loadContact(node.getAttribute('id'));
276
277   return onRowClick(event);
278 }
279
280 function onContactRowDblClick(event, node) {
281   var contactId = node.getAttribute('id');
282
283   openContactWindow(null,
284                     URLForFolderID(currentContactFolder)
285                     + "/" + contactId + "/edit");
286
287   return false;
288 }
289
290 function onMenuEditContact(event) {
291   var contactId = document.menuTarget.getAttribute('id');
292
293   openContactWindow(null,
294                     URLForFolderID(currentContactFolder)
295                     + "/" + contactId + "/edit");
296 }
297
298 function onMenuWriteToContact(event) {
299    var contactId = document.menuTarget.getAttribute('id');
300
301    openMailComposeWindow(ApplicationBaseURL + currentContactFolder
302                          + "/" + contactId + "/write");
303 }
304
305 function onMenuDeleteContact(event) {
306   uixDeleteSelectedContacts(this);
307 }
308
309 function onToolbarEditSelectedContacts(event) {
310   var contactsList = $('contactsList');
311   var rows = contactsList.getSelectedRowsId();
312
313   for (var i = 0; i < rows.length; i++) {
314     openContactWindow(null,
315                       URLForFolderID(currentContactFolder)
316                       + "/" + rows[i] + "/edit");
317   }
318
319   return false;
320 }
321
322 function onToolbarWriteToSelectedContacts(event) {
323   var contactsList = $('contactsList');
324   var rows = contactsList.getSelectedRowsId();
325
326   for (var i = 0; i < rows.length; i++)
327     openMailComposeWindow(ApplicationBaseURL + currentContactFolder
328                           + "/" + rows[i] + "/write");
329
330   return false;
331 }
332
333 function uixDeleteSelectedContacts(sender) {
334   var failCount = 0;
335   var contactsList = $('contactsList');
336   var rows = contactsList.getSelectedRowsId();
337
338   var contactView = $('contactView');
339   contactView.innerHTML = '';
340
341   for (var i = 0; i < rows.length; i++) {
342     var url, http, rowElem;
343     
344     /* send AJAX request (synchronously) */
345     
346     url = (URLForFolderID(currentContactFolder) + "/"
347            + rows[i] + "/delete");
348     http = createHTTPClient();
349     http.open("POST", url, false /* not async */);
350     http.send("");
351     if (http.status != 200) { /* request failed */
352       failCount++;
353       http = null;
354       continue;
355     }
356     http = null;
357
358     /* remove from page */
359
360     /* line-through would be nicer, but hiding is OK too */
361     rowElem = $(rows[i]);
362     rowElem.parentNode.removeChild(rowElem);
363   }
364
365   if (failCount > 0)
366     alert("Could not delete the selected contacts!");
367   
368   return false;
369 }
370
371 function newEmailTo(sender) {
372   var mailto = sanitizeMailTo(sender.parentNode.parentNode.menuTarget.innerHTML);
373
374   if (mailto.length > 0)
375     {
376       w = window.open("compose?mailto=" + mailto,
377                       "SOGo_compose",
378                       "width=680,height=520,resizable=1,scrollbars=1,toolbar=0," +
379                       "location=0,directories=0,status=0,menubar=0,copyhistory=0");
380       w.focus();
381     }
382
383   return false; /* stop following the link */
384 }
385
386 function onHeaderClick(event) {
387    var headerId = this.getAttribute("id");
388    var newSortAttribute;
389    if (headerId == "nameHeader")
390       newSortAttribute = "cn";
391    else if (headerId == "mailHeader")
392       newSortAttribute = "mail";
393    else if (headerId == "screenNameHeader")
394       newSortAttribute = "screenname";
395    else if (headerId == "orgHeader")
396       newSortAttribute = "o";
397    else if (headerId == "phoneHeader")
398       newSortAttribute = "telephonenumber";
399
400    log("header: " + headerId);
401
402    if (sorting["attribute"] == newSortAttribute)
403       sorting["ascending"] = !sorting["ascending"];
404    else {
405       sorting["attribute"] = newSortAttribute;
406       sorting["ascending"] = true;
407    }
408
409    refreshCurrentFolder();
410
411    preventDefault(event);
412 }
413
414 function registerDraggableMessageNodes() {
415   log ("can we drag...");
416 }
417
418 function newContact(sender) {
419   openContactWindow(sender,
420                     URLForFolderID(currentContactFolder) + "/new");
421
422   return false; /* stop following the link */
423 }
424
425 function onFolderSelectionChange() {
426    var folderList = $("contactFolders");
427    var nodes = folderList.getSelectedNodes();
428    $("contactView").innerHTML = '';
429   
430    if (nodes[0].hasClassName("denied")) {
431       var div = $("contactsListContent");
432       div.innerHTML = "";
433    }
434    else {
435       search = {};
436       sorting = {};
437       $("searchValue").value = "";
438       initCriteria();
439       openContactsFolder(nodes[0].getAttribute("id"));
440    }
441 }
442
443 function refreshCurrentFolder() {
444    openContactsFolder(currentContactFolder, true);
445 }
446
447 function onConfirmContactSelection(event) {
448    var tag = this.getAttribute("name");
449    var folderLi = $(currentContactFolder);
450    var currentContactFolderName = folderLi.innerHTML;
451    var selectorList = null;
452    var initialValues = null;
453
454    if (selector) {
455       var selectorId = selector.getAttribute("id");
456       selectorList = opener.window.document.getElementById('uixselector-'
457                                                            + selectorId
458                                                            + '-uidList');
459       initialValues = selectorList.value;
460    }
461
462    var contactsList = $("contactsList");
463    var rows = contactsList.getSelectedRows();
464    for (i = 0; i < rows.length; i++) {
465       var cid = rows[i].getAttribute("contactid");
466       var cname = '' + rows[i].getAttribute("contactname");
467       var email = '' + rows[i].cells[1].innerHTML;
468       opener.window.addContact(tag, currentContactFolderName + '/' + cname,
469                                cid, cname, email);
470    }
471
472    if (selector && selector.changeNotification
473        && selectorList.value != initialValues)
474       selector.changeNotification("addition");
475
476    preventDefault(event);
477 }
478
479 function onContactMailTo(node) {
480   return openMailTo(node.innerHTML);
481 }
482
483 function refreshContacts(contactId) {
484    refreshCurrentFolder();
485    cachedContacts[currentContactFolder + "/" + contactId] = null;
486    loadContact(contactId);
487
488    return false;
489 }
490
491 function onAddressBookNew(event) {
492   var name = window.prompt(labels["Name of the Address Book"].decodeEntities());
493   if (name) {
494     if (document.newAbAjaxRequest) {
495       document.newAbAjaxRequest.aborted = true;
496       document.newAbAjaxRequest.abort();
497     }
498     var url = ApplicationBaseURL + "/newAb?name=" + name;
499     document.newAbAjaxRequest
500        = triggerAjaxRequest(url, newAbCallback, name);
501   }
502   preventDefault(event);
503 }
504
505 function appendAddressBook(name, folder) {
506    var li = document.createElement("li");
507    $("contactFolders").appendChild(li);
508    li.setAttribute("id", folder);
509    li.appendChild(document.createTextNode(name));
510    setEventsOnContactFolder(li);
511 }
512
513 function newAbCallback(http) {
514   if (http.readyState == 4
515       && http.status == 201) {
516      var name = http.callbackData;
517      appendAddressBook(name, "/" + name);
518   }
519   else
520     log ("ajax problem 4:" + http.status);
521 }
522
523 function newUserFolderCallback(folderData) {
524    var folder = $(folderData["folder"]);
525    if (!folder)
526       appendAddressBook(folderData["folderName"], folderData["folder"]);
527 }
528
529 function onAddressBookAdd(event) {
530    openUserFolderSelector(newUserFolderCallback, "contact");
531
532    preventDefault(event);
533 }
534
535 function onFolderUnsubscribeCB(folderId) {
536    var node = $(folderId);
537    node.parentNode.removeChild(node);
538    var personal = $("/personal");
539    personal.select();
540    onFolderSelectionChange();
541 }
542
543 function onAddressBookRemove(event) {
544   var selector = $("contactFolders");
545   var nodes = selector.getSelectedNodes();
546   if (nodes.length > 0) { 
547      nodes[0].deselect();
548      var folderId = nodes[0].getAttribute("id");
549      var folderIdElements = folderId.split(":");
550      if (folderIdElements.length > 1)
551         unsubscribeFromFolder(folderId, onFolderUnsubscribeCB, folderId);
552      else {
553         var abId = folderIdElements[0].substr(1);
554         deletePersonalAddressBook(abId);
555         var personal = $("/personal");
556         personal.select();
557         onFolderSelectionChange();
558      }
559   }
560
561   preventDefault(event);
562 }
563
564 function deletePersonalAddressBook(folderId) {
565    var label
566       = labels["Are you sure you want to delete the selected address book?"];
567    if (window.confirm(label.decodeEntities())) {
568       if (document.deletePersonalABAjaxRequest) {
569          document.deletePersonalABAjaxRequest.aborted = true;
570          document.deletePersonalABAjaxRequest.abort();
571       }
572       var url = ApplicationBaseURL + "/" + folderId + "/delete";
573       document.deletePersonalABAjaxRequest
574          = triggerAjaxRequest(url, deletePersonalAddressBookCallback,
575                               folderId);
576    }
577 }
578
579 function deletePersonalAddressBookCallback(http) {
580   if (http.readyState == 4) {
581      if (http.status == 200) {
582         var ul = $("contactFolders");
583         
584         var children = ul.childNodesWithTag("li");
585         var i = 0;
586         var done = false;
587         while (!done && i < children.length) {
588            var currentFolderId = children[i].getAttribute("id").substr(1);
589            if (currentFolderId == http.callbackData) {
590               ul.removeChild(children[i]);
591               done = true;
592            }
593            else
594               i++;
595         }
596      }
597      document.deletePersonalABAjaxRequest = null;
598   }
599   else
600      log ("ajax problem 5: " + http.status);
601 }
602
603 function configureDragHandles() {
604   var handle = $("dragHandle");
605   if (handle) {
606     handle.addInterface(SOGoDragHandlesInterface);
607     handle.leftBlock=$("contactFoldersList");
608     handle.rightBlock=$("rightPanel");
609   }
610
611   handle = $("rightDragHandle");
612   if (handle) {
613     handle.addInterface(SOGoDragHandlesInterface);
614     handle.upperBlock=$("contactsListContent");
615     handle.lowerBlock=$("contactView");
616   }
617 }
618
619 function lookupDeniedFolders() {
620   var list = $("contactFolders").childNodesWithTag("li");
621   for (var i = 0; i < list.length; i++) {
622      var folderID = list[i].getAttribute("id");
623      var url = URLForFolderID(folderID) + "/canAccessContent";
624      
625      triggerAjaxRequest(url, deniedFoldersLookupCallback, folderID);
626   }
627 }
628
629 function deniedFoldersLookupCallback(http) {
630    if (http.readyState == 4) {
631       var denied = ! isHttpStatus204(http.status);
632       var entry = $(http.callbackData);
633       if (denied)
634          entry.addClassName("denied");
635       else
636          entry.removeClassName("denied");
637    }
638 }
639
640 function configureAbToolbar() {
641   var toolbar = $("abToolbar");
642   var links = toolbar.childNodesWithTag("a");
643   Event.observe(links[0], "click", onAddressBookNew, false);
644   Event.observe(links[1], "click", onAddressBookAdd, false);
645   Event.observe(links[2], "click", onAddressBookRemove, false);
646 }
647
648 function configureContactFolders() {
649   var contactFolders = $("contactFolders");
650   if (contactFolders) {
651     Event.observe(contactFolders, "mousedown", listRowMouseDownHandler);
652     Event.observe(contactFolders, "click", onFolderSelectionChange);
653     var lis = contactFolders.childNodesWithTag("li");
654     for (var i = 0; i < lis.length; i++)
655       setEventsOnContactFolder(lis[i]);
656
657     lookupDeniedFolders();
658
659     var personalFolder = $("/personal");
660     personalFolder.select();
661     openContactsFolder("/personal");
662   }
663 }
664
665 function setEventsOnContactFolder(node) {
666    Event.observe(node, "mousedown", listRowMouseDownHandler, false);
667    Event.observe(node, "click", onRowClick, false);
668    Event.observe(node, "contextmenu",
669                  onContactFoldersContextMenu.bindAsEventListener(node), false);
670 }
671
672 function onMenuSharing(event) {
673    var folders = $("contactFolders");
674    var selected = folders.getSelectedNodes()[0];
675    var title = this.innerHTML;
676    var url = URLForFolderID(selected.getAttribute("id"));
677
678    openAclWindow(url + "/acls", title);
679 }
680
681 function getMenus() {
682    var menus = {};
683    menus["contactFoldersMenu"] = new Array(null, "-", null,
684                                            null, "-", null, "-",
685                                            onMenuSharing);
686    menus["contactMenu"] = new Array(onMenuEditContact, "-",
687                                     onMenuWriteToContact, null, "-",
688                                     onMenuDeleteContact);
689    menus["searchMenu"] = new Array(setSearchCriteria);
690
691    return menus;
692 }
693
694 function configureSelectionButtons() {
695    var container = $("contactSelectionButtons");
696    if (container) {
697       var buttons = container.childNodesWithTag("input");
698       for (var i = 0; i < buttons.length; i++)
699         Event.observe(buttons[i], "click",
700                       onConfirmContactSelection.bindAsEventListener(buttons[i]));
701    }
702 }
703
704 function initContacts(event) {
705    if (!document.body.hasClassName("popup")) {
706      configureAbToolbar();
707    }
708    else
709      configureSelectionButtons();
710    configureContactFolders();
711 //     initDnd();
712 }
713
714 addEvent(window, 'load', initContacts);