Wednesday 9 November 2011

Managing SharePoint Site User Memberships in Multiple Groups Using SPServices

I manage about 115 groups in a single site collection…and that number is expected to grow. I found that when a new user came on board or changed duty positions, getting them into the right SP groups was slow and cumbersome through the SP interface.
Using the SPServices libraries, I was able to create a simple interface to add/remove a single user to/from multiple groups at once. When you identify/select a user, it will show you two select lists. The right side will list all of the groups the current user is a member of while the left box shows all the groups the user is NOT a member of. Between the two select lists are buttons to ‘move’ the groups from one side to the other for the identified user (while modifying their memberships appropriately in the process). The select boxes are configured to allow multiple select so you can usually perform the maintenance in just a couple clicks. The code fits neatly into a CEWP.
Of course I wanted to see it. Geoff’s code sounded exactly like the kind of thing that I think SPServices is good for: a useful solution that solves a business problem better than SharePoint out of the box without needing to deploy anything to the server.
Developing a SharePoint site to assist a large organization with information management and integration with Microsoft Office (sharing/synchronizing data between SharePoint sites and Word/Excel/Access files).
The code uses a number of Users and Groups Web Service operations that are wrapped in SPServices:
  • GetUserCollectionFromSite
  • GetGroupCollectionFromUser
  • GetGroupCollectionFromSite
  • AddUserToGroup
  • RemoveUserFromGroup
Here’s the code. It’s amazingly compact and gets the job done well.
 
001$(document).ready(function() {
002  //Populate the users pick list
003  var strHTMLSiteUsers = "";
004  $().SPServices({
005      operation: "GetUserCollectionFromSite",
006      async: false,
007      completefunc: function(xData, Status) {
008        $(xData.responseXML).find("[nodeName='User']").each(function() {
009          strHTMLSiteUsers += "<option value='" + $(this).attr("LoginName") + "'>" + $(this).attr("Name") + "</option>";
010        });
011        $("#my_SiteUsers").append(strHTMLSiteUsers);
012      }
013  });
014  RefreshGroupLists();
015});
016  
017function RefreshGroupLists(){
018  var strHTMLAvailable = "";
019  var strHTMLAssigned = "";
020  var arrOptionsAssigned = new Array();
021  var intOpts = 0;
022  var booMatch;
023  var booErr = "false";
024  
025  $("#my_SPGroupsAssigned").html("");
026  $("#my_SPGroupsAvailable").html("");
027  
028  if($("#my_SiteUsers").attr("value") == 0){
029    alert("You must select a user");
030    return;
031  }
032  
033  //Populate the Groups Assigned
034  $().SPServices({
035      operation: "GetGroupCollectionFromUser",
036      userLoginName: $("#my_SiteUsers").attr("value"),
037      async: false,
038      completefunc: function(xData, Status) {
039        $(xData.responseXML).find("[nodeName='errorstring']").each(function() {
040          alert("User not found");
041          booErr = "true";
042          return;
043        });
044        $(xData.responseXML).find("[nodeName='Group']").each(function() {
045          strHTMLAvailable += "<option value='" + $(this).attr("Name") + "'>" + $(this).attr("Name") + "</option>";
046          arrOptionsAssigned[intOpts] = $(this).attr("Name");
047          intOpts = intOpts + 1;
048        });
049        $("#my_SPGroupsAssigned").append(strHTMLAvailable);
050      }
051  });
052  
053  //Populate available site groups
054  if(booErr == "false"){
055    $().SPServices({
056        operation: "GetGroupCollectionFromSite",
057        async: false,
058        completefunc: function(xData, Status) {
059          $(xData.responseXML).find("[nodeName='Group']").each(function() {
060            booMatch = "false";
061            for (var i=0;i<=arrOptionsAssigned.length;i++){
062              if($(this).attr("Name") == arrOptionsAssigned[i]){
063                booMatch = "true";
064                break;
065              }
066            }
067            if(booMatch == "false"){
068              strHTMLAssigned += "<option value='" + $(this).attr("Name") + "'>" + $(this).attr("Name") + "</option>";
069            }
070          });
071          $("#my_SPGroupsAvailable").append(strHTMLAssigned);
072        }
073    });
074  }
075}
076  
077function AddGroupsToUser(){
078  var i;
079  
080  if($("#my_SiteUsers").attr("value") == 0){
081    alert("You must select a user");
082    return;
083  }
084  
085  if($("#my_SPGroupsAvailable").val() == null){
086    alert("You haven't selected any groups to add");
087    return;
088  }
089  else{
090    var arrGroups = $("#my_SPGroupsAvailable").val();
091    for (i=0;i<arrGroups.length;i++){
092      $().SPServices({
093          operation: "AddUserToGroup",
094          groupName: arrGroups[i],
095          userLoginName: $("#my_SiteUsers").attr("value"),
096          async: false,
097          completefunc: null
098      });
099    }
100    RefreshGroupLists();
101  }
102}
103  
104function RemoveGroupsFromUser(){
105  var i
106  
107  if($("#my_SiteUsers").attr("value") == 0){
108    alert("You must select a user");
109    return;
110  }
111  
112  if($("#my_SPGroupsAssigned").val() == null){
113    alert("You haven't selected any groups to remove");
114    return;
115  }
116  else{
117    var arrGroups = $("#my_SPGroupsAssigned").val();
118    for (i=0;i<arrGroups.length;i++){
119      $().SPServices({
120          operation: "RemoveUserFromGroup",
121          groupName: arrGroups[i],
122          userLoginName: $("#my_SiteUsers").attr("value"),
123          async: false,
124          completefunc: null
125      });
126    }
127    RefreshGroupLists();
128  }
129}
and the associated markup:
 
01<table align="center">
02  <tr>
03    <td colspan="3" style="text-align:center">
04      <font style="font-weight:bold">Select a User:   </font>
05      <select id="my_SiteUsers" style="width:350px;" onchange="RefreshGroupLists()"></select>
06    </td>
07  </tr>
08  <tr>
09    <th class='ms-vh2'>Available Groups</th>
10    <th></th>
11    <th class='ms-vh2'>Assigned Groups</th>
12  </tr>
13  <tr>
14    <td class='ms-vb2'>
15      <select id="my_SPGroupsAvailable" style="width:250px;height:450px;" multiple="multiple"></select>
16    </td>
17    <td>
18      <button id="my_AddGroupsToUser" style="width:80px;" onclick="AddGroupsToUser()">>></button><br><br>
19      <button id="my_RemoveGroupsFromUser" style="width:80px;" onclick="RemoveGroupsFromUser()"><<</button></td>
20    <td class='ms-vb2'>
21      <select id="my_SPGroupsAssigned" style="width:250px;height:450px;" multiple="multiple"></select>
22    </td>
23  </tr>
24</table>
And here’s the net result. It’s a simple little form that does exactly what it would. All I had to do to get it running in my environment was to change the references to the script files to point where I have them stored. Otherwise, it worked with no modification whatsoever.
2011-11-06-ManagingSPUserMembership-01.png
This is the sort of thing that may belong in SPServices. Of course, you can simply copy and use the code above, but perhaps some more options and additional functionality would make it even more useful. What do you think? Is this something you’d use?

1 comment:

  1. I am new to SP scripting and tried to use the code by creating a CEWP with the jscript code and one CEWP with the table mark-up. The Form displays but no data is visible.
    What did I do wrong?

    I've added 2 lines prior to the script code with reference to jquery-1.6.4.min.js and the jquery.SPServices-0.7.1a.min.js

    ReplyDelete