Simple Data Filtering Using jQuery

23 February, 2011

In this short tutorial we'll look at an extremely quick and simple way to filter data without the need for unnecessary database calls or page refreshes.

View post demoDownload post source

Our HTML and CSS Structure

We'll begin with a simple bit of HTML and CSS to get the layout of our page looking presentable. As with all projects I work on I like to level the playing field slightly with a CSS reset snippet, in this case we'll be using the popular example by Eric Meyer.

CSS

/* SIMPLE CSS RESET */
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td {
  margin: 0;
  padding: 0;
  border: 0;
  outline: 0;
  font-size: 100%;
  vertical-align: baseline;
  background: transparent;
}
body { line-height: 1; }
ol, ul { list-style: none; }
blockquote, q { quotes: none; }
blockquote:before, blockquote:after,
q:before, q:after { content: ''; content: none; }
/* remember to define focus styles! */
:focus { outline: 0; }
/* remember to highlight inserts somehow! */
ins { text-decoration: none; }
del { text-decoration: line-through; }
/* tables still need 'cellspacing="0"' in the markup */
table { border-collapse: collapse; border-spacing: 0; }
/*- -*/

With our CSS reset in place we will now have a better starting point to work from as some of the random browser inconsistencies have been ironed out. To control our filtering we need to style up a simple set of buttons, for this we'll be using the ever useful unordered list syntax.

CSS

/*- FILTER OPTIONS -*/
ul#filterOptions {
  width: 802px;
  height: 52px;
  margin: 30px 0;
  overflow: hidden;
}
ul#filterOptions li { height: 52px; margin-right: 2px; float: left; }
ul#filterOptions li a {
  height: 50px;
  padding: 0 20px;
  border: 1px solid #999;
  background: #cfcfcf;
  color: #fff;
  font-weight: bold;
  line-height: 50px;
  text-decoration: none;
  display: block;
}
ul#filterOptions li a:hover { background: #c9c9c9; }
ul#filterOptions li.active a { background: #999; }
/*- -*/

HTML

<ul id="filterOptions">
    <li class="active"><a href="#" class="all">All</a></li>
    <li><a href="#" class="prem">Premier League</a></li>
    <li><a href="#" class="champ">Championship</a></li>
    <li><a href="#" class="league1">League 1</a></li>
    <li><a href="#" class="league2">League 2</a></li>
</ul>

You'll notice from our CSS and HTML markup that we have added a different class to each of our link elements, these will be used later in our jQuery to indicate which items are to be filtered out (or hidden) and which items we are to show.  An active state has also been added to the active li element so it's clear to the user which parameter we are filtering by.

Now we move on to styling our target data. For each target item in this example I have simply used an image, followed by a h3 tag and then surrounded it with a fixed width and height div element (just to keep everything together nicely).

CSS

/*- OUR DATA HOLDER -*/
#ourHolder { width: 800px; height: 850px; overflow: hidden; }
#ourHolder div.item {
  width: 200px;
  height: 200px;
  float: left;
  text-align: center;
}
#ourHolder div.item h3 { margin-top: 10px; font-size: 16px; line-height: 20px; }
/*- -*/

HTML

<div id="ourHolder">
  <div class="item league2">
    <img src="images/accrington-stanley.jpg" alt="Accrington Stanley" />
    <h3>Accrington Stanley</h3>
  </div>
  <div class="item prem">
    <img src="images/arsenal.jpg" alt="Arsenal" />
    <h3>Arsenal</h3>
  </div>
  <div class="item league2">
    <img src="images/burton-albion.jpg" alt="Burton Albion" />
    <h3>Burton Albion</h3>
  </div>
...
</div>

You may have noticed that each of our items has an additional class assigned to it which matches up to the classes assigned to our filter options links, this is how we'll know which items to show when a filtered link is clicked. This will become much clearer as we move on to our next step, adding our jQuery.

Our jQuery

We can now link to the jQuery library. I have chosen to link to Google's CDN hosted copy of jQuery in this example (more detail into the benefit of such aproach can be found here), the following snippet is then placed in between our web pages head tags (<head></head>).

HTML

<script language="javascript" type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>

Next up we need to add a sprinkling of jQuery magic to display the specified items.  As default all items are displayed, when the visitor clicks on one of our filter option links our jQuery fetches the class of the clicked element and assigns it to the ourClass variable. After discovering the ourClass variable we 'deactivate' all of the filter option elements and reassign the active class to the clicked filter option element (this just makes it a little clear to the visitor what they are filtering by). Next up we determine whether the user has clicked the 'all' filter option, if so we show all items with the class of item (in this case all of our items) otherwise we hide all items that do not have our required ourClass value assigned and show all items that do (e.g. if the user clicks on Championship we then hide all items that do not have the championship class, and show all that do). Finally, to stop the page jumping back to the top we return false.

jQuery

$(document).ready(function() {
  $('#filterOptions li a').click(function() {
    // fetch the class of the clicked item
    var ourClass = $(this).attr('class');
    // reset the active class on all the buttons
    $('#filterOptions li').removeClass('active');
    // update the active state on our clicked button
    $(this).parent().addClass('active');
    if(ourClass == 'all') {
      // show all our items
      $('#ourHolder').children('div.item').show();
    }
    else {
      // hide all elements that don't share ourClass
      $('#ourHolder').children('div:not(.' + ourClass + ')').hide();
      // show all elements that do share ourClass
      $('#ourHolder').children('div.' + ourClass).show();
    }
    return false;
  });
});
View post demoDownload post source

It's as simple as that! I have used a slightly more complex implementation of this technique on the tours search results page of a travel website I worked on recently - Bamboo Travel.

Next up we'll look at adding some sexy transitions to manipulate our data set when a filter request is made.

Written by Stewart

Having been with Evoluted for more than 9 years, Stewart has helped to develop successful websites for countless clients. With vast experience related to web development, he’s comfortable putting his skills to use across a wide variety of projects. His ability was highlighted by the key role he played in a site we built for Bamboo Travel, which won best website at the 2013 Wanderlust Travel Awards.

Up next…
10 Must-Have Firefox Add-ons for Web Developers
18 February, 2011

11 Comments

Kerry Moran
16th October 2017 at 9:16am

Shame about the Direby badge. should be a Forest badge in there ;)

Post reply
Stewart Doxey
16th October 2017 at 9:16am

Thanks for the comment Kerry. You're lucky, I nearly added a 'Greatest Team in the Land' tab just for Super Derby

Post reply
emtwo
16th October 2017 at 9:16am

Cracking little tute mate - we've been looking at implementing something similar for our new DM2 portfolio - larvely!

Post reply
Steve
16th October 2017 at 9:16am

Come on Stu! Where's the jQuery Quicksand filter!

Post reply
Alex H
16th October 2017 at 9:16am

Great, easy to follow tutorial, cheers! One question, thou', if I want the first filter to be "Premier League" instead of "all", where do I need to edit? (basically show the PL clubs when the page is visited)
Thanks!

Post reply
Stewart Doxey
16th October 2017 at 9:16am

Hi Alex

Thanks for the kind comments.

To load the Premier League teams rather than All simply force all of the items that do not have the 'prem' class to hide when our page loads.


$('#ourHolder').children('div:not(.prem)').hide();

I hope this helps. You may need to change the active class of the filter options in your HTML too

Thanks

Stewart

Post reply
Alex H
16th October 2017 at 9:16am

Hey
Where exactly does this line of code go?
Thanks again and sorry, I am less than a novice when it comes to JQuery. :)

Post reply
Alex H
16th October 2017 at 9:16am

It works. Thanks a lot, Stewart! :)

Post reply
Alastair Hodgson
16th October 2017 at 9:16am

Cheers guys this has given me a pointer in the right direction.

Might be worth knowing that you can speed up your code with less dom calls by caching the $(this) and $('#ourHolder') selectors to vars.

I'll be using the data attribute rather than adding extra classes but either way works, thanks guys.

Post reply
Stewart Doxey
16th October 2017 at 9:16am

Thanks for the tip Alastair!

Post reply
Marten
16th October 2017 at 9:16am

Is there any way to use the hash tag for this so I can link to a filtered tab?

Post reply
Gene
16th October 2017 at 9:16am

How would you get your team logos to link to there club page for example with the filter still working. How do you make your logos so they become a list rather than 3 across and still get the filter to function

Post reply
Dave
16th October 2017 at 9:16am

Hi Stewart,

is there a possibility to make that as toggle version, without the "Show all" button? I have no clou to do that...

Dave

Post reply
vandana kota
16th October 2017 at 9:16am

i want to submenus in main menu but i could not getting answer. so how can i use jquery filtering

please tell me answer

Post reply
vandana kota
16th October 2017 at 9:16am

i want to add submenus in main menu but i could not getting answer. so how can i use jquery filtering for adding.

please tell me answer

Post reply

Leave a comment

Replying to: - Cancel