javascripthtmljquerycssjquery-isotope

Isotope.js not filtering correctly when using multiple checkboxes


I have a simple filter which contains two checkboxes, one for cake another for cupcake.

A user can check either option, or select both to show all results. However, even though my filters array contains the correct values, nothing shows.

Even when filtering by one option, it doesn't showcase the correct results.

See demo here:

(function($) {

  var $grid = $('.shop__grid'),
    $checkboxes = $('.isotope-trigger');

  $grid.isotope({
    itemSelector: '.productCard',
    layoutMode: 'fitRows'
  });

  $grid.imagesLoaded().progress(function() {
    $grid.isotope('layout');
  });


  $checkboxes.change(function() {
    var filters = [];
    // get checked checkboxes values
    $checkboxes.filter(':checked').each(function() {
      filters.push(this.value);
    });
    // filters = filters.join(', ');
    $grid.isotope({
      filter: filters
    });
    console.log(filters);
  });


})(jQuery);
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://unpkg.com/isotope-layout@3/dist/isotope.pkgd.min.js"></script>
<script src="https://unpkg.com/imagesloaded@5/imagesloaded.pkgd.min.js"></script>

<div class="shop">
  <div class="container">
    <div class="row">

      <!-- filter -->
      <div class="col-12 col-md-3">
        <div class="shopFilter">
          <div class="shopFilter__category">
            <span class="shopFilter__category-label d-block">Type</span>
            <div class="shopFilter__category-options">
              <div class="filterOption">
                <input class="filterOption__input isotope-trigger" type="checkbox" data-filter=".cake" name="item-cake" value="Cake" id="cake">
                <label class="filterOption__label" for="item-cake">Cake</label>
              </div>
              <div class="filterOption">
                <input class="filterOption__input isotope-trigger" type="checkbox" data-filter=".cupcake" name="item-cupcake" value="Cupcake" id="cupcake">
                <label class="filterOption__label" for="item-cupcake">Cupcake</label>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- listing -->
      <div class="col-12 col-md-7">
        <div class="shop__grid">
          <div class="productCard text-center cake">Cake</div>
          <div class="productCard text-center cake">Cake</div>
          <div class="productCard text-center cupcake">Cupcake</div>
          <div class="productCard text-center cake">Cake</div>
        </div>
      </div>
      <!---->

    </div>
  </div>
</div>


Solution

  • You missed 2 things:

    1. you transferred the values instead of the id's
    2. the ids of the checkboxes serve as classnames for $grid, so they have to be prepended with a dot.

    My changes can be reduced to these lines, the rest is there to demonstrate that it's running:

    $checkboxes.filter(':checked').each(function() {
      filters.push(this.id);
    });
    
    var filtersString = filters.length > 0 ? '.' + filters.join(', .') : '';
    
    // console.log(filtersString);
    
    $grid.isotope({
      filter: filtersString
    });
    

    Demonstration:

    (function($) {
    
      var $grid = $('.shop__grid'),
        $checkboxes = $('.isotope-trigger');
    
      $grid.isotope({
        itemSelector: '.productCard',
        layoutMode: 'fitRows'
      });
    
      $grid.imagesLoaded().progress(function() {
        $grid.isotope('layout');
      });
    
    
      $checkboxes.change(function() {
    var filters = [];
    // get checked checkboxes values
    $checkboxes.filter(':checked').each(function() {
      filters.push(this.id);
    });
    
    var filtersString = filters.length > 0 ? '.' + filters.join(', .') : '';
    
    console.log(filtersString);
    
    $grid.isotope({
      filter: filtersString
    });
    
    // console.log(filters);
      });
    
    
    })(jQuery);
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <script src="https://unpkg.com/isotope-layout@3/dist/isotope.pkgd.min.js"></script>
    <script src="https://unpkg.com/imagesloaded@5/imagesloaded.pkgd.min.js"></script>
    
    <div class="shop">
      <div class="container">
        <div class="row">
    
          <!-- filter -->
          <div class="col-12 col-md-3">
            <div class="shopFilter">
              <div class="shopFilter__category">
                <span class="shopFilter__category-label d-block">Type</span>
                <div class="shopFilter__category-options">
                  <div class="filterOption">
                    <input class="filterOption__input isotope-trigger" type="checkbox" data-filter=".cake" name="item-cake" value="Cake" id="cake">
                    <label class="filterOption__label" for="item-cake">Cake</label>
                  </div>
                  <div class="filterOption">
                    <input class="filterOption__input isotope-trigger" type="checkbox" data-filter=".cupcake" name="item-cupcake" value="Cupcake" id="cupcake">
                    <label class="filterOption__label" for="item-cupcake">Cupcake</label>
                  </div>
                </div>
              </div>
            </div>
          </div>
    
          <!-- listing -->
          <div class="col-12 col-md-7">
            <div class="shop__grid">
              <div class="productCard text-center cake">Cake</div>
              <div class="productCard text-center cake">Cake</div>
              <div class="productCard text-center cupcake">Cupcake</div>
              <div class="productCard text-center cake">Cake</div>
            </div>
          </div>
          <!---->
    
        </div>
      </div>
    </div>

    Here I found a documentation about the filter: https://isotope.metafizzy.co/filtering.html