Jesper O. Christensen

Cloud Architect @ Brandheroes

How to filter data with multiple parameters using jQuery

2016-02-14 jesper o. christensenJavaScript...

unsplash.com

In this tutorial I’ll show you how to filter a data set using different parameters. We’ll filter on a search box aswell as a day. We’ll show you how to easily add additional filter parameters. So let’s get started!

unsplash.com

This is our starting point. It’s a scheme showing when different people are at the office. So if we look at the first entry. We’ll see that John Johnson is at the office on mondays and thursdays. We wanna be able to search for a name and select some days at the same time, and only get too see who fit our search terms.

The HTML (our data)

Below is a snippet of the basic HTML that we’re going to be filtering on. Every day has an id ranging from 1 to 5. These ids match the ones every person has under the specific day. So lets look at monday for John Johnson. He has an active monday field with a data-schedule attribute with value 1. That means that John is at work every monday. This is just to get the basic idea of what we are working on with our jQuery filter function. I’ve stripped all the styling from this snippet to only show what parts the filter will be working on.

<table>
    <thead>
        <tr id="days">
            <td></td>
            <td>
                <h6><b class="pressable-day" id="1">Monday</b></h6>
            </td>
            <td>
                <h6><b class="pressable-day" id="2">Tuesday</b></h6>
            </td>
            <td>
                <h6><b class="pressable-day" id="3">Wednesday</b></h6>
            </td>
            <td>
                <h6><b class="pressable-day" id="4">Thursday</b></h6>
            </td>
            <td>
                <h6><b class="pressable-day" id="5">Friday</b></h6>
            </td>
        </tr>
    </thead>
 
    <tbody class="searchable">
        <tr class="row-border">
            <td>
                <h4>John Johnson</h4>
            </td>
            <td>
                <span class="active" data-schedule="1"></span>
            </td>
            <td>
                <span data-schedule="2"></span>
            </td>
            <td>
                <span data-schedule="3"></span>
            </td>
            <td>
                <span data-schedule="4"></span>
            </td>
            <td>
                <span data-schedule="5"></span>
            </td>
        </tr>
        ...
    </tbody>
</table>

Searchbox filter

We’ll start with looking at how we get the search box working.

$(function () {
    $('#searchfield').keyup(filter);
 
    function filter() {
        var rex = new RegExp($('#searchfield').val(), 'i');
        var rows = $('.searchable tr');
 
        rows.hide();
        rows.filter(function () {
            return rex.test($(this).text());
        }).show();
    }
});

Above we hook up a keyup event handler to an element with the id searchfield, which is our search input field. The filter function basically just hides all table rows which has a parent element with the searchable class and call the jQuery .filter() function on each row.

This jQuery filter function evaluates the supplied function on each row. If your function returns true, it passes the filter and the element is shown. If the function returns false, the element remains hidden.

So we write a function to test if the element fulfill our requirement. We create a Regex from the filter input box using the i modifier. This sets case-insensitive matching, so if you write “peter” it will not filter away “Peter”. Next we run a regex test on the elements text. If the test is passed, it returns true. If not it returns false.

Filtering on days

So fare so good. Now we wanna be able to click on a day and indicate that we have selected a day or more to filter on. We add an active class to a pressed day to get a different appearance. The class could look like this.

.pressable-day.active {
   background-color: forestgreen;
   color: white;
   border-radius: 50px;
}

This basically just sets a green rounded corner box around the day and change the font color to white.

Now let’s apply the class when clicking on the specific day.

$('.pressable-day').click(function () {
    $(this).toggleClass('active');
    filter();
});

Pretty simple. We add a click event handler to all elements with a pressable-day class and toggle the class active on and off. Now that we have created another parameter to filter on, let’s make a function that uses it.

function filterOnDays(selector) {
    var tester = true;
    var all = $('#days .pressable-day.active');
 
    for (var i = 0; i < all.length; i++) {
        var day = $(selector).find('[data-schedule="' + all[i].id + '"]');
 
        if (!day.hasClass('active')) {
            tester = false;
        }
    }
    return tester;
}

So the first thing to notice is this line 3. Here we find all the days we wanna filter on. So if I’ve selected monday and thursday. all will be an array with those two elements.

We then iterate through the array. For every active day in the array we:

  1. Find the day with the data-schedule == day.id

  2. If the day doesn’t have the class active, we set the tester boolean to false.

This means that if one of the selected days isn’t active for the given person, that person will be filtered away. Another approach could been to set tester to false in the beginning and then set it too true if the person is at work on at least one of the selected days. But we choose the first approach to make the filter remove everyone that doesn’t match our the expectations 100%.

So we just made a function that takes an element and tests if the element lives up to some expectations. If it does we return true and if not we return false. As simple as that.