简体   繁体   中英

How to filter bootstrap cards based on search box

I created an app using Laravel 5.8. Please scroll down to see the images before you continue to read, that will help as I explain the issue.

The search box is intended to look for matching text within <H5> tags, an then hide any recipe-card ID divs.

There are two issues:

  1. The divs do not collapse when I search.
  2. Some elements, like the card footer with the hash tags get removed as well. This is not intended.

I'm hoping someone could help me out with the JavaScript I need to use to accomplish this.

  • Search titles (H5 tags)
  • Hide any recipe cards that don't have the search criteria.

Laravel view.blade.php to show my recipe cards

<div class="container">
<div class="row pb-4">
    <div class="col-12">
        <input type="text" name="searchbox" id="searchbox" class="filterinput form-control" placeholder="Search recipe titles and tags...">
    </div>
</div>

<div class="row">
    @foreach ($recipes as $recipe)
    <div class="col-lg-4 pb-4" id="recipe-card">
        <div class="card h-100">
            <a href="/recipes/{{ $recipe->id}}"><img class="card-img-top " src="{{ $recipe->imgurl}}" alt="{{ $recipe->name }}"></a>
            <div class="card-body">
                <h5 class="card-title"><a href="/recipes/{{ $recipe->id}}"> {{ $recipe->name }} </a> {{ $recipe->favourite == 'Yes' ? ' Fav' : '' }} </h5>
                <p class="card-text">
                    <span id="">Time:{{ $recipe->totaltime }}</span>
                </p>
                <p class="card-text">
                    <span id="">Type:{{ $recipe->mealtype }}</span>
                </p>
            </div>
            <div class="card-footer text-muted text-truncate">
                <span class="badge badge-secondary">{{ $recipe->tags }}</span>
            </div>
        </div>
    </div>

    @endforeach

</div>

Here is the JavaScript that I currently use to filter:

<script>
$(document).ready(function() {
    $("#searchbox").on("keyup", function() {
        var value = $(this).val().toLowerCase();
        $("#recipe-card div").filter(function() {
            $(this).toggle($(this).find('h5').text().toLowerCase().indexOf(value) > -1)
        });
    });
});
</script>

The above code produces this:

Before using search

在此处输入图片说明

After searching for recipes with titles (H5 tags) of "bowl"

在此处输入图片说明

Your selector #recipe-card div isn't actually doing what you want it to do. Instead of grabbing the first div inside the card, it's grabbing all divs inside the card.

Additionally, you should avoid re-using the same ID for multiple cards and instead use something like a data-role. IDs are supposed to be unique, so having multiple of the same IDs is generally bad practice.

If you instead used something like data-role="recipe" , you could use this selector:

$('div[data-role="recipe"] div:first)

OR, simply place a data-role on your inner div and simply select that element specifically.

This might not solve all of your issues, but start with this and let me know if anything remains.

The below JS solution was appended by OP and this marked as the right answer:

<script>
$(document).ready(function() {
    $("#searchbox").on("keyup", function() {
        var value = $(this).val().toLowerCase();
        $('div[data-role="recipe"]').filter(function() {
            $(this).toggle($(this).find('h5').text().toLowerCase().indexOf(value) > -1)
        });
    });
});
</script>

The columns shouldn't all have the same id. Also, the jQuery code should hide the column (col-lg-4), instead of the card. There are a lot of different ways this could be handled in jQuery...

$('#searchbox').keyup(function (){
    $('.col-lg-4').removeClass('d-none');
    var filter = $(this).val();
    if (filter && filter.length>0){
        $('.row').find('.col-lg-4 .card-body h5:not(:contains("'+filter+'"))').parentsUntil('.col-lg-4').parent().addClass('d-none');
    }
});

Demo: https://codeply.com/go/IWKdFu4xIJ

Try this:

$('#searchbox').on("keyup", function() {
        $('.card').show();
        var filter = $(this).val(); 
        $('#recipe-card').find(".card-title:not(:contains(" + filter + "))").parent().css('display','none');
    });

If you want the cards to collapse into the right place after filtering, you might consider using bootstrap's "card-columns" or "card-deck" classes for layout.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM