'Filtering whit a dropdown an Vanilla JS
I'm trying to filter with a dropdown, but I'm doing something wrong. It seems that the first "if statement" is true but even so it's adding the style to disable the tbody. Any clue? Thanks in advance.
tbody = document.querySelectorAll("tbody");
dropdown = document.getElementById('filter_years');
function filterByYear(){
dropdown_value = dropdown.value
for (let i = 0; i < tbody.length; i++) {
years = tbody[i].getAttribute("data-year");
if(dropdown_value == years[i]){
tbody[i].classList.remove("cat_hide_year");
} else if(dropdown_value == "2020-2022") {
tbody[i].classList.remove("cat_hide_year");
}
else{
tbody[i].classList.add("cat_hide_year");
}
}
}
dropdown.onchange = filterByYear;
td{
border:1px solid black;
padding:10px 20px;
}
#filter_dropdown{
margin-bottom:20px;
}
.cat_hide_year{
display:none;
}
<div id="filter_dropdown">
<select id="filter_years">
<option value="2020-2022">2020-2022</option>
<option value="2020">2020</option>
<option value="2021">2021</option>
<option value="2022">2022</option>
</select>
</div>
<table>
<tbody data-year="2022" class="">
<tr><td>2022</td></tr>
</tbody>
<tbody data-year="2021" class="">
<tr><td>2021</td></tr>
</tbody>
<tbody data-year="2020" class="">
<tr><td>2020</td></tr>
</tbody>
</table>
Solution 1:[1]
You have an [i] in if(dropdown_value == years[i]){ which does not belong there, but actually I think you are over-complicating this.
Note I changed the first option value to "all"
const tbody = document.querySelectorAll("tbody");
document.getElementById('filter_years').addEventListener("change", function() {
const dropdown_value = this.value;
tbody.forEach(tb => tb.hidden = dropdown_value !== "all" && dropdown_value !== tb.dataset.year)
})
td {
border: 1px solid black;
padding: 10px 20px;
}
#filter_dropdown {
margin-bottom: 20px;
}
<div id="filter_dropdown">
<select id="filter_years">
<option value="all">2020-2022</option>
<option value="2020">2020</option>
<option value="2021">2021</option>
<option value="2022">2022</option>
</select>
</div>
<table>
<tbody data-year="2022" class="">
<tr>
<td>2022</td>
</tr>
</tbody>
<tbody data-year="2021" class="">
<tr>
<td>2021</td>
</tr>
</tbody>
<tbody data-year="2020" class="">
<tr>
<td>2020</td>
</tr>
</tbody>
</table>
Solution 2:[2]
Just delete the [i] in the if statement
// AS-IS
if(dropdown_value == years[i]){
// TO-BE
if(dropdown_value == years){
tbody = document.querySelectorAll("tbody");
dropdown = document.getElementById('filter_years');
function filterByYear(){
dropdown_value = dropdown.value
for (let i = 0; i < tbody.length; i++) {
years = tbody[i].getAttribute("data-year");
if(dropdown_value == years){
tbody[i].classList.remove("cat_hide_year");
} else if(dropdown_value == "2020-2022") {
tbody[i].classList.remove("cat_hide_year");
}
else{
tbody[i].classList.add("cat_hide_year");
}
}
}
dropdown.onchange = filterByYear;
td{
border:1px solid black;
padding:10px 20px;
}
#filter_dropdown{
margin-bottom:20px;
}
.cat_hide_year{
display:none;
}
<div id="filter_dropdown">
<select id="filter_years">
<option value="2020-2022">2020-2022</option>
<option value="2020">2020</option>
<option value="2021">2021</option>
<option value="2022">2022</option>
</select>
</div>
<table>
<tbody data-year="2022" class="">
<tr><td>2022</td></tr>
</tbody>
<tbody data-year="2021" class="">
<tr><td>2021</td></tr>
</tbody>
<tbody data-year="2020" class="">
<tr><td>2020</td></tr>
</tbody>
</table>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Dali |
