Blitz
Blitz

Reputation: 59

jQuery: how to show only specific elements of the DOM in a text search

I'm working on a text search functionality and would like to only display particular elements of the DOM: When a user types in a search term only the divs with class='accordion' and their children, grandchildren etc. should be shown that include the search term in their grand-child's text. I tried the following and the result was, that no elements were shown whenever a search term was entered.

 $('#search-criteria').on('keyup', function() {
    var g = $(this).val().toLowerCase();
    $('.panel-info').each(function() {
        var s = $(this).text().toLowerCase();

       if (s.indexOf(g) !== -1) {

        $(this).parentsUntil('.accordion').show();
        $(this).parentsUntil('.accordion').addClass('sh');
       }
       else if ($(this).hasClass('sh') === false && (s.indexOf(g) === -1)) 
       {
        $(this).parentsUntil('.accordion').hide();
       }

    });
});

Before I had also tried this instead of the if/else, which seems much more elegant, but didn't work either:

$(this).parentsUntil('.accordion')[ s.indexOf(g) !== -1 ? 'show' : 'hide' ]();  

Please find the fiddle here jsfiddle.net/2vvwZ

Upvotes: 0

Views: 991

Answers (1)

fiskeben
fiskeben

Reputation: 3467

Use jQuery's [:contains selector][1] to select nodes that match your search criteria and show them, then hide the rest.

Given that you want to search through elements with the class .accordion and show or hide them, you do this:

$('#search-criteria').on('change', function() {
  var val = $(this).val();
  $('.accordion').find(':contains(' + val + ')').show();
  $('.accordion').find(':not(:contains(' + val + '))').hide();
}).on('keyup', function() {
  $(this).change();
});

This snippet basically finds all elements with the class accordion, finds those of their children that contains the input value and show()s them. Afterwards it does the same but finds elements that do not contains the input and hide()s them.

Unfortunately, the selector that comes with jQuery is case sensitive. If you want your code to not be case sensitive, you can create your own selector like this:

$.expr[":"].icontains = $.expr.createPseudo(function(arg) {
  return function (elem) {
    return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
  };
});

Here I've created a selector called icontains that converts the strings to upper case before comparing them. Remember to change the two contains in the example above if you want to use icontains.

Upvotes: 1

Related Questions