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>