[Bedework-commit] carddav r181 - in trunk/clients/javascript/bwAddrbookClient: . config/lang resources

svnadmin at bedework.org svnadmin at bedework.org
Wed Oct 27 16:16:46 EDT 2010


Author: johnsa
Date: 2010-10-27 16:16:45 -0400 (Wed, 27 Oct 2010)
New Revision: 181

Modified:
   trunk/clients/javascript/bwAddrbookClient/config/lang/en_US.js
   trunk/clients/javascript/bwAddrbookClient/index.html
   trunk/clients/javascript/bwAddrbookClient/resources/addressbook.css
   trunk/clients/javascript/bwAddrbookClient/resources/addressbook.js
Log:
javascript client: add members to groups

Modified: trunk/clients/javascript/bwAddrbookClient/config/lang/en_US.js
===================================================================
--- trunk/clients/javascript/bwAddrbookClient/config/lang/en_US.js	2010-10-27 02:58:38 UTC (rev 180)
+++ trunk/clients/javascript/bwAddrbookClient/config/lang/en_US.js	2010-10-27 20:16:45 UTC (rev 181)
@@ -59,6 +59,9 @@
 var bwAbDispError404 = "<h3>You cannot access the current address book.</h3><p>It is likely that you are still authenticated as another user.  You must invalidate your HTTP authentication or close your browser and try again.</p>"; 
 var bwAbDispError500 = '<h3>Internal Server Error</h3><p>We\'re still in development.<p><p>If you do not see an address book listing and expect one, please try <a href="javascript:window.location.reload();">reloading</a> your browser.</p><p>(You may otherwise ignore and close this message.)</p>';
 var bwAbDispErrorAccessDenied = "Access Denied";
+var bwAbDispDisallowed = "Not Allowed";
+var bwAbDispNoMemberAddEmail = "Entries without an email address may not be added to groups.";
+var bwAbDispNoMemberAddGroup = "You may not add groups to groups.";
 
 // add/update messages
 var bwAbDispSuccessTitle = "Success";

Modified: trunk/clients/javascript/bwAddrbookClient/index.html
===================================================================
--- trunk/clients/javascript/bwAddrbookClient/index.html	2010-10-27 02:58:38 UTC (rev 180)
+++ trunk/clients/javascript/bwAddrbookClient/index.html	2010-10-27 20:16:45 UTC (rev 181)
@@ -35,6 +35,7 @@
     <script type="text/javascript" src="resources/jquery/layout/jquery.layout.min-1.2.0.js"></script>
     <link href="resources/jquery/layout/layout.css" rel="stylesheet" type="text/css"/>
     <script type="text/javascript" src="resources/jquery/tablesorter/jquery.tablesorter.min.js"></script>
+    <script type="text/javascript" src="resources/jquery/jquery.cookie.js"></script>
     <script type="text/javascript" src="resources/Math.uuid.js"></script>
     <script type="text/javascript" src="config/config.js"></script>
     <script type="text/javascript" src="resources/addressbook.js"></script>
@@ -85,6 +86,7 @@
            We make each visible or invisible as needed using javascript. -->
       <ul id="bw-pages">
         <li id="bw-list">
+          <!-- 
           <ul id="filterLetters">
             <li><a href="#A">A</a></li>
             <li><a href="#B">B</a></li>
@@ -113,6 +115,7 @@
             <li><a href="#Y">Y</a></li>
             <li><a href="#Z">Z</a></li>
           </ul>
+          -->
           <div id="bwAddrBookOutputList"></div>
         </li>
         <li id="bw-details" class="invisible content-block">

Modified: trunk/clients/javascript/bwAddrbookClient/resources/addressbook.css
===================================================================
--- trunk/clients/javascript/bwAddrbookClient/resources/addressbook.css	2010-10-27 02:58:38 UTC (rev 180)
+++ trunk/clients/javascript/bwAddrbookClient/resources/addressbook.css	2010-10-27 20:16:45 UTC (rev 181)
@@ -51,31 +51,22 @@
   position: relative;
   white-space: nowrap;
 }
-ul.books {
-	margin-bottom: 1em;
-}
-ul.books li {
-  list-style-image: url("icons/silk/book.png");
-}
-ul.subscriptions li {
-  list-style-image: url("icons/silk/book_link.png");
-}
 li.empty {
 	list-style: none !important;
 }
-ul.books li.group,
-ul.subscriptions li.group,
-ul.groups li,
 li.group {
   list-style-image: url("icons/silk/group.png");
 }
-ul.contacts li,
 li.contact {
   list-style-image: url("icons/silk/user.png");
 }
 li.location {
   list-style-image: url("icons/silk/building.png");
 }
+.droppableHighlight {
+	background-color: #eef !important;
+	color: black;
+}
 ul#add li {
   background-color: #eef;
   padding: 0.15em 1em 0.3em 5px;
@@ -112,7 +103,8 @@
   list-style: disc outside none;
 }
 #booksAndGroups li {
-  margin: 0 0 0.25em 2em;
+  margin: 0 0 0.25em 0.5em;
+  list-style: none;
 }
 #booksAndGroups h3 {
   margin: 0 0 0.5em 0;
@@ -128,8 +120,29 @@
 	margin: 0.5em 0 2em 0;
 }
 #booksAndGroups ul ul li {
-  margin-bottom: 0.25em;
+  margin: 0 0 0.5em 1em;
 }
+#booksAndGroups ul.books {
+  margin-bottom: 1em;
+}
+#booksAndGroups a.bwBook {
+  background: white url("icons/silk/book.png") left no-repeat;
+  color: #333;
+  display: block;
+  padding-left: 20px;
+}
+#booksAndGroups a.bwSubscription {
+  background: white url("icons/silk/book_link.png") left no-repeat;
+  color: #333;
+  display: block;
+  padding-left: 20px;
+}
+#booksAndGroups a.bwGroup {
+  background: white url("icons/silk/group.png") left no-repeat;
+  color: #333;
+  display: block;
+  padding-left: 22px;
+}
 #booksAndGroups a.selected {
 	background-color: #ff9;
 	color: #333;

Modified: trunk/clients/javascript/bwAddrbookClient/resources/addressbook.js
===================================================================
--- trunk/clients/javascript/bwAddrbookClient/resources/addressbook.js	2010-10-27 02:58:38 UTC (rev 180)
+++ trunk/clients/javascript/bwAddrbookClient/resources/addressbook.js	2010-10-27 20:16:45 UTC (rev 181)
@@ -36,6 +36,7 @@
   this.creating = true; // are we creating or editing an item?
   this.book; // the currently selected book
   this.card; // the currently selected card
+  this.selectedMenuId = $.cookie("selectedMenuId"); // the currently selected menu item; might be null
   this.groupMenus = new Array(); // a place to store groups when building menus
   
   this.init = function(bookTemplate,userid) {
@@ -101,20 +102,21 @@
     for (var i=0; i < bwAddressBook.books.length; i++) {
       var book = bwAddressBook.books[i];
       var bookId = "bwBook-" + i;
+      var bookLinkId = "bwBookLink-" + i;
       switch(book.type) {
         case "personal-default" :
           // this is the default book; mark it as such.  We will replace the title with the user's id
-          personalBooks += '<li class="bwBook defaultUserBook" id="' + bookId + '">';
-          personalBooks += '<a href="#" class="selected">' + bwAddressBook.userid + '</a>';
+          personalBooks += '<li id="' + bookId + '">';
+          personalBooks += '<a href="#" class="bwBook bwBookLink defaultUserBook selected" id="' + bookLinkId + '">' + bwAddressBook.userid + '</a>';
           personalBooks += '<ul class="bwGroups"></ul>';
           personalBooks += '</li>';
           break;
         case "personal" :
-          personalBooks += '<li class="bwBook" id="' + bookId + '"><a href="#">' + book.label + '</a></li>';
+          personalBooks += '<li id="' + bookId + '"><a href="#" class="bwBook bwBookLink" id="' + bookLinkId + '">' + book.label + '</a></li>';
           break;
         case "subscription" :
           // this is a subscription
-          subscriptions += '<li class="bwBook" id="' + bookId + '"><a href="#">' + book.label + '</a></li>';
+          subscriptions += '<li id="' + bookId + '"><a href="#" class="bwSubscription bwBookLink" id="' + bookLinkId + '">' + book.label + '</a></li>';
           break;
         default :
           alert(book.label + ':\n' + bwAbDispBookType + ' "' + book.type + '" ' + bwAbDispUnsupported);
@@ -136,25 +138,18 @@
     $("#bwBooks").html(personalBooks);
     $("#bwSubscriptions").html(subscriptions);
     
-    // got groups? put them with the correct books
+    // Got groups? put them with the correct books.
+    // We've gathered the group menu items in an array when we built the listing (below).
     for (var j=0; j<this.groupMenus.length; j++) {
       $("#bwBook-" + j + " ul").html(this.groupMenus[j]);
     }
-    
-    $(".defaultUserBook").droppable({ 
-      accept: '#bwAddrBookOutputList td.name',  
-      drop:   function () { 
-        showMessage(bwAbDispUnimplementedTitle,bwAbDispUnimplemented,true);
-        return false; 
-      } 
-    }); 
 
   };
   
   this.buildList = function(bookIndex) {
     var book = new Array();
     var index = bookIndex;
-    var listing = ""; // for tabular listing
+    var listing = ""; // for tabular listing of book members
     var groups = ""; // for listing of groups in the menu
     
     // select the current book
@@ -256,10 +251,10 @@
         
         listing += '<tr id="bwBookRow-' + index + '-' + i + '">';
         if (book.listDisp.name) {
-          listing += '<td class="name"><img src="' + kindIcon + '" width="16" height="16" alt="' + kind + '"/>' + fn + '</td>';
+          listing += '<td class="name" id="bwCardFN-' + index + '-' + i + '"><img src="' + kindIcon + '" width="16" height="16" alt="' + kind + '"/>' + fn + '</td>';
         }
         if (book.listDisp.familyName) {
-          listing += '<td class="name"><img src="' + kindIcon + '" width="16" height="16" alt="' + kind + '"/>' + familyName + '</td>';
+          listing += '<td class="name" id="bwCardFamName-' + index + '-' + i + '"><img src="' + kindIcon + '" width="16" height="16" alt="' + kind + '"/>' + familyName + '</td>';
         }
         if (book.listDisp.givenNames) {
           listing += '<td class="name">' + givenNames + '</td>';
@@ -283,7 +278,7 @@
           
         // if we have a group, we need to add it to the groups list that belongs in the menu tree
         if (kind == "group") {
-          groups += '<li id="bwBookGroup-' + index + '-' + i + '" class="group">' + fn + '</li>';
+          groups += '<li id="bwBookGroup-' + index + '-' + i + '"><a href="#" id="bwBookGroupLink-' + index + '-' + i + '" class="bwGroup">' + fn + '</a></li>';
         }
           
       }
@@ -303,7 +298,9 @@
       helper: function (e,ui) {
          return $(this).clone().appendTo('body').css('zIndex',5).show();
       } 
-    }) 
+    })
+    
+    /* uncomment if we choose to separate icons from the name field
     // make the list items draggable by icon too
     $("#bwAddrBookOutputList td.kind").draggable({ 
       opacity: 0.5,
@@ -312,6 +309,7 @@
          return $(this).clone().appendTo('body').css('zIndex',5).show();
       } 
     })
+    */
 
   };
    
@@ -406,8 +404,6 @@
   };
   
   this.updateContact = function() {
-    // For now, we'll assume there is only one book to which we can write.
-    var addrBookUrl = bwAddressBook.defPersBookUrl;
     var curCard = jQuery.parseJSON(bwAddressBook.books[bwAddressBook.book].vcards[bwAddressBook.card]);
     
     var vcData = "BEGIN:VCARD\n"
@@ -438,11 +434,6 @@
   // *******************
 
   this.addGroup = function() {
-    // For now, we'll assume there is only one book to which we can write.
-    // In the future, we'll want to check to see if there is more than 
-    // one personal book, and check which is selected.
-    var addrBookUrl = bwAddressBook.defPersBookUrl;
-    
     // Create the UUID
     var newUUID = "BwABC-" + Math.uuid();
     
@@ -463,8 +454,6 @@
   };
   
   this.updateGroup = function() {
-    // For now, we'll assume there is only one book to which we can write.
-    var addrBookUrl = bwAddressBook.defPersBookUrl;
     var curCard = jQuery.parseJSON(bwAddressBook.books[bwAddressBook.book].vcards[bwAddressBook.card]);
     
     var vcData = "BEGIN:VCARD\n"
@@ -478,22 +467,81 @@
     vcData += "CLASS:PRIVATE\n";
     vcData += "REV:" + getRevDate() + "\n";
     vcData += "NOTE:" + $("#GROUP-NOTE").val() + "\n";
+    if (curCard.MEMBER != undefined) {
+      $(curGroup.MEMBER).each(function() {
+        vcData += "MEMBER:mailto:" + $(this).value + "\n";
+      }); 
+    }
     vcData += "END:VCARD";
     
     this.updateEntry(vcData,curCard.href,curCard.etag,"#groupForm");
-  };  
+  };
   
+  // group is a json object
+  // memberMailTo is a mailto address -- we won't arrive here without it
+  this.addMemberToGroup = function(bookIndex,groupIndex,memberBookIndex,memberIndex) {
+    // get the current member to be added
+    var curMember = jQuery.parseJSON(bwAddressBook.books[memberBookIndex].vcards[memberIndex]);
+    
+    if (curMember.KIND[0].value == "group"){
+      // can't add groups to groups
+      showMessage(bwAbDispDisallowed,bwAbDispNoMemberAddGroup,true);
+    } else if (curMember.EMAIL == undefined) {
+      // the member has no email (mailto) address, so disallow adding it to a group
+      showMessage(bwAbDispDisallowed,bwAbDispNoMemberAddEmail,true);
+    } else {
+      // get the group
+      var curGroup = jQuery.parseJSON(bwAddressBook.books[bookIndex].vcards[groupIndex]);
+      
+      // check for the existence of the properties (UID must be ok or we should simply fail out)
+      var fn ="";
+      if(curGroup.FN != undefined) { 
+        fn = curGroup.FN[0].value; 
+      }
+      var nickname ="";
+      if(curGroup.NICKNAME != undefined) { 
+        fn = curGroup.NICKNAME[0].value; 
+      }
+      var org = "";
+      if(curGroup.ORG != undefined) { 
+        org = curGroup.ORG[0].values.organization_name; 
+      }
+      var note = "";
+      if(curGroup.NOTE != undefined) { 
+        url = curGroup.NOTE[0].value; 
+      } 
+      
+      // now let's build the vcard
+      var vcData = "BEGIN:VCARD\n"
+      vcData += "VERSION:4.0\n";
+      vcData += "UID:" + curGroup.UID[0].value + "\n";
+      vcData += "FN:" + fn + "\n";
+      vcData += "N:" + fn + ";;;;\n";
+      vcData += "KIND:group\n";
+      vcData += "ORG:" + org + ";;\n";
+      vcData += "NICKNAME:" + nickname + "\n";
+      vcData += "CLASS:PRIVATE\n";
+      vcData += "REV:" + getRevDate() + "\n";
+      vcData += "NOTE:" + note + "\n";
+      if (curGroup.MEMBER != undefined) {
+        $(curGroup.MEMBER).each(function() {
+          vcData += "MEMBER:mailto:" + $(this).value + "\n";
+        }); 
+      }
+      // now tag on the new member:
+      vcData += "MEMBER:mailto:" + curMember.EMAIL[0].value + "\n";
+      vcData += "END:VCARD";
+      
+      this.updateEntry(vcData,curGroup.href,curGroup.etag,"#groupForm");
+    };
+  };
   
+  
   // **********************
   // LOCATION FORM HANDLING
   // **********************
 
   this.addLocation = function() {
-    // For now, we'll assume there is only one book to which we can write.
-    // In the future, we'll want to check to see if there is more than 
-    // one personal book, and check which is selected.
-    var addrBookUrl = bwAddressBook.defPersBookUrl;
-    
     // Create the UUID
     var newUUID = "BwABC-" + Math.uuid();
         
@@ -520,8 +568,6 @@
   };
   
   this.updateLocation = function() {
-    // For now, we'll assume there is only one book to which we can write.
-    var addrBookUrl = bwAddressBook.defPersBookUrl;
     var curCard = jQuery.parseJSON(bwAddressBook.books[bwAddressBook.book].vcards[bwAddressBook.card]);
     
     var vcData = "BEGIN:VCARD\n"
@@ -587,6 +633,10 @@
     }
   }
   
+  // *******************
+  // DISPLAY HANDLING
+  // *******************
+ 
   this.display = function() {
     var index = bwAddressBook.book;
     
@@ -664,8 +714,19 @@
     $("#bwAddrBookOutputDetails").html(details);
     showPage("bw-details");
   }
+  
+  // *******************
+  // FILTERING
+  // *******************
+
+  this.filterByGroup = function(bookIndex,groupIndex) {
+    alert("We will filter by book " + bookIndex + " vcard " + groupIndex);
+  }
     
-  // Getters and Setters
+  // *******************
+  // GETTERS AND SETTERS
+  // *******************
+
   this.setBook = function(val) {
     bwAddressBook.book = val; 
   }
@@ -742,21 +803,52 @@
   // DISPLAY HANDLERS
   // *****************
   
-  // select a book to display
-  $(".bwBook").click(function() {
+  // select a book or subscription to display
+  $(".bwBookLink").click(function() {
     // extract the book array index from the id
     bwAddrBook.setBook($(this).attr("id").substr($(this).attr("id").indexOf("-")+1));
     
-    // remove highlighting from all books
-    $(".bwBook a").each(function(index){
+    // remove highlighting from all menu items
+    $("#booksAndGroups a").each(function(index){
       $(this).removeClass("selected");
     });
     // now highlight the one just selected
-    $(this).find("a:first-child").addClass("selected");
+    $(this).addClass("selected");
     
     bwAddrBook.display();
+    
+    // set a cookie so we can hold on to the current menu item
+    // between page refreshes
+    //$.cookie("selectedMenuId",$(this).attr("id"));
+    //alert($.cookie("selectedMenuId"));
   });
-
+  
+  //select a group to display
+  $(".bwGroup").click(function() {
+    // Extract the book array index from the id
+    // Though we are only filtering, we have to set the book (as there may be more than one)
+    var groupRef = $(this).attr("id").substr($(this).attr("id").indexOf("-")+1);
+    var bookIndex = groupRef.substring(0,groupRef.indexOf("-"));
+    var groupIndex = groupRef.substr(groupRef.indexOf("-")+1);
+    
+    bwAddrBook.setBook(bookIndex);
+    
+    // remove highlighting from all menu items
+    $("#booksAndGroups a").each(function(index){
+      $(this).removeClass("selected");
+    });
+    // now highlight the one just selected
+    $(this).addClass("selected");
+    
+    bwAddrBook.display();
+    bwAddrBook.filterByGroup(bookIndex,groupIndex);
+    
+    // set a cookie so we can hold on to the current menu item
+    // between page refreshes
+    //$.cookie("selectedMenuId",$(this).attr("id"));
+    //alert($.cookie("selectedMenuId"));
+  });
+  
   // display vcard details
   $(".bwAddrBookTable tr").click(function() {
     // get the part of the id that holds the indices
@@ -829,7 +921,43 @@
     showPage("bw-modResource");
   });
   
+  /* disable book droppables for now - while we have only one assumed 
+   * droppable book, additions will be made directly from 
+   * search results     
+   $("#booksAndGroups a.bwBook").droppable({ 
+    accept: '#bwAddrBookOutputList td.name',
+    greedy: true,
+    hoverClass: 'droppableHighlight',  
+    drop:   function () { 
+      showMessage(bwAbDispUnimplementedTitle,bwAbDispUnimplemented,true);
+      return false; 
+    } 
+  });
+  */ 
   
+  // add a member to group by dragging and dropping
+  $("#booksAndGroups a.bwGroup").droppable({ 
+    accept: '#bwAddrBookOutputList td.name', 
+    greedy: true,
+    hoverClass: 'droppableHighlight',
+    drop:   function (event, ui) { 
+      // get the group indices
+      var groupRef = $(this).attr("id").substr($(this).attr("id").indexOf("-")+1);
+      var bookIndex = groupRef.substring(0,groupRef.indexOf("-"));
+      var groupIndex = groupRef.substr(groupRef.indexOf("-")+1);
+      
+      // get the member indices
+      var memberRef = ui.draggable.attr("id").substr(ui.draggable.attr("id").indexOf("-")+1);
+      var memberBookIndex = memberRef.substring(0,memberRef.indexOf("-"));
+      var memberIndex = memberRef.substr(memberRef.indexOf("-")+1);
+      
+      // pass them to the update method
+      bwAddrBook.addMemberToGroup(bookIndex,groupIndex,memberBookIndex,memberIndex);
+      return false; 
+    } 
+  }); 
+  
+  
   // EDITING
   
   //show form for editing an item



More information about the Bedework-commit mailing list