Eddie Weldon
Eddie Weldon

Reputation: 133

How to change the specific checkbox label class @change in Vue?

Background: I have a list of checkboxes that is bound to a names array. I am trying to change the class of the specific name once the checkbox is clicked.

Problem: Once a checkbox is clicked it changes the class of all the names instead of the specific name attached to the checkbox.

JSFiddle of the issue: JSFiddle

HTML

<div id="app">
<ul>
 <li v-for="name in names" :key="index">
   <input @click="available = !available" type="checkbox">  
   <label :class="{available:available}" >{{name.name}}</label>
  </li>
</ul> 
</div>

Vue instance

var app = new Vue({
  el: '#app',
  data: {
    available: false,
    names: [{'name':'Jerry'},{'name':'Eddie'},{'name':'Kerry'},{'name':'Jane'}]
  }
})

Css

.available{
    text-decoration: line-through;
}

Upvotes: 1

Views: 1545

Answers (2)

Andres Foronda
Andres Foronda

Reputation: 1409

Ad the available variable to each name object and use a method to update the available property:

var app = new Vue({
  el: '#app',
  data: {
    names: [
      {'name':'Jerry', 'available': false},
      {'name':'Eddie', 'available': false},
      {'name':'Kerry', 'available': false},
      {'name':'Jane', 'available': false}
     ]
  },
  methods: {
    updateAvailable(index) {
      // Update the available property on the specific object with its index
      this.names[index].available = !this.names[index].available
    }
  }
})

Then in your template, call the method updateAvailable:

<div id="app">
<ul>
 <li v-for="(name, index) in names" :key="index">
   <input @click="updateAvailable(index)" type="checkbox">  
   <label :class="{available: name.available}" >{{name.name}}</label>
  </li>
</ul> 
</div>

Upvotes: 2

Phil
Phil

Reputation: 164723

Move the available property in to each name element and toggle name.available in your template. You can even use v-model on your checkboxes.

const names = [{'name':'Jerry'},{'name':'Eddie'},{'name':'Kerry'},{'name':'Jane'}]

const app = new Vue({
  el: '#app',
  data: () => ({
    names: names.map(name => ({ ...name, available: false }))
  })
})
.available {
  text-decoration: line-through;
}
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<div id="app">
  <ul>
    <li v-for="(name, i) in names">
      <input :id="`name_${i}`" v-model="name.available" type="checkbox">
      <label :for="`name_${i}`" :class="{ available: name.available }">
        {{name.name}}
      </label>
    </li>
  </ul>
</div>

Upvotes: 1

Related Questions