leewilson78
leewilson78

Reputation: 35

Filtering content using Javascript but how to when content sits in multiple 'categories'

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

Answers (2)

Paul
Paul

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

Denis Stukalov
Denis Stukalov

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

Related Questions