views:

124

answers:

3

I have a list of songs, and I want users to be able to filter them by typing into a text field. Here's what I'm doing now:

  $("#filter_song_list").keyup(function() {
    var filter = new RegExp($(this).val(), "i");

    $("ul.song_list a").each(function(){
      if (!$(this).text().match(filter)) {
        $(this).hide();
      } else {
        $(this).show();
      }
    });
  });
  1. Is this the right approach?
  2. Since I'm interpreting the user's input as a regular expression, he can't search for songs with (say) a period in the title without first escaping it ("."). How can I fix this while still maintaining the case-insensitivity of the search?
+2  A: 

the easiest way to do what you ask for (not any better in terms of performance then your solution) is:

change filter to be the user input, not a regex.

change the filtering line to:

if ($(this).text().toLowerCase().indexOf($.trim(filter.toLowerCase())) > -1) {
mkoryak
+2  A: 

Escape your regex prior to executing it:

var pattern = $(this).val().replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1');
var filter = new RegExp(pattern , "i");

However you're just doing a case-insensitive search for a string within a string. You don't need regular expressions for this. @mkoryak's answer is more suitable for you IMO.

I'd have said jQuery's built-in contains psuedo selector was perfect for you, but it is case sensitive.

Crescent Fresh
+2  A: 

First of all, make a cached reference to your elements to speed things up:

var cache = $("ul.song_list a");

Then do a simple string match, using the jQuery filter() function, and hide() matched elements:

cache.filter(function ()
{
    return $(this).text().toLower().indexOf( <value from input> ) < 1;
}).hide();

The final snippet of code:

$(function ()
{
    var cache = $("ul.song_list a");

    $("#filter_song_list").keyup(function ()
    {
        var val = $(this).val();

        cache.filter(function ()
        {
            return $(this).text().toLower().indexOf(val) < 1;
        })
        .hide();
    });
});
roosteronacid