Wednesday 19 June 2013

Filter list view based on membership in SharePoint group

Filter list view based on membership in SharePoint group

This script filters a list view based on membership in SharePoint groups. The filtering has nothing to do with item level security, it is merely a method for filtering by comparing a users group membership against a text field containing a group name. This column “VisibleTo” must contain the actual group names from the “People and Groups” list in SharePoint.
This method gives you the ability to filter the list view based on multiple criteria. If the user is member of multiple groups, the list will display all items relevant to any of the groups. You may also specify that elements where the column “VisibleTo” is empty will be displayed for all visitors. The “VisibleTo” column can be a multiple choice checkbox type column.
As always we start like this:
Create a document library to hold your scripts (or a folder on the root created in SharePoint Designer). In this example i have made a document library with a relative URL of “/test/English/Javascript” (a sub site named “test” with a sub site named “English” with a document library named “Javascript”):
IMG
The jQuery-library is found here. The pictures and the sourcecode refers to jquery-1.3.2.min. If you download another version, be sure to update the script reference in the sourcecode.
The scripts “interaction.js” and “stringBuffer.js” is created by Erucy and published on CodePlex.
The script “AccessUserProfileInWSS.js” is found here.
Note:
  • If used in grouped views, you must have the groups initially expanded, otherwise the elements are not rendered and cannot be filtered.
  • Only one level of grouping is currently supported.
  • Boxed view are not supported.
  • The filter does not apply in a datasheet view.
Add a CEWP below the list view webpart, and add this code:
01<script type="text/javascript" src="../../Javascript/jquery-1.3.2.min.js"></script>
02<script type="text/javascript" src="../../Javascript/interaction.js"></script>
03<script type="text/javascript" src="../../Javascript/stringBuffer.js"></script>
04<script type="text/javascript" src="../../Javascript/AccessUserProfileInWSS.js"></script>
05<script type="text/javascript" src="../../Javascript/FilterListViewByGroupMembership.js"></script>
06<script type="text/javascript">
07  
08// Find the user login name
09var ui = getUserInfo(); 
10var userLoginName = ui['Name'];
11// Get the group collection for the current user
12var ug = getGroupCollectionObjFromUser(userLoginName);
13// Set the filter - if you want the results to include elements in a specific group by default, specify it in the array below
14filterVal = [];
15// Define the group - find the group ID in "People and Groups"
16var groupIdTeam1 = 145;
17var groupIdTeam2 = 146;
18// Build the filter - add more if's to complete your filter
19// Is the user member of the group with id 145?
20if(ug[groupIdTeam1]!=undefined){
21    filterVal.push(ug[groupIdTeam1]);
22}
23// Is the user member of the group with id 146?
24if(ug[groupIdTeam2]!=undefined){
25    filterVal.push(ug[groupIdTeam2]);
26}
27  
28// Call the function
29filterListViewByGroupMembership('VisibleTo',filterVal,true,true,true);
30</script>
The sourcecode for the file “FilterListViewByGroupMembership.js”:
001/* Filter list view by membership in SharePoint group - hide the column header and the filter column if specified
002 * -----------------------------
003 * Created by Alexander Bautz
004 * LastMod 15.02.2010
005 * -----------------------------
006 * Include reference to:
007    jquery - http://jquery.com
008    interaction.js - http://spjslib.codeplex.com/
009    stringBuffer.js - http://spjslib.codeplex.com/
010    AccessUserProfileInWSS.js
011    FilterListViewByGroupMembership.js
012 * -----------------------------
013   If used in grouped views, you must have the groups initially expanded, otherwise the elements are not rendered and cannot be filtered.
014   Note: only one group level is currently supported.
015*/
016  
017function filterListViewByGroupMembership(FieldInternalName,filterValueArr,includeEmpty,hideFilterCol,collapseGroupedViews){
018filterOK = true;
019    // Build object of all headings
020    if(typeof(filterColIndex)=='undefined'){
021        if(typeof(FieldInternalName)=='string'){
022            intName = FieldInternalName;
023            hideTD = hideFilterCol;
024            fvArr = filterValueArr;
025            inclEmpty = includeEmpty;
026        }
027        filterColIndex = '';
028        $(".ms-viewheadertr th").each(function(){
029            if($(this).find('table:first').attr('name')==intName){
030                filterColIndex = $(this).attr('cellIndex'); 
031                displayName = $(this).find('table:first').attr('displayname');
032                // If the parameter "hideFilterCol" is true, remove the column
033                if(hideTD){
034                    $(this).remove()
035                }
036            }
037        });
038          
039        if(filterColIndex==''){
040            filterOK = false;
041            var str = "<font color='red'>The column with FieldInternalName  "" + intName + "", must be in the view for the filter to work.</font>";
042            $("td.ms-toolbar[width='99%']").append("<div id='hoverDelayInfo' class='ms-listheaderlabel' style='text-align:center;margin-top:-15px'>" + str + "</div>");
043        }
044    }
045      
046    // Apply filter
047    if(filterOK){
048        // Build view header text
049        if(inclEmpty && fvArr.length==0){
050            fvArr.push('');
051            var fv = displayName + " = empty";
052        }else if(inclEmpty && fvArr.length>0){
053            fvArr.push('');
054            var fv =  displayName + " = " + fvArr.join(' or ') + " or empty";
055        }else if(!inclEmpty && fvArr.length==0){
056            var fv = "No filtervalues found - all items hidden";
057        }else if(!inclEmpty && fvArr.length>0){
058            var fv =  displayName + " = " + fvArr.join(' or ');
059        }       
060        // Insert view header text
061        if($("#filterInfo").length==0){
062            $("td.ms-toolbar[width='99%']")
063                .append("<div id='filterInfo' class='ms-listheaderlabel' style='text-align:center;margin-top:-15px'>" +
064                        "<span style='cursor:default'><img src='/_layouts/images/filter.gif'>&nbsp;" + fv + ".</span></div>");
065        }
066  
067        // Find all rows and apply filter
068        $("table.ms-listviewtable tbody:not([id^='aggr']) tr:has(td.ms-vb2) >td[cellIndex=" + filterColIndex + "]").each(function(){ 
069            var thisTd = $(this);
070            // Build array from all values in "Visible to" - column
071            var arrCurrTDtext = thisTd.text().split(';');
072            var keeper = false;
073            // Find all keepers
074            $.each(arrCurrTDtext,function(i,val){
075                var thisVal = $.trim(val);
076                if($.inArray(thisVal,fvArr)>-1){
077                    keeper = true;
078                }
079            }); 
080            // Remove the ones that do not match
081            if(!keeper){
082                thisTd.parents('tr:first').remove();                
083            }           
084            // If the parameter "hideFilterCol" is true, remove the column          
085            if(hideTD){
086                $(this).remove()
087            }
088        });
089          
090        // Test whether the view is grouped twice and give alert
091        if($("td.ms-gb2").length>0)alert("Sorry, but this script does not handle views grouped twice.");
092        // Loop trough every tbody to remove empty and to update item count
093        $("tbody[isloaded='true'][beenthere!='true']").each(function(){
094            $(this).attr('beenthere',true)
095            var gId = $(this).attr('id');
096            var gIdPart = gId.substring(4,gId.length-1);
097                // Number of elements remaining
098                var trLength = $(this).find("td.ms-vh-group").length;               
099                if(trLength==0){    
100                    // Remove the group heading and remaining elements for the group            
101                    $("#titl"+gIdPart).remove();
102                    $("#foot"+gIdPart+"_").remove();
103                    $(this).remove();
104                }else{
105                    // Write the new count to the group heading
106                    $("#titl"+gIdPart).find('td.ms-gb span:last').html("&lrm;(" + trLength + ")");
107                }
108        });
109          
110        // Collapse all groups - they must be expanded by default for the filter to apply
111        if(collapseGroupedViews){
112            $("td.ms-gb").each(function(){
113                $(this).find('a:first').click();
114            });
115        }
116          
117        // Fix highlighting of every other row
118        var classToFind = '';
119        if($("table.ms-listviewtable").find('tr.ms-alternating').length>0){
120            var classToFind = 'ms-alternating';
121        }else if($("table.ms-listviewtable").find('tr.ms-alternatingstrong').length>0){
122            var classToFind = 'ms-alternatingstrong';
123        }
124        if(classToFind!=''){
125            $("table.ms-listviewtable tr:has(td.ms-vb2)").each(function(i,row){
126                if(i%2==0){
127                    $(this).addClass(classToFind);
128                }else{
129                    $(this).removeClass(classToFind);
130                }
131                  
132            });
133        }
134          
135    }
136}
137  
138/*
139 * Function to get the groupCollectionfrocurrent user.
140 * Requires the scripts interaction.js and stringBuffer.js to be loaded
141*/
142function getGroupCollectionObjFromUser(userLoginName){
143    var result = {};
144    innerPost(wsBaseUrl + 'usergroup.asmx'
145        'http://schemas.microsoft.com/sharepoint/soap/directory/GetGroupCollectionFromUser',
146        '<GetGroupCollectionFromUser xmlns="http://schemas.microsoft.com/sharepoint/soap/directory/"><userLoginName>' + userLoginName + '</userLoginName></GetGroupCollectionFromUser>',
147        function(data){     
148            $('Group', data).each(function(idx, itemData){
149                result[$(itemData).attr('ID')] = $(itemData).attr('Name');
150            });
151        });
152    return result;
153}
154  
155// Attaches a call to the function to the "expand grouped elements function" for it to function in grouped listview's
156function ExpGroupRenderData(htmlToRender, groupName, isLoaded){
157    var tbody=document.getElementById("tbod"+groupName+"_");
158    var wrapDiv=document.createElement("DIV");
159    wrapDiv.innerHTML="<TABLE><TBODY id="tbod"+groupName+"_" isLoaded=""+isLoaded+"">"+htmlToRender+"</TBODY></TABLE>";
160    tbody.parentNode.replaceChild(wrapDiv.firstChild.firstChild,tbody);
161javascriptFilterView();
162}
Save as “FilterListViewByGroupMembership.js”, mind the file extension, and upload to the scriptlibrary as shown above.

No comments:

Post a Comment