Super-easy filterable lists/tables with jQuery

I’m working on a page that will potentially have a very long table of information, and I wanted a way to filter the table to only show rows that contain a specific text string.

Fortunately, with jQuery that’s super easy. It took me about 3 minutes to build and test. Let’s take a look!

First, you want to create your table. Give it a class you’ll be able to use to tell jQuery this is what you’re filtering. Something like this:

<table class="filterable">
  <tbody>
    <tr>…</tr>
  </tbody>
</table>

Now let’s put in a little form field for entering the filter string. This is old news now, but HTML5 lets us use one-off form inputs for on-page actions without having to wrap them in a <form> tag, so let’s just stick this into our HTML above the table:

<div>
  Filter: <input type="text" id="list_filter" />
</div>

Now here’s where it gets fun. In jQuery, we’re going to watch for the keyup event on the input. If the input has a value (i.e. is not empty), we’ll do our filtering. If it is empty, we’ll just reveal all of the rows in the table again.

We probably want the filter to be case-insensitive, so we’ll make both the input string and our check of each row’s text all-lowercase with .toLowerCase().

Next we’ll step through each row of the table, check if our filter string is not present (.indexOf() == -1) in the .text() inside that row. If it’s not there, we’ll hide the row. Otherwise, we’ll show it. (This last bit is important because we want to start revealing previously hidden rows if the user deletes characters from the filter input.)

Yeah… that’s pretty much it. And since it’s all jQuery interacting with elements already present on the page, it’s lightning-fast.

<script>
  jQuery(function() {
    jQuery('input#list_filter').on('keyup', function() {
      if (jQuery(this).val() != '') {
        var filter_val = jQuery(this).val().toLowerCase();
        jQuery('table.filterable tbody tr').each(function() {
          if (jQuery(this).text().toLowerCase().indexOf(filter_val) == -1) {
            jQuery(this).hide();
          }
          else {
            jQuery(this).show();
          }
        });
      }
      else {
        jQuery('table.filterable tbody tr').show();
      }
    });
  });
</script>

A few other notes:

  1. The way this is built, you could conceivably have multiple filterable tables on one page, but only one filter input. The filter would automatically get applied to all filterable tables on the same page. There are various ways of changing this by modifying your selector.
  2. I am deliberately only checking for <tr> tags inside the <tbody> tag to allow for a header row inside a <thead> tag that would not be subject to the filter. If you have a header row inside your <tbody> tag, it’s going to get filtered too! Probably not desirable.
  3. You could play around with making the whole thing smoother with .slideUp() and .slideDown() instead of .hide() and .show() but that UX can get messy in a hurry.

Finally, more than 25 years later…

I think it was probably around 1983 that I got my first Rubik’s Cube. Wasn’t that the year they really hit big in the U.S.? Anyway, I just never had the patience or the logical foresight to be able to solve it. Never. Not once. Oh, sure, I was able to solve one side. I think once I might have solved two. But I could never envision how to put it all together. It’s the same reason I suck at chess.

Before long, I knew that it wasn’t possible to just solve the whole thing one side at a time. And, unnervingly, when you were closest to having the whole puzzle solved, just a couple of turns away from a complete solution, there would be a sequence of moves where none of the sides were solved. That was just too much for my 9-year-old brain.

Eventually I just gave up on ever solving my Rubik’s Cube. It didn’t help that I had also learned that you could turn one side to a 45-degree angle, pop out the middle edge piece, and easily disassemble the entire thing, reassembling it in perfect order. And so it was, that my speedy solution to the Rubik’s Cube, sadly, always involved a screwdriver.

This year my parents gave me a Rubik’s Cube for Christmas. (It’s OK… that’s not the only thing they got me for Christmas. I also got this, which rocks.) Today I decided, by gum, I’m gonna solve it! Of course, not on my own. These days Rubik’s Cubes ship with a little pamphlet revealing the magical seven-step solution. (No, not seven moves, more like a hundred or so. But seven basic logical steps.)

I was doing great… halfway through the seventh and final step, when… well, the whole thing fell apart. Not literally. They’re made pretty well — and it’s no longer possible to pop out the edge piece with a screwdriver. (Don’t ask me how I know that it’s no longer possible. I just have my ways.)

I realized after a moment of fretting that I had misinterpreted part of Step 7. I was left with this:

Almost had it...

One good side, and five sides of crap. (Much like Yessongs. Sorry… had to say it. Not too often you can work in a joke about a 36-year-old prog rock triple live album. By Yes.)

After dinner I was sufficiently distanced from my devastating defeat that I was willing to have another go, and this time… success!

Success!

Scene of the crime

Here are a couple of photos I took of my office/studio for the RPM Challenge, and I figured I might as well post them here too, so you can get a glimpse into the world where the magic happens. Well, where… something happens.

Reading presidential body language

Ex-, current and soon-to-be Presidents

As just about everyone who pays attention probably knows by now, the Bush White House today convened a Presidents Club luncheon, consisting of the 3 surviving ex-presidents, the White House’s current occupant, and Barack Obama, who in less than three weeks will be setting up shop in the Oval Office.

I find the photo above to be fascinating as a study in body language. George W. Bush stands front and center, but seems nervously out-of-place, with his awkward smirk and cocked left foot. Barack Obama is both leaning and looking away from the current president, speaking with his father. There is a strange stiffness in his comportment, as if simply standing in close proximity to “Dubya” is creating negative energy. GHWB stands at the end, hand outstretched in mid-sentence, in a position that suggests either patting a child on the head or pushing them away.

Bill Clinton stands grinning wistfully, hands behind his back, contemplating, perhaps, his own personal history (and I mean personal) in the very room in which the five men now stand.

And Jimmy Carter knows exactly what’s on Bill’s mind.

I’ll leave you to ponder the merits, or lack thereof, of my decision to omit an apostrophe in the phrase “Presidents Club.”