Simple Data Filtering Using jQuery

23 February, 2011

Updated for 2020!

Summary: In this short tutorial, we present a really quick and simple method of data filtering using jQuery - without the need for unnecessary database calls or page refreshes. This is clearly presented between:

  1. HTML and CSS Structure
  2. jQuery

View post demo

Download 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, 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() {
      // store anything commonly called in variables to speed up your code
      const $this = $(this)
      const ourClass = $this.attr('class');
      const $ourHolder = $('#ourHolder');
      // 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;
    });
  });

Checking the active class

In some situations, you may want to have the page start on a different tab. For that we will have to run a check on the page load and make all those not in active be hidden. To select which one you want active on page load, now you can simply just add the active class to that option.

jQuery

$(document).ready(function() {
    // store anything commonly called in variables to speed up your code
    const $active = $('#filterOptions li.active a').attr('class');
    const $ourHolder = $('#ourHolder');
    // hide all elements that aren't in the $active class
    $ourHolder.children('div:not(.' + $active + ')').hide();
    $('#filterOptions li a').click(function() {
      // store anything commonly called in variables to speed up your code
      const $this = $(this)
      const 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;
    });
  });

HTML

...
<ul id="filterOptions">
    <li><a href="#" class="all">All</a></li>
    <li><a href="#" class="prem">Premier League</a></li>
    <li class="active"><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>
...

View post demo

Download 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

Leave a comment

Replying to: - Cancel