Reputation: 35
I have a list of items (artists) on the page, above this I have buttons (categories) to filter the list, what I can't get my head around in my Javascript is how to filter an item if it sits within multiple categories.
Here is my JS:
const buttons = document.querySelector("#buttons").children
const items = document.querySelector(".artists-container").children
for(let i=0; i<buttons.length; i++) {
buttons[i].addEventListener("click", function(){
for(let j=0; j<buttons.length; j++){
buttons[j].classList.remove("active")
}
this.classList.add("active")
const target = this.getAttribute("data-target")
for(let k=0; k<items.length; k++){
items[k].style.display="none"
if(items[k].getAttribute("data-discipline")==target){
items[k].style.display="block"
}
if(target=="artists"){
items[k].style.display="block"
}
}
})
}
If it helps, here is my HTML too:
<section class="artists">
<div class="filter-btn">
<ul id="buttons">
<li class="active" data-target="artists">All</li>
<li data-target="category1">Category 1</li>
<li data-target="category2">Category 2</li>
<li data-target="category3">Category 2</li>
</ul>
</div>
<div class="artists-container">
<article data-discipline="category1 category2">
<a href="#">
<div class="artist-details">
<p>Category 1, Category 2</p>
<h5>I appear in two categories</h5>
</div>
</a>
</article>
<article data-discipline="category3">
<a href="#">
<div class="artist-details">
<p>Category 3</p>
<h5>I appear in one category</h5>
</div>
</a>
</article>
</section>
Any help would be greatly appreciated.
Thanks
Upvotes: 0
Views: 134
Reputation: 2076
I think the simplest solution is to check whether the target is within the attribute list by using includes
.
const buttons = [...document.querySelector("#buttons").children]
const items = [...document.querySelector(".artists-container").children]
for (let i = 0; i < buttons.length; i++) {
buttons[i].addEventListener("click", function() {
buttons.forEach(button => button.classList.remove("active"))
this.classList.add("active")
const target = this.getAttribute("data-target")
items.forEach(item => {
let display = target === "artists" ? "block" : "none"
if (item.getAttribute("data-discipline").includes(target)) {
display = "block"
}
item.style.display = display;
});
});
}
<section class="artists">
<div class="filter-btn">
<ul id="buttons">
<li class="active" data-target="artists">All</li>
<li data-target="category1">Category 1</li>
<li data-target="category2">Category 2</li>
<li data-target="category3">Category 3</li>
</ul>
</div>
<div class="artists-container">
<article data-discipline="category1 category2">
<a href="#">
<div class="artist-details">
<p>Category 1, Category 2</p>
<h5>I appear in two categories</h5>
</div>
</a>
</article>
<article data-discipline="category3">
<a href="#">
<div class="artist-details">
<p>Category 3</p>
<h5>I appear in one category</h5>
</div>
</a>
</article>
</div>
</section>
Upvotes: 0
Reputation: 1242
See my example, I set little change in equals with target and slightly reduced the code:
const buttons = Array.from(document.querySelector("#buttons").children)
const items = Array.from(document.querySelector(".artists-container").children)
const onClick = function() {
buttons.forEach((button)=>{ button.classList.remove("active") })
this.classList.add("active")
const target = this.getAttribute("data-target")
items.forEach((item)=>{ item.style.display="none" })
items.filter(item=>item.getAttribute("data-discipline").indexOf(target)>=0 || target=="artists").forEach((item)=>{item.style.display="block"})
}
buttons.forEach((button)=>{ button.addEventListener("click",onClick) })
See full example in playground: https://jsfiddle.net/denisstukalov/uz5qeoLy/9/#&togetherjs=LpfzceeTVL
Upvotes: 1