Sam Teng Wong
Sam Teng Wong

Reputation: 2439

VueJS trigger Checkbox by clicking table row

I'm really new to vuejs and I was wondering if it is possible to trigger the checkbox by clicking the table row.

here's a fiddle for you to play. https://jsfiddle.net/50wL7mdz/265410/

HTML

<div id="app">
<table>
    <tbody>
      <tr v-for="cat in categories" @click="selectCat(cat)">
        <td><input type="checkbox" :value="cat" v-model="selected" name="" id=""></td>
        <td>{{ cat.code}}</td>
        <td>{{ cat.name }}</td>
      </tr>
    </tbody>
</table>
<button @click="checkData()">Check</button>
</div>

VUEJS

  new Vue({
  el: '#app',
  data() {
    return {
     categories: [
                {code:'HW', name:'Hardware'},
          {code:'SW', name:'Software'},
          {code:'OS', name:'Office Supplies'}
     ],
     selected:[]
    }
  },
  methods:{ 
  selectCat(cat){
    this.selected.push(cat);
  },
 checkData(){
      alert(1);
       console.log(this.selected);
      }
  }
})

Thanks in advance.

Upvotes: 1

Views: 7795

Answers (1)

Philip Feldmann
Philip Feldmann

Reputation: 8375

Add a selected model to your categories and switch that attribute on row click like so:

<div id="app">
    <table>
        <tbody>
          <tr v-for="(cat, index) in categories" :key="index" @click="cat.selected = !cat.selected">
            <td><input type="checkbox" v-model="cat.selected"></td>
            <td>{{ cat.code}}</td>
            <td>{{ cat.name }}</td>
          </tr>
        </tbody>
    </table>
</div>


new Vue({
  el: '#app',
  data() {
    return {
     categories: [
                {code:'HW', name:'Hardware', selected: false},
          {code:'SW', name:'Software', selected: false},
          {code:'OS', name:'Office Supplies', selected: false}
     ]
    }
  },
  methods:{
  }
})

Manipulating the state of natives components should always be done by changing their v-model, rather than going into the DOM and and setting a selected attribute. Basically let your model define the state of your view.

Here's another version that'll use a separate array for handling the selected state:

<div id="app">
    <table>
        <tbody>
          <tr v-for="(cat, index) in categories" :key="index" @click="toggleSelect(cat)">
            <td><input type="checkbox" :checked="selected.includes(cat.code)"></td>
            <td>{{ cat.code}}</td>
            <td>{{ cat.name }}</td>
          </tr>
        </tbody>
    </table>
</div>

new Vue({
  el: '#app',
  data() {
    return {
     categories: [
          {code:'HW', name:'Hardware'},
          {code:'SW', name:'Software'},
          {code:'OS', name:'Office Supplies'}
     ],
     selected: ['HW']
    }
  },
  methods:{
    toggleSelect (cat) {

      if (this.selected.includes(cat.code)) {
        this.selected.splice(this.selected.findIndex(v => v === cat.code), 1)
      } else {
        this.selected.push(cat.code)
      }
    } 
  }
})

Upvotes: 5

Related Questions