'toggle class for the clicked element queryselectorAll

I want to expand a div onclick the problem is it expands every other div with the same class

<div class="formations div">
          <div class="buttn" @click="expand">
              <p>Formations</p><i class="fas fa-chevron-right"></i>
          </div>
          <div class="link">
              <a>link</a>
              <a>link</a>
              <a>link</a>
          </div>
      </div>
      <div class="Evolution div">
          <div class="buttn">
              <p>Evolution & Carrieres</p><i class="fas fa-chevron-right"></i>
          </div>
          <div class="link">
              <a>link</a>
              <a>link</a>
              <a>link</a>
          </div>
      </div>

js:

expand(){
        let links= document.querySelectorAll(".link")
        for(let i = 0; i< links.length; i++){
            links[i].classList.toggle('show');
        }

I tried other solutions but i couldn't fix the issue



Solution 1:[1]

You can send button to function and toggle the closest links.

With Vue you can create data object with array of buttons and links, then method to toggle specific links, or you can use refs, without data and pass ref name to method:

new Vue({
  el: '#app',
  data: {
    types : [
      { name : 'Formations',
        links: [ 'formations link1', 'formations link2', 'formations link3' ]
      },
      { name : 'Evolution & Carrieres',
        links: [ 'evolution link1', 'evolution link2', 'evolution link3' ]
      },
    ],
    toggleLinks: { el: null, state: false }
  },
  methods: {
    expand(el) {
      this.toggleLinks.el = el.name;
      this.toggleLinks.state = !this.toggleLinks.state;
    },
    expandRef(el) {
      let links = this.$refs[el].closest('.div').querySelectorAll('.link')
      links.forEach(l => l.classList.toggle('show'))
    }
  },
})

/*function expand(el) {
  let links = el.closest('.div').querySelectorAll('.link')
  links.forEach(l => l.classList.toggle('show'))
}*/
.link {
  display: none;
  list-style: none;
}

.show {
  display: block;
}

ul {
  list-style: none;
  margin: 0;
}

#app {
  display: flex;
  
}
.refs {
  margin-left: 2em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <ul >
    <h3>With data</h3>
    <li v-for="type in types" :key="type.name">
      <button class="buttn" @click="expand(type)">
        <p>{{ type.name }}</p><i class="fas fa-chevron-right"></i>
      </button>
      <ul class="link" :class="{ 'show': toggleLinks.state && toggleLinks.el === type.name }">
        <li v-for="link in type.links" :key="link">
          <a>{{ link }}</a>
        </li>
      </ul>
    </li>
  </ul>

  <div class="refs">
    <h3>With refs</h3>
    <div class="formations div">
        <button ref="f" class="buttn" @click="expandRef('f')">
            <p>Formations</p><i class="fas fa-chevron-right"></i>
        </button>
        <div class="link">
            <a>formations link</a>
            <a>formations link</a>
            <a>formations link</a>
        </div>
    </div>
    <div class="Evolution div">
        <button ref="e" class="buttn" @click="expandRef('e')">
            <p>Evolution & Carrieres</p><i class="fas fa-chevron-right"></i>
        </button>
        <div class="link">
            <a>evolution link</a>
            <a>evolution link</a>
            <a>evolution link</a>
        </div>
    </div>
  </div>
  
</div>

<!-- <div class="formations div">
    <button class="buttn" onclick="expand(this)">
        <p>Formations</p><i class="fas fa-chevron-right"></i>
    </button>
    <div class="link">
        <a>formations link</a>
        <a>formations link</a>
        <a>formations link</a>
    </div>
</div>
<div class="Evolution div">
    <button class="buttn" onclick="expand(this)">
        <p>Evolution & Carrieres</p><i class="fas fa-chevron-right"></i>
    </button>
    <div class="link">
        <a>evolution link</a>
        <a>evolution link</a>
        <a>evolution link</a>
    </div>
</div> -->

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