When dealing with list based data on HTML forms, filtering that data down based on a search text expression is an extremely useful feature. We’re used to search boxes on just about anything these days and HTML forms should be no different. In this post I’ll describe how you can easily filter a list down to just the elements that match text typed into a search box. It’s a pretty simple task and it’s super easy to do, but I get a surprising number of comments from developers I work with who are surprised how easy it is to hook up this sort of behavior, that I thought it’s worth a blog post.

But Angular does that out of the Box, right?

These days it seems everybody is raving about Angular and the rich SPA features it provides. One of the cool features of Angular is the ability to do drop dead simple filters where you can specify a filter expression as part of a looping construct and automatically have that filter applied so that only items that match the filter show. I think Angular has single handedly elevated search filters to first rate, front-row status because it’s so easy.

I love using Angular myself, but Angular is not a generic solution to problems like this. For one thing, using Angular requires you to render the list data with Angular – if you have data that is server rendered or static, then Angular doesn’t work. Not all applications are client side rendered SPAs – not by a long shot, and nor do all applications need to become SPAs.

Long story short, it’s pretty easy to achieve text filtering effects using jQuery (or plain JavaScript for that matter) with just a little bit of work. Let’s take a look at an example.

Why Filter?

Client side filtering is a very useful tool that can make it drastically easier to sift through data displayed in client side lists. In my applications I like to display scrollable lists that contain a reasonably large amount of data, rather than the classic paging style displays which tend to be painful to use. So I often display 50 or so items per ‘page’ and it’s extremely useful to be able to filter this list down.

Here’s an example in my Time Trakker application where I can quickly glance at various common views of my time entries. I can see Recent Entries, Unbilled Entries, Open Entries etc and filter those down by individual customers and so forth. Each of these lists results tends to be a few pages worth of scrollable content.

The following screen shot shows a filtered view of Recent Entries that match the search keyword of CellPage:

As you can see in this animated GIF, the filter is applied as you type, displaying only entries that match the text anywhere inside of the text of each of the list items. This is an immediately useful feature for just about any list display and adds significant value.

A few lines of jQuery

The good news is that this is trivially simple using jQuery.

To get an idea what this looks like, here’s the relevant page layout showing only the search box and the list layout:

The idea here is pretty simple: You capture the keystroke in the search box and capture the search text. Using that search text you first make all items visible and then hide all the items that don’t match.

Since DOM changes are applied after a method finishes execution in JavaScript, the show and hide operations are effectively batched up and so the view changes only to the final list rather than flashing the whole list and then removing items on a slow machine. You get the desired effect of the list showing the items in question.

Case Insensitive Filtering

But there is one problem with the solution above: The jQuery :contains filter is case sensitive, so your search text has to match expressions explicitly which is a bit cumbersome when typing. In the screen capture above I actually cheated – I used a custom filter that provides case insensitive contains behavior.

jQuery makes it really easy to create custom query filters, and so I created one called containsNoCase. Here’s the implementation of this custom filter:

This filter can be added anywhere where page level JavaScript runs – in page script or a seperately loaded .js file. The filter basically extends jQuery with a : expression. Filters get passed a tokenized array that contains the expression. In this case the m[3] contains the search text from inside of the brackets. A filter basically looks at the active element that is passed in and then can return true or false to determine whether the item should be matched. Here I check a regular expression that looks for the search text in the element’s text.

You attach the .searchFilter() plug-in to the text box you are searching and specify a targetSelector that is to be filtered. Optionally you can specify a character count at which the filter kicks in since it’s kind of useless to filter at a single character typically.

Summary

This is s a very easy solution to a cool user interface feature your users will thank you for.

Search filtering is a simple but highly effective user interface feature, and as you’ve seen in this post it’s very simple to create this behavior with just a few lines of jQuery code. While all the cool kids are doing Angular these days, jQuery is still useful in many applications that don’t embrace the ‘everything generated in JavaScript’ paradigm. I hope this jQuery plug-in or just the raw jQuery will be useful to some of you…

If I were to use this I'd probably look into escaping special characters (quotes and other punctuation) for the jQuery selector and the regex. For simple text searches it works a treat but if a search string includes special characters it errors.

Love it. The only minor problem I found is that hitting the x button that appears after you've started typing in the search box didn't trigger a search. And I gave up trying to find a reliable way to check for it being clicked, so got rid of type="search", which stops it appearing in most browsers. For IE, I made the button very small (hiding it may not work as well it seems)

@2bitcoder - for that you would be better off manually writing the logic. As you're hinting in your code you would need two selectors, one to search, and one to show/hide items. What you'd do is find your targets, then walk up to the show/hide selector and show those - hide all the other ones before.

Thanks for the post. Yes, I'm one of those people that still finds jQuery quite useful, and it's interesting that dispite the hype and popularity of the AngularJS, jQuery is indeed still relevant - and both AngularJS and jQuery are being rewritten into new libraries today, in 2015!!!

My question is in your humble opinion, if you had do create a website using only one Javascript JS file, would you use an AngularJS or a jQueryJS (yes, I know you'd rather write your own) AND what version of that JS file would you use?

I'm wondering if u could provide example with dropdown as we can see on that .gif image. First filter by "customers" or wathever and then search by input field inside those "customers". How to merge them together actually ?

@Darek - in this case the other drop downs are filtered on the server - otherwise the list would be too big and would require to have all the data on the client. So any of the other filters cause the server to re-render the page with the retrieved items. In this case it's an ASP.NET app that redraws the entire page, but you could also refresh the data from the data with an AJAX call.

If you need to filter all that data via AJAX in combination I would probably just run the query on the server and feed all the data based on all the filters and you'd get the same effect albeit a bit slower since the data would come from the server.

This is wonderful! Is there anyway that I could include a class on one of the div's, call it say 'searchable' and only have the script search that field, but still display all the other info in the search results.