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”):
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:
<script type="text/javascript" src="../../Javascript/jquery-1.3.2.min.js"></script> <script type="text/javascript" src="../../Javascript/interaction.js"></script> <script type="text/javascript" src="../../Javascript/stringBuffer.js"></script> <script type="text/javascript" src="../../Javascript/AccessUserProfileInWSS.js"></script> <script type="text/javascript" src="../../Javascript/FilterListViewByGroupMembership.js"></script> <script type="text/javascript"> // Find the user login name var ui = getUserInfo(); var userLoginName = ui['Name']; // Get the group collection for the current user var ug = getGroupCollectionObjFromUser(userLoginName); // Set the filter - if you want the results to include elements in a specific group by default, specify it in the array below filterVal = []; // Define the group - find the group ID in "People and Groups" var groupIdTeam1 = 145; var groupIdTeam2 = 146; // Build the filter - add more if's to complete your filter // Is the user member of the group with id 145? if(ug[groupIdTeam1]!=undefined){ filterVal.push(ug[groupIdTeam1]); } // Is the user member of the group with id 146? if(ug[groupIdTeam2]!=undefined){ filterVal.push(ug[groupIdTeam2]); } // Call the function filterListViewByGroupMembership('VisibleTo',filterVal,true,true,true); </script>
The sourcecode for the file “FilterListViewByGroupMembership.js”:
/* Filter list view by membership in SharePoint group - hide the column header and the filter column if specified * ----------------------------- * Created by Alexander Bautz * LastMod 15.02.2010 * ----------------------------- * Include reference to: jquery - http://jquery.com interaction.js - http://spjslib.codeplex.com/ stringBuffer.js - http://spjslib.codeplex.com/ AccessUserProfileInWSS.js FilterListViewByGroupMembership.js * ----------------------------- If used in grouped views, you must have the groups initially expanded, otherwise the elements are not rendered and cannot be filtered. Note: only one group level is currently supported. */ function filterListViewByGroupMembership(FieldInternalName,filterValueArr,includeEmpty,hideFilterCol,collapseGroupedViews){ filterOK = true; // Build object of all headings if(typeof(filterColIndex)=='undefined'){ if(typeof(FieldInternalName)=='string'){ intName = FieldInternalName; hideTD = hideFilterCol; fvArr = filterValueArr; inclEmpty = includeEmpty; } filterColIndex = ''; $(".ms-viewheadertr th").each(function(){ if($(this).find('table:first').attr('name')==intName){ filterColIndex = $(this).attr('cellIndex'); displayName = $(this).find('table:first').attr('displayname'); // If the parameter "hideFilterCol" is true, remove the column if(hideTD){ $(this).remove() } } }); if(filterColIndex==''){ filterOK = false; var str = "<font color='red'>The column with FieldInternalName "" + intName + "", must be in the view for the filter to work.</font>"; $("td.ms-toolbar[width='99%']").append("<div id='hoverDelayInfo' class='ms-listheaderlabel' style='text-align:center;margin-top:-15px'>" + str + "</div>"); } } // Apply filter if(filterOK){ // Build view header text if(inclEmpty && fvArr.length==0){ fvArr.push(''); var fv = displayName + " = empty"; }else if(inclEmpty && fvArr.length>0){ fvArr.push(''); var fv = displayName + " = " + fvArr.join(' or ') + " or empty"; }else if(!inclEmpty && fvArr.length==0){ var fv = "No filtervalues found - all items hidden"; }else if(!inclEmpty && fvArr.length>0){ var fv = displayName + " = " + fvArr.join(' or '); } // Insert view header text if($("#filterInfo").length==0){ $("td.ms-toolbar[width='99%']") .append("<div id='filterInfo' class='ms-listheaderlabel' style='text-align:center;margin-top:-15px'>" + "<span style='cursor:default'><img src='/_layouts/images/filter.gif'>&nbsp;" + fv + ".</span></div>"); } // Find all rows and apply filter $("table.ms-listviewtable tbody:not([id^='aggr']) tr:has(td.ms-vb2) >td[cellIndex=" + filterColIndex + "]").each(function(){ var thisTd = $(this); // Build array from all values in "Visible to" - column var arrCurrTDtext = thisTd.text().split(';'); var keeper = false; // Find all keepers $.each(arrCurrTDtext,function(i,val){ var thisVal = $.trim(val); if($.inArray(thisVal,fvArr)>-1){ keeper = true; } }); // Remove the ones that do not match if(!keeper){ thisTd.parents('tr:first').remove(); } // If the parameter "hideFilterCol" is true, remove the column if(hideTD){ $(this).remove() } }); // Test whether the view is grouped twice and give alert if($("td.ms-gb2").length>0)alert("Sorry, but this script does not handle views grouped twice."); // Loop trough every tbody to remove empty and to update item count $("tbody[isloaded='true'][beenthere!='true']").each(function(){ $(this).attr('beenthere',true) var gId = $(this).attr('id'); var gIdPart = gId.substring(4,gId.length-1); // Number of elements remaining var trLength = $(this).find("td.ms-vh-group").length; if(trLength==0){ // Remove the group heading and remaining elements for the group $("#titl"+gIdPart).remove(); $("#foot"+gIdPart+"_").remove(); $(this).remove(); }else{ // Write the new count to the group heading $("#titl"+gIdPart).find('td.ms-gb span:last').html("&lrm;(" + trLength + ")"); } }); // Collapse all groups - they must be expanded by default for the filter to apply if(collapseGroupedViews){ $("td.ms-gb").each(function(){ $(this).find('a:first').click(); }); } // Fix highlighting of every other row var classToFind = ''; if($("table.ms-listviewtable").find('tr.ms-alternating').length>0){ var classToFind = 'ms-alternating'; }else if($("table.ms-listviewtable").find('tr.ms-alternatingstrong').length>0){ var classToFind = 'ms-alternatingstrong'; } if(classToFind!=''){ $("table.ms-listviewtable tr:has(td.ms-vb2)").each(function(i,row){ if(i%2==0){ $(this).addClass(classToFind); }else{ $(this).removeClass(classToFind); } }); } } } /* * Function to get the groupCollectionfrocurrent user. * Requires the scripts interaction.js and stringBuffer.js to be loaded */ function getGroupCollectionObjFromUser(userLoginName){ var result = {}; innerPost(wsBaseUrl + 'usergroup.asmx', 'http://schemas.microsoft.com/sharepoint/soap/directory/GetGroupCollectionFromUser', '<GetGroupCollectionFromUser xmlns="http://schemas.microsoft.com/sharepoint/soap/directory/"><userLoginName>' + userLoginName + '</userLoginName></GetGroupCollectionFromUser>', function(data){ $('Group', data).each(function(idx, itemData){ result[$(itemData).attr('ID')] = $(itemData).attr('Name'); }); }); return result; } // Attaches a call to the function to the "expand grouped elements function" for it to function in grouped listview's function ExpGroupRenderData(htmlToRender, groupName, isLoaded){ var tbody=document.getElementById("tbod"+groupName+"_"); var wrapDiv=document.createElement("DIV"); wrapDiv.innerHTML="<TABLE><TBODY id="tbod"+groupName+"_" isLoaded=""+isLoaded+"">"+htmlToRender+"</TBODY></TABLE>"; tbody.parentNode.replaceChild(wrapDiv.firstChild.firstChild,tbody); javascriptFilterView(); }
Save as “FilterListViewByGroupMembership.js”, mind the file extension, and upload to the scriptlibrary as shown above.
Let me know if something is unclear.
Regards
Alexander
Is there a way to filter a calendar view with java or something else?
Hi,
I have not yet made any solutions that can do this, but i have some ideas on how it could be done. Please post a request in the Request’s post with the details on how the filter is supposed to work, I will then add it to the “article queue”. I cannot however promise any “delivery date”.
Alexander
If interested please look into the below link for filtering SPList items with Current User and Current User’s Group.
http://go.limeleap.com/community/bid/297846/Custom-List-View-Based-on-Current-User-Using-SharePoint-Designer
Thank you again for speedy reply. I will post my request in the request post. Ofcourse I understand you can’t promise any delivery date.
Thx for the the trouble anyway.
Hi, is it possible to modify this code to filter by userprofile only not by groupmembership?
Hi,
Edit line 12 in the CEWP code to query the user profile in stead – like described in this article Accessing user profile information in WSS 3.0 with javascript
I have not tested, but believe this should work without any further modification than the code in the CEWP.
Ask again if you do not understand.
Alexander
Hi,
thanks it worked. may problem now is my view has paging, and sometimes the record for a user doesnt display not unless i click on the paging link. think it still retains the current sorting of records
Hi,
This has to do with the fact that this filter is applied after the “original” items are rendered in the browser. If you have paging configured, you might set the “Item limit” to 20, but if none of this 20 items fit the javascript applied filter, the list will be empty.
I do not have any other solution than removing the “paging” option – or use the “Current user filter” found in MOSS 2007 (if you have MOSS).
Alexander
Hi,
Thanks for this article! Quick question? Will this work on a list which is used in a form? I sort of think it will not because the CEWP is rendering on the page, but how could it affect a form?
Any thoughts? Thanks in advance!
Tracey
Excellent work! I have a question though. It only work with one “Group by” choice. How do you add additional Group by fieled or choice?
What I mean is how do make it work for views grouped twice?
Hi,
The code currently supports only one group level, sorry.
Alexander
Hi,
great article. I am trying to implement this. I got the userName correctly.
But, it seems to be failing at this line.
var ug = getGroupCollectionObjFromUser(userLoginName);
After the above call, I am expecting the ug variable to contain something. if I check the length using ug.length, it is returning undefined.
any idea?
How do I get the groupID to be used here?
Many thanks,
Anu
Hi,
The variable ug is an object and has no “length”. You find the groupId in the “People and Groups” section in SharePoint. Go to the desired group and look at the URL and you will find the groupID like this:
…/_layouts/people.aspx?MembershipGroupId=3
Alexander
Hi, great bit of code. It works brill on a standard list view, but i’m trying to use it on a web part page with the list in the body and some other links on the right hand column, and it doesnt filter at all. Any ideas?
Hi,
This code will only work in a native list view. If you want to make it work in a custom web part page it will require modifications. If you look at some other of my scripts that modifies items in a list view, you might find some clues there.
Alexander
Ah, good to see it’s not just me then. I’m a complete newbie on both java and sharepoint (ok at VBA!), but i’ll have a look through your tips and see if I can make head or tail of the code!
Thanks for all the great stuff on this site
I think in function getGroupCollectionObjFromUser(userLoginName) on line number:
143 var result = {};
is an error. Shouldn’t it be like this
143 var result = []; ??
Then You can use returned object(var result) as an array and then it has length property.
Hi,
Sorry, but the function “getGroupCollectionObjFromUser” is supposed to return an object literal and not an array.
The variable “ug” in the CEWP code is an object and when you “ask” the object for its value for the property “group ID of your group”, you get the groupname.
Alexander
Hi Alex, will this method of filtering be supported in SP2010; I tried it on a SP 2010 list and it does not work; are there changes I need to make for this to work. Thanks
Hi,
The HTML is different from 2007 and the script would have to be modified to work. Another matter is that the view is updated/drawn asynchronously.
This will require the handling of grouped views to be different as the code must keep running at timed intervals to check whether the view have changed.
I cannot promise that this script will be “ported” to SP2010.
Alexander
If I could get this to work it would be exactly what i need I am still New to JavaScript and SharePoint.
For this Section Should I full qualify this since it is on the SharePoint site like below
For the Section If my groupIdReam1 was bobs_team and the ID was 123 Would every Were groupIdTeam1 show up need to be updated to B
// Define the group – find the group ID in “People and Groups”
bobs_team or leave it alone and update the ID like this var groupIdTeam1 = 123;
var groupIdTeam1 = 145;
var groupIdTeam2 = 146;
Thanks
Unfortunately the link downloads a file that is of no use. The scripts “interaction.js” and “stringBuffer.js” is created by Erucy and published on CodePlex. Can you provide a better link?
Hi,
Go here http://spjslib.codeplex.com/releases/view/22639 and download the file named “SPJsLib.zip”.
Alexander
Hpw did you get the following value?
var groupIdTeam1 = 145;
var groupIdTeam2 = 146;
Can this solution work in sharepoint 2010
Hi,
Go to the People and Groups page, click on your group and look at the URL for the ID parameter.
I think this should also work in 2010.
Alexander
Can this be used to filter the values of a drop down field based on his group membership?
Yes, but it will need some modifications. From the file “FilterListViewByGroupMembership.js” you need only the function “getGroupCollectionObjFromUser”.
In the CEWP code you will have to write the logic for which option to show for each group and loop trough the options in the dropdowns – hiding the ones that does not apply.
See what you can make out of it. Ask if you need any more guidance.
Alexander
When I add the CEWP, it removes the “Views” altogether. I have the ID correct. I’m in the same boat where I just want specific views to be in the view drop down list. How would I go about creating this list? Ex: view named ABC.aspx and DEF.aspx???
As you can see, I’m a little new to jQuery. I have some exposure to javascript. I’ve been able to get the CEWPs to work that I’ve tried, except this one so far.
I neglected to mention, I’m working on SharePoint 2010.
Hi –
My test user, who is a member of a group selected from the VisibleTo column keeps getting prompted for her login information.
And the items in the list where she has selected the proper group actually will not display for her – so it’s kind of working backwards!
I’m sure I have something bolloxed up – any ideas? Any help will be appreciated.
Hi,
This solution has nothing to do with user rights. It’s only a method of filtering items from the view if the user is not a member (again – no rights, only member or not) of a given group.
Alexander
Hi Alex,
Great post! I know you mentioned this only works on a native view but I wanted to know if you can apply the same concept for users to have certain views based on membership group?
For example, I have the standard AllItems view but I also have four other views that I created. What I would like is for certain groups to have access to specific views that were created.
Currently I have had to have different groups create personal views individually to make this happen but it would be great if we could create a public view as an administrator and have only certain group have access to that view.
Any help would be greatly appreciated.
Hi, I’m sorry, but I do not have such a solution. Alexander
You can also check this:
http://stackoverflow.com/questions/3991661/sharepoint-view-how-to-see-items-assigned-to-me-or-to-a-group-im-in/3998567#3998567
Really easy solution
Hi
I we can achieve this using SharePoint designer. After applying a membership filter the view will only show the items for the user or usergroups.
Check the follwoing link
http://sharepointcodes.com/filter-list-view-by-user-and-groups-in-sharepoint/
Will this work on 2013?
No, this code will not work in SP2013.
Alexander