Home > Software engineering >  Filter divs using multiple dropdowns with jQuery
Filter divs using multiple dropdowns with jQuery

Time:11-19

I'm currently trying to implement a simple filter using jQuery, I was able to implement it with one single dropdown/select but when adding another one things get messy.

$("select").change(function () {
  let $elementsToFilter = $("#filterable-elements div");

  let $category = $("#category-filter").val();
  let $type = $("#type-filter").val();

  $elementsToFilter.hide();

  $elementsToFilter.filter(function (index, element) {
    let $el = $(element);

    if ($category === "all" && $type == "all") {
      $elementsToFilter.show();
    } else if ($el.data("category") === $category && $el.data("type") === $type) {
      $el.show();
    }
  });
});

This is my current code, the problem starts when I try to use the dropdowns independently, they only work when combined. So if want to only show divs with data-category = 1, it doesn't work unless I also select a type.

Thanks in advance for any ideas.

EDIT: JSFiddle with the problem

CodePudding user response:

Here you go .. You can add some || OR conditions to let the code run even the value is equal to all

$("select").change(function () {
  let $elementsToFilter = $("#filterable-elements div");

  let $category = $("#category-filter").val();
  let $type = $("#type-filter").val();

  $elementsToFilter.hide().filter(function (index, element) {
    let $el = $(element);
    return ($el.data("category") === $category || $category == "all") && ($el.data("type") === $type || $type == "all");
  }).show();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <div>
    <label for="category-filter">Filter by Category</label>
    <select id="category-filter" name="category-filter">
      <option selected value="all">All categories</option>
      <option value="cat 1">Category 1</option>
      <option value="cat 2">Category 2</option>
      <option value="cat 3">Category 3</option>
    </select>
  </div>

  <div>
    <label for="type-filter">Filter by Type</label>
    <select id="type-filter" name="type-filter">
      <option selected value="all">All types</option>
      <option value="type 2">Type 2</option>
      <option value="type 3">Type 3</option>
      <option value="type 5">Type 5</option>
    </select>
  </div>
</div>

<div id="filterable-elements">
  <div data-category="cat 1" data-type="type 3">EL 2</div>
  <div data-category="cat 2" data-type="type 5">EL 3</div>
  <div data-category="cat 3" data-type="type 5">EL 4</div>
  <div data-category="cat 1" data-type="type 2">EL 5</div>
</div>

You need to read about the difference between .each() , .filter()

ِ Also if you need to detect if there're no data matched to do some action you can see the next example

$("select").change(function () {
  let $elementsToFilter = $("#filterable-elements div");

  let $category = $("#category-filter").val();
  let $type = $("#type-filter").val();
  let divs = $elementsToFilter.hide().filter(function (index, element) {
                let $el = $(element);
                return ($el.data("category") === $category || $category == "all") && ($el.data("type") === $type || $type == "all");
              });
              
              
  if(divs.length < 1){  // if no data matched 
    console.log("NO Data Matched");
    // or show all of them
    // $elementsToFilter.show();
  }else{
    divs.show(); // show the matched elements
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <div>
    <label for="category-filter">Filter by Category</label>
    <select id="category-filter" name="category-filter">
      <option selected value="all">All categories</option>
      <option value="cat 1">Category 1</option>
      <option value="cat 2">Category 2</option>
      <option value="cat 3">Category 3</option>
    </select>
  </div>

  <div>
    <label for="type-filter">Filter by Type</label>
    <select id="type-filter" name="type-filter">
      <option selected value="all">All types</option>
      <option value="type 2">Type 2</option>
      <option value="type 3">Type 3</option>
      <option value="type 5">Type 5</option>
    </select>
  </div>
</div>

<div id="filterable-elements">
  <div data-category="cat 1" data-type="type 3">EL 2</div>
  <div data-category="cat 2" data-type="type 5">EL 3</div>
  <div data-category="cat 3" data-type="type 5">EL 4</div>
  <div data-category="cat 1" data-type="type 2">EL 5</div>
</div>

  • Related