2

How do you toggle a class in vue.js for list rendered elements? This question is an extension on this well answered question. I want to be able to toggle each element individually as well as toggle them all. I have attempted a solution with the below code but it feels fragile and doesn't seem to work.

A different solution would be to use a single variable to toggle all elements and then each element has a local variable that can be toggled on and off but no idea how to implement that..

// html element
<button v-on:click="toggleAll"></button>
<div v-for="(item, i) in dynamicItems" :key=i
     v-bind:class="{ active: showItem }"
     v-on:click="showItem[i] = !showItem[i]">
</div>

//in vue.js app
//dynamicItems and showItem will be populated based on API response
data: {
    dynamicItems: [], 
    showItem: boolean[] = [],
    showAll: boolean = false;
},
methods: {
    toggleAll(){
        this.showAll = !this.showAll;
        this.showItem.forEach(item => item = this.showAll);
    }
}
MJ_Wales
  • 873
  • 2
  • 8
  • 20
  • You can just wrap your `v-for` element in another div and have the binding of the class to toggle all on that, then it'll hide everything rather than binding it on the `v-for` – George Mar 15 '19 at 12:11

2 Answers2

2

Here is the small example to acheive you want. This is just a alternative not exact copy of your code.

var app = new Vue({
el:'#app',
data: {
    dynamicItems: [
      {id:1,name:'Niklesh',selected:false},
      {id:2,name:'Raut',selected:false}
    ],
    selectedAll:false,
},
methods: {
    toggleAll(){
      for(let i in this.dynamicItems){
         this.dynamicItems[i].selected = this.selectedAll;
      }
    }
}
});
.active{
  color:blue;
  font-size:20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.9/vue.js"></script>
<div id="app">
<template>
<input type="checkbox" v-model="selectedAll" @change="toggleAll"> Toggle All 
<div v-for="(item, i) in dynamicItems">
  <div :class='{active:item.selected}'><input type="checkbox" v-model="item.selected">Id : {{item.id}}, Name: {{item.name}}</div>
</div>
{{dynamicItems}}
</template>
</div>
Niklesh Raut
  • 34,013
  • 16
  • 75
  • 109
1

I think all you need to do is this

v-bind:class="{ active: showItem || showAll }"

and remove the last line from toggleAll

You also need to use Vue.set when updating array values, as array elements aren't reactive.

tony19
  • 125,647
  • 18
  • 229
  • 307
Radu Diță
  • 13,476
  • 2
  • 30
  • 34