2

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?

3 Answers 3

2

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) {
Sign up to request clarification or add additional context in comments.

Comments

2

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.

Comments

2

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();
    });
});

1 Comment

it think you need to user .toLowerCase() instead. Also, tried ( jsfiddle.net/aegq4/10 ) and i get all items hidden and never shown again, even if the input matches the text. Are you sure it should work? am i doing something wrong?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.