最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Jquery - text filter to hide divs - Stack Overflow

programmeradmin2浏览0评论

I'm trying to use jquery to to create a live filter to hide divs on realtime text input. So far I have the following:

<input type="text" class="form-control" id="filter" name="filter" class="filter">
<div class="media">
    <div class="media-body>
        <h4>Apples</h4>
        ...
    </div>
</div>
<div class="media">
    <div class="media-body>
        <h4>Oranges</h4>
        ...
    </div>
</div>

<script>
    $('#filter').keyup(function () { 
        var filter = $("#filter").val();
        $('.media').each(function(i, obj) {
            if ($('this > .media-body > h4:contains(filter)').length === 0) {
                $(this).css("display","none");
            }
        });
    });
</script>

I want this to work so that as soon as someone types an 'o' the apples div is hidden but currently it hides all the divs as soon as anything is typed.

Also how can I make it case insensitive?

I'm trying to use jquery to to create a live filter to hide divs on realtime text input. So far I have the following:

<input type="text" class="form-control" id="filter" name="filter" class="filter">
<div class="media">
    <div class="media-body>
        <h4>Apples</h4>
        ...
    </div>
</div>
<div class="media">
    <div class="media-body>
        <h4>Oranges</h4>
        ...
    </div>
</div>

<script>
    $('#filter').keyup(function () { 
        var filter = $("#filter").val();
        $('.media').each(function(i, obj) {
            if ($('this > .media-body > h4:contains(filter)').length === 0) {
                $(this).css("display","none");
            }
        });
    });
</script>

I want this to work so that as soon as someone types an 'o' the apples div is hidden but currently it hides all the divs as soon as anything is typed.

Also how can I make it case insensitive?

Share Improve this question edited Apr 1, 2014 at 12:04 Evgeniy 2,9213 gold badges22 silver badges35 bronze badges asked Apr 1, 2014 at 11:58 RayZorRayZor 6651 gold badge13 silver badges25 bronze badges 3
  • see jsfiddle.net/arunpjohny/LXEDE/1 – Arun P Johny Commented Apr 1, 2014 at 12:05
  • I suppose items should be shown again when someone clears the filter? :) – Ja͢ck Commented Apr 1, 2014 at 12:18
  • Wow! I pop out for lunch and come back to a flurry of answers! Thank-you every one! =D – RayZor Commented Apr 1, 2014 at 13:09
Add a comment  | 

10 Answers 10

Reset to default 8

Big thanks to everyone who responded to this question - in the end I went with the solution Fabrizio Calderan provided, but have made a few modifications to it that allow for the text filter to search a string for words in any order and to redisplay previously hidden divs if the user deletes what they've typed, I thought I would share this modified solution with you:

    $('#filter').keyup(function () {
        var filter_array = new Array();
        var filter = this.value.toLowerCase();  // no need to call jQuery here

        filter_array = filter.split(' '); // split the user input at the spaces

        var arrayLength = filter_array.length; // Get the length of the filter array

        $('.media').each(function() {
            /* cache a reference to the current .media (you're using it twice) */
            var _this = $(this);
            var title = _this.find('h4').text().toLowerCase();

            /* 
                title and filter are normalized in lowerCase letters
                for a case insensitive search
             */

            var hidden = 0; // Set a flag to see if a div was hidden

            // Loop through all the words in the array and hide the div if found
            for (var i = 0; i < arrayLength; i++) {
                 if (title.indexOf(filter_array[i]) < 0) {
                    _this.hide();
                    hidden = 1;
                }
            }
            // If the flag hasn't been tripped show the div
            if (hidden == 0)  {
               _this.show();
            }
        });
    });

You need to properly interpolate the selector string with the actual value of filter.
You also have a typo in $('this > ....

Try this code (with some improvements)

$('#filter').keyup(function () {

    var filter = this.value.toLowerCase();  // no need to call jQuery here

    $('.media').each(function() {
        /* cache a reference to the current .media (you're using it twice) */
        var _this = $(this);
        var title = _this.find('h4').text().toLowerCase();

        /* 
            title and filter are normalized in lowerCase letters
            for a case insensitive search
         */
        if (title.indexOf(filter) < 0) {
            _this.hide();
        }
    });
});

Try

if (!RegExp.escape) {
    RegExp.escape = function (value) {
        return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&")
    };
}

var $medias = $('.media'),
    $h4s = $medias.find('> .media-body > h4');
$('#filter').keyup(function () {
    var filter = this.value,
        regex;
    if (filter) {
        regex = new RegExp(RegExp.escape(this.value), 'i')
        var $found = $h4s.filter(function () {
            return regex.test($(this).text())
        }).closest('.media').show();
        $medias.not($found).hide()
    } else {
        $medias.show();
    }
});

Demo: Fiddle

Modified the answer to this


    var filter = this.value.toLowerCase();  // no need to call jQuery here

    $('.device').each(function() {
        /* cache a reference to the current .device (you're using it twice) */
        var _this = $(this);
        var title = _this.find('h3').text().toLowerCase();

        /* 
            title and filter are normalized in lowerCase letters
            for a case insensitive search
         */
        if (title.indexOf(filter) < 0) {
            _this.hide();
        }
        else if(filter == ""){
            _this.show();
        }
        else{
            _this.show();
        }
    });
});

Try this -

if ($('.media-body > h4:contains('+filter+')',this).length  === 0) {
        $(this).css("display","none");
}

This is wrong:

if ($('this > .media-body > h4:contains(filter)').length === 0) {

You should do like this:

if ($(this).find(' > .media-body > h4:contains('+filter+')').length === 0) {

Or like this:

if ($(' > .media-body > h4:contains('+filter+')', this).length === 0) {

You need to use .children() as well as concatenate your filter variable using +, so use:

if ($(this).children('.media-body > h4:contains(' + filter +')').length === 0) {
    $(this).css("display","none");
}

instead of:

if ($('this > .media-body > h4:contains(filter)').length === 0) {
    $(this).css("display","none");
}

example here

$('#filter').keyup(function () { 
    var filter = $("#filter").val();
    $('.media').each(function() {
        $(this).find("h4:not(:contains('" + filter + "'))").hide();
        $(this).find("h4:contains('" + filter + "')").show();
    });
});

You can simplify this code to:

$('#filter').keyup(function () {  

    // create a pattern to match against, in this one
    // we're only matching words which start with the 
    // value in #filter, case-insensitive

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

    // hide all h4's within div.media, then filter
    $('div.media h4').hide().filter(function() {

        // only return h4's which match our pattern
        return !!$(this).text().match(pattern);

    }).show(); // show h4's which matched the pattern

});

Here's a fiddle

Credit to this answer for the expression to escape special characters in the value.

You can use this code.

 $('#filter').keyup(function () {
            var filter = this.value.toLowerCase();
            $('.media').each(function () {
                var _this = $(this);
                var title = _this.find('h1').text().toLowerCase();

                if (title.indexOf(filter) < 0) {
                    _this.hide();
                }
                if (title.indexOf(filter) == 0) {
                    _this.show();
                }
            });
        });
发布评论

评论列表(0)

  1. 暂无评论