Create a jQuery + SharePoint instant search/filter

We’re going to use jQuery and SharePoint to create an “instant” search/filter of a Content Query WebPart and/or List View. This uses the .find(), :contains(), .val(), .hide(), .show(), :not(), .change(), and .keyup() jQuery codes. You can learn all about those from the jQuery documentation. This is all client-side, and only deals with what shows on the page. I’m not going to deal with any server requests, pagination of lists, etc. That’s for later.

Check out the video tutorial below:

Skip ahead:

You’ll be creating something like this:

Step 1: Load jQuery script in your master page

Because our SharePoint installation is secured, I downloaded the latest jQuery build instead of sourcing it from online. So my script in the master page looks like this:

<script type="text/javascript" src="/Style Library/scripts/jquery.js"></script>

Step 2: Create a page with a CQWP or a list view

Doesn’t matter which one you create, but just have some content we can filter.

Step 3: The Code

I built a lot of this from scratch using the jQuery documentation, but a big shout-out goes to Kilian Valkhof’s article, which helped me organize a lot of what I had. This first part enables case-insensitive searching. It came from Kilian Valkhof, who apparently sourced it from Mike Merrit’s LiveFilter jQuery Plugin, but I’m not sure. Either way, I didn’t write it :). Note:if you use this expression, it means you need to change every instance of contains (small C) to Contains (capital C).

<script type="text/javascript">// <![CDATA[
jQuery.expr[':'].Contains = function(a,i,m){return (a.textContent || a.innerText || "").toUpperCase().indexOf(m[3].toUpperCase())>=0;};

Now we start our function anytime the search input box is changed. Once it’s changed, it sets the value of a variable we have called “txt”.

$(document).ready(function(){
  $("input.search").change(function() {
      var txt = $("input.search").val();

Here we have an IF statement that just checks if there is indeed something in the search box, ELSE everything goes back to normal. If there is something inside the search input box, we are going to do two things. First, we’ll find any row that does NOT contain the string, and we’ll hide that row. Then we’ll find any row that DOES contain that string, and we’ll show that row. Finally, we chain a “keyup” function to the change function so that as we type everything is happening all together.

    if (txt) {
     $("#WebPartWPQ4").find("tr.ms-itmhover:not(:Contains("+txt+"))").hide();
     $("#WebPartWPQ4").find("tr.ms-itmhover:Contains("+txt+")").show();
    } else {
     $("#WebPartWPQ4").find("tr.ms-itmhover").show();
    }
  }).keyup(function(){$(this).change();
 })
})
// ]]></script>

And last but not least, we’ll create a simple search input box with a class of “search”. My styling is attached, feel free to erase and do your own:

<div style="padding: 5px; border: 1px solid #cccccc; width: 60%; margin: 10px auto 0pt; background: none repeat scroll 0% 0% #efefef; display: block;">
<h3 style="text-align: center;">Instant search: <input class="search" style="padding: 10px;" type="text" /></h3>
</div>

Step 4: Final touches

The final step is to put this code inside a Content Editor WebPart (I know, I know, but this is for the sake of this tutorial, definitely not best practice). You’ll have to change the target it’s searching and replace it based on whether or not you’re using a CQWP or a list view. A few tips:

#WebPartWPQ4 is the ID of the webpart on my page, but it might change depending on how many webparts you have, what kind they are, etc.

tr.ms-itmhover seems to be the correct selector for any row in a list view

For searching in a Content Query WebPart, I use this:

find("a:Contains("+txt+")").parents("li.dfwp-item").show();

Note that I used parents instead of parent because the latter only searches one level up. CQWP list items are so intricately embedded deep down that you have to find the text inside the link, and then hide the whole list item. Just play around with it, let me know if you need any help.

About bentedder

Ben Tedder is a front-end web developer. He loves WordPress, SharePoint, and Drupal, along with jQuery, CSS, and good 'ol HTML. +Ben Tedder on Google or follow @bentedder

Comments

I try to respond personally, but things get busy sometimes :)
  1. Will says:

    Wow. This is pretty awesome. I built a custom search function for SharePoint 2007 using JavaScript… what mine does is manipulates the URL string to mimic filtering functions with wildcards. However, the drawback is searching using this method requires reload, which limits the effectiveness of variables and such.

    I’m going to try this next week. Do you know if this works with SharePoint 2007? We haven’t yet upgraded…

    • Will says:

      Oh, and also…
      “tr.ms-itmhover seems to be the correct selector for any row in a list view”

      Do you mean the column ID in this case? Or does this jQuery search look in ANY column that’s visible in a share point list view?

      • bentedder says:

        Hey Will,
        Yeah, jQuery searches every row of the table. When SharePoint creates the table it puts a class of “ms-itemhover” on each row. So this was a quick way of selecting every row that’s visible.

        I imagine this works with SP2007 because it’s really not dependent on any SharePoint features. As long as you can select the classes of rows or cells you want to search, jQuery should be able to handle it.

        • Will says:

          Hi B-

          I am having issues locating the ms-itmhover class… where would this be located in the source of the page? Also- i’m using a list view web part, not a content query webpart… does this matter?

          • bentedder says:

            List View WebPart should be fine. Although, you mentioned you were in SharePoint 2007. Honestly, they might apply some different class to table rows. Really, if you can grab a class of a table row you’ll be good. You just need to give jQuery something to hook onto when it does its search for each row.

          • Cicely B says:

            On the page I’m trying to implement this on, it doesn’t look like each table row has a class. Some say class=”". Have you found a way to get this to work in SharePoint 2007?

          • bentedder says:

            I’ve never tried in SharePoint 2007, but I imagine that even if each row doesn’t have a class, you can slowly move up the DOM tree until you find an element that does, then work your way down with the jquery selector. Something like $(“div.whatever d#whatever table tr”).action…

            Would that work?

  2. Gabe says:

    Thank you so much for posting this! I’ve spent the past day trying to fix the search/filter function on a Sharepoint list of mine using Jquery Mobile.

    Cheers.

  3. Daniel says:

    Hi

    I really like this series of articles. I can’t decide whether link a filter field to a jQuery call to a set of terms in my term store rather than your free txt approach. Thereafter, I guess your approach to display relevant rows via show() and not say filter on a connected web part.

    • Daniel says:

      Hi

      My CQWP has ID of g_3e2800e1_1468_4e17_8027_2cd0d2016c7. I just wondered if this was safe to change it before doing jQuery filtering.

  4. Steve says:

    Hi im a total newbie, Im trying to use this to filter a field on my list , but struggling.. What is the code I need just to filter on 1 field? Regards

    • bentedder says:

      Sorry for the delay. But in order to filter on one field, you would probably just filter on the first cell in each row (meaning the entire first column). Because it’s jQuery, it doesn’t really look at the “field” per se, it just looks at the html. So you’ll have to tell it exactly which divs/tds/tables to look in. Does that make sense? In my example I just used the ‘tr’ because I wanted to search every row and column in the table.

  5. Edward says:

    Excellent blog post!

    I’d love to implement this on larger lists/libraries, without having to load everything in the browser.

    Do you have another post that explains how to accomplish this?

    • bentedder says:

      Thanks!

      Man, I wish. I would love to figure out how to implement this so it doesn’t really load only what’s in the browser. It’s really a glorified “Find” function that your browser already does.

      I do know that you can pull in list items into an autocomplete textbox. That could be an approach? Also, I wonder if an “instant search” like I drew out above would only work in the list sense for a large library, or if you would have to use some form of CQWP? I’m not sure how you would dynamically populate the list itself with SharePoint values in all the right places.

      Would love to see it if you’re able to figure it out though!

  6. check this post it may help you people
    jQuery instant search
    http://workwithphp.info/jquery-instant-search/

  7. Shawn says:

    Nice one.

    The only draw back is when you have a big list:
    If you need paging then it’s partial working, or you have to display everying in one go, and you have a big list in the page/

  8. Ramiya Dixit says:

    if i want to apply the search filter for the list in a particular page.
    Can i add the .js file and .jquery file links in the CEWP?

    I tried its not working.

  9. Brian says:

    Can I implement the jquery list filter using the CEWP? My client will not allow me to use SP Designer, but has requested this functionality. Any help you can provide would be greatly appreciated.

    Thanks,
    Brian

  10. RoM says:

    Hi.
    First, I’d like to thank you for such a wonderful piece of code :)
    I have only one question – this code works like charm, until I remove “Allow individual item checkboxes ” from tabular view in “Modify view” page.
    Any help ?

    Rgds
    R

    • bentedder says:

      Well, the beauty of this code is that because it’s jQuery you tell it which div to search, and which rows to search for. So, in my example I searched for rows like this: tr.ms-itmhover

      But maybe once you take away the checkbox (haven’t done it myself), it changes the class of the row. So use firebug or the inspector on Chrome to find any class in the table rows you can hook onto in order to use the .find() function.

      Hopefully that helps!

      Ben

  11. Patrick says:

    Hello Ben,
    Thanks for the post, very interesting alternative to datatable.net (yours is much shorter and explanations are clearer).
    You write you may later add something that retrieves the rest of the elements from the server, not just the active view…any idea when ? I’m eager to see it !
    Regards,
    Patrick

  12. Jennifer says:

    Hi – first off thank you sooooooo much for this post I’ve been searching for a way to do this for well over a month. We are using SharePoint within our company; but they have restricted some access. One of the restrictions is to not have site owners change the master pages. However, I have used the jquery book marklet which says that jquery is already in use on the page. So I think that covers the first step. I’ve attempted to add your above code using both SPD and editing the HTML on a content editor in the browser.

    When I add the code in SPD it renders it as just “Instant Search” in plain black text with no text box. When I add the code to the “edit HTML” in the browser I get the Instant Search Lable and the input box; but when I type in something it doensn’t actually filter the list.

    I am using a DFWP to display my data; but I’ve also tried it with a basic list and have no luck there either.

    F12 in my IE browser I have found the list webpart ids; and have tried using the 20+ character long version and the “WepPartWPQ1″ version. Again no luck.

    Any suggestions?

  13. steven says:

    Hi
    Love how this works. Any chance you could go into further info for a CQWP

    You mention find(“a:Contains(“+txt+”)”).parents(“li.dfwp-item”).show(); for a CQWP, are you replacing this text instead of $(“#WebPartWPQ4″).find(“tr.msitmhover:Contains(“+txt+”)”).show();

    Thanks in advance

    • bentedder says:

      Sorry for the late reply,
      yes, if you replace

      
       $("#WebPartWPQ4").find("tr.ms-itmhover:not(:Contains("+txt+"))").hide();
           $("#WebPartWPQ4").find("tr.ms-itmhover:Contains("+txt+")").show();
          } else {
           $("#WebPartWPQ4").find("tr.ms-itmhover").show();

      with

      
       $("#WebPartWPQ4").find(“a:not(:Contains(“+txt+”))”).parents(“li.dfwp-item”).hide();
           $("#WebPartWPQ4").find(“a:Contains(“+txt+”)”).parents(“li.dfwp-item”).show();
          } else {
           $("#WebPartWPQ4 li.dfwp-item”).show();
      

      That should work? (Hopefully!)

  14. Rene says:

    Hello, I am a totally newbie here, how can i know the ID of my webpart? what must I do to get it?

    • Steven says:

      Install firebug into firefox, right click on your web part header and inspect element, you should be able to see the webpart ID, be aware as you remove webparts their ID change dynamically

  15. Swaroop says:

    HI,
    It working fantastic, but I need this with pagination because list more items.
    Have you written any blog on this ? Please provide me help to search with pagination

  16. Rimple says:

    If i have a custom view with few conditioning if/equal parts, will this still work as long as the webpart is pointed to that view, (the code will search that view that webpart is pointed to?).

    IE: have a webpart that has 911 /411 announcements for sales, and have a ‘archive’ view that has all current/past announcements, if i create a new web-part page and point the webpart to that “archived” view and add the instant search code, it will search this view specific view, correct?

  17. Jordan says:

    Wow! Really cool and simple code. Before I implement this (time is money) I need to know: If I export the “filtered” list to excel will it still export rows being hidden by the scripts? Anybody who has implemented this may know already. Thanks!

  18. Mauricio says:

    Hello Ben, i love your blog!, it has very interesting articles. Can you help me?. This is my case: My list has 700 items and it is paged each 50 items, your instant search only finds items from the current page.
    I need an instant search to find items in all list and not in one page only.
    Is it possible with this script do something like this?

    Thanks.
    Mauricio.

    • bentedder says:

      Hi Mauricio,
      Actually, yes. I’ve figured out a way to have an instant search filter on a whole list. While it won’t use an out-of-the-box list view, it will accomplish this. However, I’m swamped at the moment so haven’t found time to write about it. BUT, I’ve actually just finished writing a chapter in a SharePoint + jQuery book coming out. It will cover this exact topic. Stay tuned on my blog and I’ll post about it when it comes out. Probably a couple weeks away, but you’ll be able to pre-order soon for way cheaper.

  19. Ben Hudson says:

    When I add it appears like this:
    http://s22.postimg.org/r49jly4kh/Capture.png

    What have i done wrong?

  20. Pierre says:

    The code you are using is not the same as you placed in demo? Is that correct?

Trackbacks

  1. [...] out this post about how to create this. You can create a filter, and then append it to any list across your [...]

  2. [...] I’ve just recorded a screencast version of my post about how to create a jQuery instant filter for SharePoint 2010 lists. Enjoy! (The code featured in the video is pasted [...]

  3. [...] sul post di Ben Tedder è possibile creare una ricerca rapida su una lista, ottenendo qualcosa [...]

  4. [...] This tutorial explains how to create a search scope for a SharePoint 2010 list or library. As a side note, you may be interested to read how to create a jQuery instant filter for a list or CQWP. [...]

Join the discussion!