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

enter image description here

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

enter image description here

Answer

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>

Leave a Reply

Your email address will not be published. Required fields are marked *