Filter content by multiple data attributes using jquery

Viewed 38

Using jQuery and Bootstrap I've created a simple filtering functionality. The code is below as well the jsFiddle. But somehow it doesn't work = doesn't show results. Despite the fact there are elements that should meet the criteria. What is wrong then?

$(document).ready(function() {
  $(".filters-1 li").click(function() {
    $(".filters-1 li").removeClass("active");
    $(this).addClass("active");
  });

  $(".filters-2 li").click(function() {
    $(".filters-2 li").removeClass("active");
    $(this).addClass("active");
  });

  $('.filters ul li a').on('click', function() {
    var category_list = [];

    $(this).each(function() {
      var category = $(this).val();
      // console.log(category);
      category_list.push(category);
    });

    if (category_list.length == 0)
      $('.filtered-content').fadeIn();
    else {
      $('.filtered-content').each(function() {
        platform = $(this).attr('data-platform');
        genre = $(this).attr('data-genre');

        if (jQuery.inArray(platform, category_list) > -1 && jQuery.inArray(genre, category_list) > -1)
          $(this).fadeIn('slow');
        else
          $(this).hide();
      });
    }
  });
});
.list-group-item a {
  text-decoration: none;
  color: grey;
}

.active {
  background: pink!important;
  border: red!important;
  -webkit-transition: background-color 200ms linear;
  -ms-transition: background-color 200ms linear;
  transition: background-color 200ms linear;
}

.active a {
  color: #fff;
  font-weight: bold;
}
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.1/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.1/css/bootstrap.min.css">
<div class="container py-3">
  <div class="row filters">
    <div class="col">
      <p>Type filters</p>
      <ul class="list-group list-group-horizontal filters-1" data-filter="platform">
        <li class="list-group-item active">
          <a href="#" data-reset="platform">ALL</a>
        </li>
        <li class="list-group-item">
          <a href="#" data-platform="dvd">DVDs</a>
        </li>
        <li class="list-group-item">
          <a href="#" data-platform="book">Books</a>
        </li>
        <li class="list-group-item">
          <a href="#" data-platform="comicbook">Comicbooks</a>
        </li>
      </ul>
    </div>
    <div class="col">
      <p>Genre filters</p>
      <ul class="list-group list-group-horizontal filters-2" data-filter="genre">
        <li class="list-group-item active"><a href="#" data-reset="genre">ALL</a></li>
        <li class="list-group-item"><a href="#" data-genre="comic">Comic</a></li>
        <li class="list-group-item"><a href="#" data-genre="drama">Drama</a></li>
        <li class="list-group-item"><a href="#" data-genre="comedy">Comedy</a></li>
        <li class="list-group-item"><a href="#" data-genre="poetry">Poetry</a></li>
      </ul>
    </div>
  </div>
  <div class="row filtered-content">
    <div class="col-lg-3 py-2 px-2 object" data-platform="dvd" data-genre="drama">
      <img src="https://picsum.photos/id/237/200" alt="Random image" class="img-fluid" />
    </div>
    <div class="col-lg-3 py-2 px-2 object" data-platform="book" data-genre="comedy">
      <img src="https://picsum.photos/id/267/200" alt="Random image" class="img-fluid" />
    </div>
    <div class="col-lg-3 py-2 px-2 object" data-platform="comicbook" data-genre="comic">
      <img src="https://picsum.photos/id/287/200" alt="Random image" class="img-fluid" />
    </div>
    <div class="col-lg-3 py-2 px-2 object" data-platform="comicbook" data-genre="comic">
      <img src="https://picsum.photos/id/537/200" alt="Random image" class="img-fluid" />
    </div>
    <div class="col-lg-3 py-2 px-2 object" data-platform="book" data-genre="comedy">
      <img src="https://picsum.photos/id/937/200" alt="Random image" class="img-fluid" />
    </div>
    <div class="col-lg-3 py-2 px-2 object" data-platform="dvd" data-genre="poetry">
      <img src="https://picsum.photos/seed/picsum/200" alt="Random image" class="img-fluid" />
    </div>
    <div class="col-lg-3 py-2 px-2 object" data-platform="dvd" data-genre="drama">
      <img src="https://picsum.photos/id/117/200" alt="Random image" class="img-fluid" />
    </div>
  </div>
</div>

JSfiddle is here

I've doubled checked if there are any typos in doing the js code as well checked the HTML code. But have no clue why it doesn't work.

1 Answers

Thank you for such an interesting thread. I have tried to rework your code to be more adapted to my testing project needs.

I would like to extend the JS functionality by adding a possibility of having a multiple data-attribute values. So in practice, now your code works only when data-attribute="singleValue".

What I'm trying to achieve is to make it working in condition when data-attribute="firstValue secondValue". As you will notice, this thing is visible in both filtering lists (in my example it's applicable with PC and PS4/PS5) and the results.

HTML:

<div class="container py-3">
  <div class="row filters">
    <div class="col">
      <p>
        Platform filters
      </p>
      <ul class="list-group list-group-horizontal filters-1" data-filter="platform">
        <li class="list-group-item active">
          <a href="#" data-platform="platform">ALL</a></li>
        <li class="list-group-item">
          <a href="#" data-platform="pc-steam pc-epic pc-gog">PC</a></li>
        <li class="list-group-item">
          <a href="#" data-platform="ps4 ps5">PS4 & PS5</a></li>
        <li class="list-group-item">
          <a href="#" data-platform="xbox">Xbox</a></li>
      </ul>
    </div>

    <div class="col">
      <p>
        Type filters
      </p>
      <ul class="list-group list-group-horizontal filters-2" data-filter="type">
        <li class="list-group-item active"><a href="#" data-type="type">ALL</a></li>
        <li class="list-group-item"><a href="#" data-type="rpg">RPG</a></li>
        <li class="list-group-item"><a href="#" data-type="adventure">Adventure</a></li>
        <li class="list-group-item"><a href="#" data-type="shooter">Shooter</a></li>
        <li class="list-group-item"><a href="#" data-type="simulator">Simulator</a></li>
        <li class="list-group-item"><a href="#" data-type="arcade">Arcade</a></li>
      </ul>
    </div>
  </div>

  <div class="row filtered-content">

    <div class="col-lg-3 py-2 px-2 object" data-platform="pc" data-type="rpg">
    PC | RPG 
    </div>

    <div class="col-lg-3 py-2 px-2 object" data-platform="pc" data-type="adventure">
    PC | adventure
    </div>

    <div class="col-lg-3 py-2 px-2 object" data-platform="xbox" data-type="shooter">
     xbox | shooter 
    </div>

    <div class="col-lg-3 py-2 px-2 object" data-platform="ps4 ps5" data-type="simulator">
     ps4 and ps5 | simulator
    </div>

    <div class="col-lg-3 py-2 px-2 object" data-platform="ps5 xbox" data-type="arcade">
     ps5 and xbox | arcade 
    </div>

    <div class="col-lg-3 py-2 px-2 object" data-platform="pc-steam" data-type="adventure shooter">
    pc-steam | adventure shooter
    </div>

    <div class="col-lg-3 py-2 px-2 object" data-platform="pc-epic pc-gog xbox" data-type="rpg adventure">
     pc-epic and pc-gog and xbox | rpg and adventure 
    </div>




  </div>
</div>

JS:

(function($){ 
    $(".filters-1 li").click(function() {
        $(".filters-1 li").removeClass("active");
        $(this).addClass("active");
        filter();
      });
    
      $(".filters-2 li").click(function() {
        $(".filters-2 li").removeClass("active");
        $(this).addClass("active");
        filter();
      });
      
      function filter() {
        var category_list = [];
    
        $(".filters ul li.active a").each(function() {
          var category = $(this).attr("data-platform") || $(this).attr("data-type");
          
          console.log(category);
          category_list.push(category);
        });
    
        //console.log(category_list)
        
        if (category_list.length == 0)
          $('.filtered-content > .object').fadeIn();
        else {
          $('.filtered-content > .object').each(function() {
            platform = $(this).attr('data-platform');
            type = $(this).attr('data-type');
    
            console.log(platform, type, jQuery.inArray(platform, category_list))
            if ((jQuery.inArray(platform, category_list) != -1 || jQuery.inArray('platform', category_list) != -1) && (jQuery.inArray(type, category_list) != -1 || jQuery.inArray('type', category_list) != -1))
              $(this).fadeIn('slow');
            else
              $(this).hide();
          });
        }
      }
     
})(jQuery);

CSS:

.list-group-item a {
  text-decoration:none;
  color:grey;
}

.active {
  background:black!important;
  border:black!important;
      -webkit-transition: background-color 200ms linear;
    -ms-transition: background-color 200ms linear;
    transition: background-color 200ms linear;
    border-radius:0;
}

.active a {
  color:#fff;
  font-weight:bold;
}

.object {
  background:#acacac;
  color:black;
  padding:1em;
  width:10em;
  height:10em;
  margin:1em;
}

From my knowledge and understanding it is doable. JSFiddle is here

Related