Check out "Do you speak JavaScript?" - my latest video course on advanced JavaScript.
Language APIs, Popular Concepts, Design Patterns, Advanced Techniques In the Browser

Filtering data with jQuery

We are working with data every day and there is a part of our applications, which is responsible for presenting the information to the user. Sometimes we need to show a lot of records and then we are using pagination or additional server requests to filter the data. A little JavaScript code could change the things a lot - fast data filtering and better user experience.

The example which I used is located here (download the source code). The script generates fifty random words and shows them in a simple HTML table. The idea is to use the input field at the top to access a specific record. When the user starts typing, the words are automatically filtered. In this case I used jQuery, but generally you can easily use some other library.It is good to put all the filtering login in one namespace/module. I really like the module pattern. That's why I used it here.

var Filtering = (function(){	...})();

I also used a function by James Padolsey which generates the random words:

var createRandomWord = function () {
  var consonants = 'bcdfghjklmnpqrstvwxyz ',
    length = 20,
    vowels = 'aeiou ',
    rand = function (limit) {
      return Math.floor(Math.random() * limit);
    },
    i, word = '',
    consonants = consonants.split(''),
    vowels = vowels.split('');
  for (i = 0; i < length / 2; i++) {
    var randConsonant = consonants[rand(consonants.length)],
      randVowel = vowels[rand(vowels.length)];
    word += (i === 0) ? randConsonant.toUpperCase() : randConsonant;
    word += i * 2 < length - 1 ? randVowel : '';
  }
  return word;
};

Adding the words in a HTML table:

var generateRows = function () {
  var rows = 50;
  for (var i = 0; i < rows; i++) {
    var row = $('<tr class="row"><td>' + (i + 1) + '</td><td class="word">' + createRandomWord() + '</td></tr>');
    $("#rows").append(row);
  }
};

As it is good to present the data immediately after a change in the filter input, I attached a keyup event handler to the field. Once I got the value of the input I used regular expression to decide which rows to hide or show.

var initFilterField = function () {
  filterInput.keyup(function () {
    var filterText = filterInput.val().toLowerCase();
    var rows = $(".row");
    var numOfRows = rows.length;
    for (var i = 0; i < numOfRows; i++) {
      var row = rows.eq(i);
      var word = row.find(".word").html();
      if (word && word.toLowerCase().match(".*" + filterText + ".*")) {
        row.css("display", "table-row");
      } else {
        row.css("display", "none");
      }
    }
  });
  filterInput.focus();
};

The whole example's code looks like that:

$(document).ready(function () {
  var Filtering = (function () {
    var filterInput = $("#filter");
    var createRandomWord = function () {
      var consonants = 'bcdfghjklmnpqrstvwxyz ',
        length = 20,
        vowels = 'aeiou ',
        rand = function (limit) {
          return Math.floor(Math.random() * limit);
        },
        i, word = '',
        consonants = consonants.split(''),
        vowels = vowels.split('');
      for (i = 0; i < length / 2; i++) {
        var randConsonant = consonants[rand(consonants.length)],
          randVowel = vowels[rand(vowels.length)];
        word += (i === 0) ? randConsonant.toUpperCase() : randConsonant;
        word += i * 2 < length - 1 ? randVowel : '';
      }
      return word;
    };
    var generateRows = function () {
      var rows = 50;
      for (var i = 0; i < rows; i++) {
        var row = $('<tr class="row"><td>' + (i + 1) + '</td><td class="word">' + createRandomWord() + '</td></tr>');
        $("#rows").append(row);
      }
    };
    var initFilterField = function () {
      filterInput.keyup(function () {
        var filterText = filterInput.val().toLowerCase();
        var rows = $(".row");
        var numOfRows = rows.length;
        for (var i = 0; i < numOfRows; i++) {
          var row = rows.eq(i);
          var word = row.find(".word").html();
          if (word && word.toLowerCase().match(".*" + filterText + ".*")) {
            row.css("display", "table-row");
          } else {
            row.css("display", "none");
          }
        }
      });
      filterInput.focus();
    };
    return {
      initFilterField: initFilterField,
      generateRows: generateRows
    };
  })();
  Filtering.initFilterField();
  Filtering.generateRows();
});
If you enjoy this post, share it on Twitter, Facebook or LinkedIn.