Let’s say your users want to have an easy way to filter items in a SharePoint list or library, but for some specific reason they should be able to do this with some other functionality than the standard filtering made available in the list&library column header. With a little help of jQuery and SPServices you can easily achieve this and add some dropdowns onto a page, and you can even easily add a nice design (though I’ll leave this part out of this article and leave it up to you to implement with some CSS).

 


What we want to achieve

The following screenshot shows how this solution allows you to apply filters to a list similar to the way these standard column header filters work. As you can see, filters for the columns SingleLineOfText and Number have been applied already, I could also apply another filter for Currency.

Image(1)

You have the choice which columns you want to be filterable here. If you have 5 columns (Name, Address, ZIP, City, Country), you could supply filters for 2 columns (City, Country) only!

The benefit of this solution here is that it works anywhere. For example, you can use it in combination with a Data View Web Part instead of the standard list/library Web Part (Edit: DVWP work differently than the “normal” list/library web parts; I’m currently testing how to integrate this solution with them). Another option would be to provide users with nicer looking filter dropdowns somewhere else on the page (on top of the library; to the right; embedded within some descriptive text!; etc).
Also, this is probably the easiest way to get a dropdown of all possible unique filter values.

 


Background Information

The filters here do not recreate the standard filter menus, but rather reuse SharePoint’s very own creation mechanism (the same way that these standard menus are created). Basically, the filter menu for a list/library is created through JavaScript. You can find the relevant function addFilterMenuItems in the core.js file . Diving into its functionality, once can see that SharePoint actually calls the file /_layouts/filter.aspx when creating the filter menus. If you open this page manually with the relevant parameters, you get to see that it creates a dropdown just the way we need it:

Image(2)

An example for this URL is:
http://myserver/mysubsite/_layouts/filter.aspx?ListId=%7B8A624345%2DDB60%2D41E6%2D9863%2D3DAF60557DA1%7D&FieldInternalName=Region&ViewId={CDBA0419-769D-4AFB-9152-6D311DE99879}&FilterOnly=1&Filter=1

These relevant parameters are:

  1. the ID of the list/library that you’re using (ListId)
  2. the ID of the view that you’re using (ViewId)
  3. the name of the column that we want to filter (FieldInternalName)

Information about how to find all these parameters is listed further below in this article.

It is also important to note the following things:

  1. If one or more filters are applied, all other filters will take them into account. If I filter by Number in my example above, the dropdown for Currency will only show me the values for those rows which meet the Number filtering as well.
  2. If SharePoint doesn’t allow you to filter a field (e.g. multiple lines of text), you can’t filter it here

The important question is: how do we get the values from this dropdown onto our page?

In the discussion board of SPServices you can find a thread that briefly discusses how to retrieve the dropdown itself as well as it’s values. With some modifications, this code can be used for our solution.

 

The Code

The code below consists of two parts, a JavaScript section (including jQuery and SPServices usage) to retrieve the dropdown and prepare its output as well as a simple HTML section where we present the result of the JavaScript code.

//update the following 2 lines with your own local versions if wanted
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery.SPServices/2014.01/jquery.SPServices.min.js"></script>
<script type="text/javascript">
$("document").ready(function() {
//set default vars; replace them with your ownvar
listID = '{B858515E-A827-4444-98DA-E81B4F1AF0AD}';
var viewID = '%7B3C11FBF2%2D9702%2D4B76%2DB280%2D02A783B8E7FA%7D';
//load paramsvar
allVars = $().SPServices.SPGetQueryString();
var filterFieldsParams = "";
$.each(allVars, function( objKey, objValue ){
if(objKey.substr(0,11).toLowerCase()=="filterfield" || objKey.substr(0,11).toLowerCase()=="filtervalue"){
filterFieldsParams+="&"+objKey+"="+objValue;
}
});

function getAjaxFilter(name, internalName){
$.ajax({
url: $().SPServices.SPGetCurrentSite()+'/_layouts/filter.aspx?ListId='+listID+'&FieldInternalName='+internalName+'&ViewId='+viewID+'&FilterOnly=1&Filter=1'+filterFieldsParams,
success: function(data) {
// replace"<b>"+name+": </b>" with your own code if required
$('#filterField'+internalName).html("<b>"+name+": </b>").append($("<div></div>").append(data).find("select, img"));
//clear current onChange event
$("#diidFilter"+internalName).attr("onchange", '');
// add change event
$("#diidFilter"+internalName).change(function() {
FilterField(viewID,internalName,encodeURIComponent(this.options[this.selectedIndex].value), this.selectedIndex);
});
}
});
}
// provide selected filters
getAjaxFilter("Single Line of Text", "SingleLineOfText");
getAjaxFilter("Number", "Number");
getAjaxFilter("Currency", "Currency");
});
</script>
<div id="allFilters">
<div id="filterFieldSingleLineOfText"></div>
<div id="filterFieldNumber"></div>
<div id="filterFieldCurrency"></div>
</div>

 


Explanation

The first two lines load the necessary jQuery and SPServices scripts. In the beginning of the JavaScript code block, we first define the ID of the list/library and the view, and then to fetch any filter parameters that may have been applied already from the URL. In such a case, we want our filters to take into account any existing filters, so that unrealistic filter options are not shown (as mentioned under Background Information).

The function getAjaxFilter is the core of this solution. It calls the above mentioned filter.aspx page and fetches its data, filters it to return only any dropdown and any images (if a filter is applied, an icon is shown), and updates the dropdowns onChange event. The reason for this is that the default behaviour in this case doesn’t work properly when you want to remove a filter (when you select (All) from the dropdown). What we need to do here is to simply call the exact same JavaScript function FilterField (defined in core.js) with the correct parameters.

After the function declaration, we have 3 function calls, which you will later need to r
eplace with your own. Lastly, there are three named DIVs which are used later to “store” the results from the getAjaxFilter calls. They follow the naming convention filterFieldINTERNALFIELDNAME, so you need to update them accordingly with your own column names (see below for how to find them out).

 


Using it on your own page

As mentioned above, there are multiple ways how you can include this solution on your page. The easiest way is to add a Content Editor Web Part (CEWP) and paste the code into its Source Editor.

What you’ll need to apply it to your own list/library is the ID of it as well as the ID of the view that you’re using. Both IDs can be in either of the following two formats:
%7BB858515E%2DA827%2D4444%2D98DA%2DE81B4F1AF0AD%7D
or
{B858515E-A827-4444-98DA-E81B4F1AF0AD}

How do you get both required IDs? When you open the settings page of the list/library, you can find its ID as part of the URL:

Image(3)

An easy way to get the ID of the view that you’re using is to apply a filter through the list/library’s header row. Afterwards you can find the ID as part of the URL:

Image(4)

To get the internal name that is used for a column, go to the list/library’s settings, and click on the column name. The internal name can then be found as part of the URL as the parameter Field:

Image(5)

Please note that if you used certain special characters while creating the column, SharePoint will not use them for the internal name, but replace them with hex codes (http://abstractspaces.wordpress.com/2008/05/07/sharepoint-column-names-internal-name-mappings-for-non-alphabet/):

Image(6)

You will still need to bring these columns into a more readable format. For example, if you copy the name marked here (My%5Fx0020%5F1st%5Fx0020%5FTest%5Fx0020%5FColumn%5Fx0021%5F), and decode it at http://meyerweb.com/eric/tools/dencoder/, you will get the actual proper name My_x0020_1st_x0020_Test_x0020_Column_x0021_ which needs to be used

Once you have all these, replace the IDs in the code with your own, and create your own DIV wrappers and getAjaxFilter calls for your respective columns.

 


Possible Improvements

There are still some improvements that could be done. Depending on your own requirements (for example if you wish to reuse that code in multiple locations), you may want to consider calling getAjaxFilter with filterFieldsParams as parameter to avoid relying on it as a global variable. Also, this implementation is not flexible when it comes to creating output in different layouts. If you want to have different ways of displaying the filters (in a table row / with different style sheets / etc), I’d recommend to not do any output changes (namely the $(‘#filterField’+internalName).html(..) call), but rather return the result from getAjaxFilter and use it in your own function for further changes.

37 thoughts on “Providing Filter Dropdowns for a SharePoint List/Library with jQuery”

  1. Hien, I’ve tested it with Checkboxes as well as with a People column that allows multiple selections, it works for both. Generally I would say: if you can filter it with SharePoint directly, it works here (as I’m just reusing SharePoint’s own functionality)

  2. I can’t add this to my sharepoint 2010 site, can u help me?
    this is the error..

    Mensaje: Permiso denegado
    Línea: 2
    Carácter: 3238
    Código: 0
    URI: /whc/WHCLibImg/jquery-1.7.1.min.js

    1. Hi Javier,
      I would suggest that you use the non-minified version of jQuery, and use a JavaScript debugger (e.g. the Internet Explorer Developer Tools) to find out exactly where that error occurs.
      Right now I am as clueless as you about what’s happening and why

  3. I have followed to the best of my ability the instructions as outlined here. The result I get is a blank “Content Editor Web Part”. Is there something key that I am missing that would result in a blank web part?

  4. Hi Spencer,

    did you paste the code directly into a CEWP? If so, some of the code may have been stripped out by SharePoint. It’s better to put the code into a file, upload that file to SharePoint, and reference it from the CEWP’s properties.

    If you did that already, I don’t have any immediate idea why it doesn’t work. You could try to troubleshoot by checking if the URL get from “$().SPServices.SPGetCurrentSite()+’/_layouts/filter.aspx?ListId=’+listID+’&FieldInternalName=’+internalName+’&ViewId=’+viewID+’&FilterOnly=1&Filter=1’+filterFieldsParams” is available (wrong internalname, viewid, and/or listid would probably results in an empty page, thus an empty CEWP)

  5. A couple comments and then a quick question.

    Line 5 of your code, at the end (ownvar\) that \ causes issues with the code because it still thinks line 6 is commented out. If you delete that \, it will not cause issues with line 6 and the code will be able to read the listID.

    I struggled with this code for a while because I too was getting a blank CEWP even though I copied the code and replaced the proper areas correctly. When I did a JavaScript debugger, I found the issue – line 26 is missing a { at the end of the line. It should read .change(function() {

    Once I added that, everything worked properly. Hopefully that helps out others who might have issues.

    My question is concerning DVWP. You mentioned early in your post that you are testing how to integrate the solution with DVWP. Have you figured that out yet? I have a client that wants this exact functionality but utilizing the DVWP. Any updates or suggestions?

    Thanks for your help and thanks for providing this solution.

  6. Hi Kris,

    thanks a lot for that detailed and helpful comment! Not sure where those errors came from ( I copied & pasted from working code), just corrected the code above.

    As for the DVWP, I cannot remember at all how far I got. I think I haven’t touched the code above in more than a year, and I can’t remember what I meant with “the DVWP is different”. So, I don’t have any working solution or even an advise right now.
    Sadly, I also won’t have time to look into it in the next few weeks (a few other things on my plate, plus going to the SharePoint conference in Vegas in November), so I have to say that I can’t help you any further right now.

  7. Hi Rene,

    Although this is a post of > 2 years old I think it could be still very useful for me.
    Unfortunately I cannot get it up and running in SharePoint 2010. I get a Jquery permission denied error on line:
    $(‘#filterField’+internalName).html(““+name+”: “).append($(“”).append(data).find(“select, img”));

    It seems that it has problems appending the contents of ‘data’ to the div. When I use Fiddler and I check the raw response I do see the complete contents of the filter.aspx including the inline JavaScript functions, HTML etc. So apparantly it is not able to append the content of the dropdownlist to my div.
    Do you have any idea how to resolve this?

    Thanks in advance!

    Koen

  8. Hi Rene,

    Problem solved.
    Used JQuery’s parseHTML and appended it to the div so more a Jquery related question.

    Regards,

    Koen

    1. Hi Koen,

      glad that you managed to find a solution for your issue, and many thanks for sharing it here! I’ll have a closer look at it soon to see if including it generally in my code above might help others as well.

      Rene

      1. This is brilliant! I’ve been looking for a way to do this since forever, but I so far had not managed to dissect the javascript involved. Like Koen, I had the issue with permission denied and the use of jQuery.parseHTML sorted it out. The built in SharePoint List Filter web part is so very bad I never use it. This is exactly how it should work.

  9. Rene,

    Nice script you got there.

    Listen, I’ve made it work just fine on my server. I have quite a few filters I’d like to add though, and not all of them follow the same format. The first one was easy, it was a Select. How would I go around to add some additional filters in Date format, Checkbox and Text?

    Thanks

  10. I’ve been searching for how to do this type of thing for a while, and was so glad to find your explanation. Easily the most thorough and helpful walkthrough. My only doh! moment is that I hadn’t updated the reference to jQuery and SPServices, or changed the id of the div. Perhaps adding some comments to those sections in your code to remind us? 😉

    Also, if this can help anyone else, a quick way of referencing jQuery and SPServices is to use CDN method. So top two lines of Rene’s code would be:

    Also, in later versions of SharePoint consider using the Script Editor webpart instead of Content to ensure SharePoint doesn’t reformat it.

    Keep up the great work!

  11. Hi Rene,

    Love your solution. I am facing a small issue though. if the List column contains values that have & in it it filters on the string prior to &.

    For e.g if list contains P&G and I filter on that, the dropdown box just shows ‘P’. Is there a way to overcome this?

    1. Hi Jeff, fixed the code above. The call to the FilterField function now includes an encoded version of the value to filter (via encodeURIComponent). Let me know if this works for you or if there are any other issues

      1. Unfortunately this has the side-effect of double encoding spaces which then breaks the filter value.

        i.e. %20 becomes %2520 and so on

        Still a great solution however. I’m wondering if there’s a way to filter the list without a full page refresh? Seems that SharePoint Online list views now use an Ajax function to handle in-place refresh.

      2. I answered my question about the AJAX refresh by modifying the script to use the inplview.MyRefreshPage(null, url, null); method.

        The only limitation is that I can’t find documentation for this and seem to be limited to a single filter unless I choose to declare a unique change event for each dropdown. Even then it’d be messy. :\

  12. hi Rene,

    Your postings help a lot in my work. I wanted to do multiple values and wildcard filter, however couldn’t figure out how do that with your sample. Any advice?

    Thanks.

  13. hi Rene,

    I saw in core.js, the filterfield function has some coding for “filterop” which could be very useful in filtering. “filterop” like “Eq”, “Neq”, “Geq”, etc. However i couldn’t figure out how to pass “filterop” with the filterfield function.

    Have you see this part of the coding?
    Thank you.

  14. hi everyone, just to share what i manage to find.

    For views (ex: Allitems.aspx), you may use (filterfield and filtervalue) or (filterfields and filtervalues). Cannot combine them. You could also use filterop but it fails in pagination for my case.

    I ended by using caml query to retrieve the data and further filter it in javascript (because camlquery doesn’t support multivalue in lookup). Then the final filterdata is shown in jquery datatable.

    Have a nice day.

  15. Hi Rene,
    Thanks alott its working. But after we select once, the 1st drop down is not having other values for selecting next time, as it is getting populated from current view I guess.. Say if I wanna search more than once. Please let me know how can I achieve it.

    Thank you soo much for the code..

  16. I like the post. Is there a way to display bunch of Check boxes and do the same? If yes, any code or help will be greatly appreciated.

  17. Nice post. Is there a way to change the default name (ALL) in a dropdown filter? Any help will be appreciated.Thanks in advance!

  18. Hello, I used the code on my SharePoint 2013 list but it is not working. i changed the list ID, View ID and column internal Names as per your instruction. Please let me know if this code is compatible with SP 2013. thanks!

    1. Any success on this issue? I tried it as well on SP 2013 and changed the IDs as described.
      Doesn’t matter if I use a content web part or script web part, nothing appears. Always blank.

      Maybe you could help me out, or you have a different filter solution. Would be great.

      Thanks in advance

  19. Hi,

    I have implemented the Code in SharePoint Online and Drop-downs are working fine (showing the data I like) and it filters correctly.
    Now I tried to use this on a Web Part Page where several List View Web Part are displayed but the filtering is not working (Presumably because they all have different ID’s for views). Is there a way to make this work to filter several List View Web Parts (all from the same list)?

  20. Great article! The code worked great for me in SP 2013. I got a dropdowns for all the fields and they were populated by the appropriate data. However, how do you then get this to actually filter your list?

    I don’t see a way to connect it to the list itself – which is located in the web part following the CEWP.

  21. Hi Rene,

    Awesome article!

    i was wondering how can we accomplish like this on SharePoint online specifically.
    i checked for filter.aspx page in it but that doesnot exit in the path stated in above solution.
    i need to have document library filters on a page with 2 levels of filtering.
    Any insights are highly appreciated.

Leave a Reply to Rodrigo Schott Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.