12/07 2011

jQuery Multiple Filter

Lately I have been much more focused on creating useful things that I have had the motivation to actually write a Blog post on something I made a while ago.

I should point out that this is quite advanced and some undertsanding of the finer points of HTML/CSS/jQuery are necessary in order to understand every detail. I even had to do quite a few modifications to my code highlighting to handle this, so please bare that in mind. It ain't easy kids!

I made this a while back now for a small site where they wanted the interface to do all the work. They wanted to have a portfolio of projects they had worked on but had quite a diverse 'jack of all trades' category list to work with.

The following information was the kind of thing I had to work with from the start of the project (names of categories are made up to avoid conflicting with the real life project).

Customer list

  • Google
  • Yahoo
  • Microsoft
  • Geewiz Inc
  • Apple

Service list

  • Flat Design
  • Working Design
  • Interaction Design
  • Back End Programming
  • Writing
  • Administration

Year list

  • 2011
  • 2010
  • 2009
  • 2008
  • 2007
  • 2006
  • 2005

My brief was to create a 'filterable list' where the user would be able to click on each category item in turn to show and hide all the items under that category. I thought this was also a great idea and something I could use in other projects where I could develop the script and behaviour further.

The basics of the request were pretty straight forward to achieve. They basically wanted to be able to click on items and have items within the selected categories appear or disappear accordingly as part of the interface. Things like the jQuery Quicksand plugin or the Filtering Blocks demo quickly sprang to mind until I realised that they were asking for one extra vital component, the ability to select more than one thing at a time. None of these interfaces have the ability to do this and it requires much more thought and script to achieve.

Where the heck to start?!

My first action as with any slightly daunting project was to panic but this was shortlived. I then went about investigating why the above examples acted in the way they did and what the jQuery was interacting with on the page.

Once I started to understand this, I could start putting together some structure. Thankfully, I was working to a predetermined design (which always helps). This was unlikely to change so I knew I could confidently go to town on the jQuery without fear of repercussions further down the line. There are few things less heartening than to do a weeks work on something only for it to be scrapped the following Monday because someone changed their mind.

Panic over, lets begin

The best place to start with any project, if there is a design in place and it has been approved and double approved, build it! The behaviour can always be applied to the finished design so unquestionably, always build something you and the user of the site would be happy to use without any Javascript enhancements. Below is the HTML I ended up with:


<!doctype html>



<script src="js/libs/modernizr-1.6.min.js">


<script src="//"> <script>!window.jQuery && document.write(unescape('%3Cscript src="js/libs/jquery-1.4.2.js"%3E%3C/script%3E')) <script src="js/plugins.js"> <script src="js/script.js">  

The main elements here are the .filter li's and the #holder li's. In order for the two to talk to each other, they have to have something in common. In this instance it is done with classes. In this instance I have used elements to trigger a click event. This is purely because the design had checkboxes shown and it was better to tie the click event to something that was easy to reference checked or unchecked. This could just as easily be done with other elements, adding and removing classes and checking for the presence of them.

When a click is made on these elements, the jQuery runs through a series of thought out procedures:

  1. If the 'Show all' checkbox has been clicked
    1. If it is and it is checked, make all projects appear
    2. If it is and its not checked, make all projects disappear
  2. If not, is the selection checked
    1. If its checked, we must need to show all the elements with the same class as the value in the checkbox input. We need to show all the elements that match the selection, then make an array out of all the categories matching the selection. Then they are checked in the filter list to show the user what other categories share the project.
    2. If it got as far as this, the only possibility left is that something is being deselected. We need to hide all the elements that match the selection, then make an array out of all the categories matching the selection. Then they are deselected from the filter list.

I told you it was quite in depth and I have done my best to explain things. It may help if I actually show you the script.js file for it:

The jQuery

$(document).ready(function () {

// Removes all filtered elements initially
$("#holder li, .played").hide();
$("#holder.showThis li").show();

// Counts up occurances of classes and sets number of occurrences in filter list
$(".filters li").each(function () {
    var $val = $(this).find('input').val();
    var $valcount = $("#holder ." + $val).length;

// Sets the number in the 'Show all' filter by counting the total amount of entries.
var $itval = $("#holder li").length;
$(".filters li input[value*='all']").parent().find('span').html($itval);

// When clicking an item in the filter list, elements will appear or dissappear
// depending on whether list item is checked or unchecked.

$(".filters li input[type=checkbox]").click(function () {

    $('a.jqTransformChecked').parent().find('input[type=checkbox]').attr('checked', 'checked');

    // next two lines remove the initial page content when a filter is clicked

    var selection = $(this).val();
    if (selection == "all") {
        //show all items
        if ($(this).is(':checked')) {
            $("#holder li img").fadeIn('fast');
            $("#holder li").slideDown('slow');
            $(".filters li input[type=checkbox]").attr('checked', 'checked');
            $(".filters li").addClass('checked');
            $(".filters li label").css({ 'color': '#efefef' });
        } else {
            $("#holder li img").fadeOut('slow');
            $("#holder li").slideUp('slow', function () {
            $(".filters li input[type=checkbox]").removeAttr('checked');
            $(".filters li").removeClass('checked');
            $(".filters li label").css({ 'color': '#40575F' });

    } else {
        if ($(this).is(':checked')) {
            $("#holder li." + selection + " img").fadeIn('slow');
            $("#holder li." + selection).prependTo('#holder').slideDown('fast');

            var stringOfClassNames = '';
            var thisClassString = $("#holder li." + selection).attr('class');
            stringOfClassNames = stringOfClassNames + ' ' + thisClassString;

            var arrayClasses = stringOfClassNames.split(' ');
            $.each(arrayClasses, function () {
                $('.filters input[value=' + this + ']').parent('li').addClass('checked');
                $('.filters input[value=' + this + ']').parent('li').find('label').css({ 'color': '#efefef' });
                $('.filters input[value=' + this + ']').attr('checked', 'checked');

            $(this).parent().find('label').css({ 'color': '#efefef' });

            if ($.browser.webkit) {
                $('#main #holder li').css({ 'position': 'relative' })
        } else {

            $("#holder li." + selection + " img").fadeOut('slow');
            $("#holder li." + selection).slideUp('fast', function () {

                var stringOfClassNames = '';
                var thisClassString = $("#holder li." + selection).attr('class');
                stringOfClassNames = stringOfClassNames + ' ' + thisClassString;

                var arrayClasses = stringOfClassNames.split(' ');

                $.each(arrayClasses, function () {
                    $('.filters input[value=' + this + ']').parent('li').removeClass('checked');
                    $('.filters input[value=' + this + ']').parent().find('a.jqTransformCheckbox').removeClass('jqTransformChecked');
                    $('.filters input[value=' + this + ']').parent('li').find('label').css({ 'color': '#40575F' });
                    $('.filters input[value=' + this + ']').removeAttr('checked');

                if ($('.filters input:checked').length & lt;= 0){
                $("#holder li").slideUp('fast');


$(this).parent('li.' + selection + ' input[type=checkbox]').removeAttr('checked');
$(this).parent().find('label').css({ 'color': '#40575F' });

if ($('#filterIDall').is(':checked')) {
    $('#filterIDall').parent().find('label').css({ 'color': '#40575F' });

In conclusion, this is a great bit of Interface Design that I'm quite proud of. I do know there are a few slight improvements possible and I'm open to any comments but hope someone out there finds it helpful.

30 Responses to jQuery Multiple Filter

  1. seb says:

    wohooo, thats so awesome! just what i needed. blog bookmarked.

  2. luca says:

    This is AWESOMEEEEEE!!!!! very well done.
    I have a question. Do you think is possible to call the list from a DB and achieve the same result and have a lighter script?

    1. Webegg says:

      Hi Luca. I guess you mean with Ajax. I can’t see a reason why you couldn’t adapt the script to work with Ajax calls rather than everything on the page. It’d be great to see it inspire something else.

  3. My brother suggested I might like this web site. He was once entirely right. This put up truly made my day. You can not believe just how so much time I had spent for this information! Thanks!

    1. Legues says:

      Me too… i spent several hours, days, weeks… searching for a script like this one… !!!! ItΒ΄s amazing!! Thanks a lot! Can we use it for free? What license do you use it on this project?

      Thank you!!

      1. Webegg says:

        Excellent, I was frustrated with the lack of something like this, which is why I wrote it. It is free to use as you wish, add to it or modify how you like.

        There is a ‘donate’ link at the bottom of the site so if you feel generous, it wouldn’t go unappreciated.

  4. jFanatic says:

    Awesome tutorial. Is there a way that I can make the “Image placeholder” to be 200×200 so there will be a 3 columns of images?

    1. Webegg says:

      You should be able to change anything via css and html as long as all the classes and stuff jquery needs are still in place. Have a play and let me know.

  5. Kris says:

    Nico one!
    Is it possible to sort entries in there original order when clicking individual ones? Now all is only being sorted in order if you click on “show all”. With the other options, if clicked, it shows google, then yahoo.. (so they are not mixed on entry order)
    Cheers Kris

    1. Webegg says:

      It doesn’t do this at the moment but definitely scope there for further development.

  6. Joseph says:

    This is amazing! Thank you!!!

  7. rai says:

    That’s gr8!!! keep it up πŸ™‚

  8. Klaus says:

    Hi there,
    that is a really cool filter. I was wondering: Is it posible to see all results in the beginning and exclude result through the filter?
    Many Thanks

    1. Webegg says:

      Yes, it should just be a small change in the initial call. Have a play!

  9. Hey! Great script, looking forward to using it. Question: How possible is it to modify the JS to return results that match only specified checks? Currently if you click a value in one section, it will automatically tick all corresponding classes. Doing this would make this script a little more dynamic, but I don’t have the brains to figure it out. Thanks in advance πŸ™‚

  10. Webegg says:

    Thanks for the new comments guys. So glad and flattered this script has become so popular.
    Unfortunately it would seem some of you ‘don’t have the brains’ and I don’t have the time to support all requests for modifications as I’m working doing this sort of stuff full time for a Web Agency.
    Everything you’ve all suggested is very possible so feel free to rip it apart, do what you want with it and see what you can come up with. That’s the only way to learn. Good luck all!

  11. Marie says:

    You are the biggest life saver ever! πŸ˜‰

    1. Webegg says:

      No problem πŸ™‚

  12. SteveD says:

    Very Nice! Exactly what I was looking for – excellent intuitive design. Thanks very much.

    1. Webegg says:

      Not a problem, glad to have helped you out.

  13. Suresh says:

    Very nice tutorial. Many thanks for this. However I have additional requirement on top of this and I am not able to implement my own requirement. My requirement is: if the number of elements is huge (say 500) and if I need to implement pagination to the result of multiple filter, how do I implement? Please help me with a code.

    1. Webegg says:

      Unfortunately I don’t have the time to support requests. Feel free to pull the plugin apart and play with it though. Good luck!

  14. ducky says:

    looks great, but i cant get it to work. im kinda noob at this stuff. can anyone send me the source code in a zip or rar file and send it to


    1. Webegg says:

      Unfortunately I don’t have time to support your request. Have you looked at the demo ( That works and you can copy everything down to your local machine to play with it.

  15. Dracotonis says:

    First off I love your code its perfect for my needs except for one feature.
    Im planning to create a site with alot of checkboxes and results with multiple tags, is there anyway to stop the code from ticking multiple checkboxes when I only select one?
    I would like the only checkboxes to be ticked to be ones the user selects.
    Thx again for ur code its saving my project!

    1. Webegg says:

      There’s always a way. Happy developing.

  16. PEdi says:

    hi ! Awesome script !
    I need some help with editing the script.
    I do count all elements after filtering.

    for example: Found: xxx elements

    1. Webegg says:

      If you hire a developer I’m sure they can help you.

  17. kimo says:

    Thank You.thats so awesome just what i needed

  18. Naomi says:

    Hey! Brilliant script!
    I noticed that when you click ‘2006’ as your first filter selection, the ‘geewiz’ , ‘administration’ & ‘writing’ categories don’t autoselect. The holder shows all the related projects, but the .filter checkboxes only highlight the categories related to the first list item with ‘2006’. ”

    Just wondering if you did this on purpose for any reason? Thank you!

Leave a Reply

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

This article is in the jquery category. Here are some other related articles also in this category.