89

I have a v-model on checkbox which values are assigned from a loop. I want the click event to invoke a function where I need to access the data of the checked ones. When a click is triggered, if I log the state it does not print the current clicked data of the checkbox. It prints previous clicked checkbox data. Should a event must be passed and accessed data in the function?

<div id="demo">
  <ul>
    <li v-for="mainCat in mainCategories">
      <input 
        type="checkbox" 
        :value="mainCat.merchantId"     
        id="mainCat.merchantId" 
        v-model="checkedCategories" 
        @click="check(checkedCategories)"
      > 
      {{mainCat.merchantId}}
    </li>
  </ul> 
  {{ checkedCategories }}
</div>

script:

var demo = new Vue({
  el: '#demo',
  data: {
    checkedCategories: [],
    mainCategories: [{
      merchantId: '1'
    }, {
    merchantId: '2'
    }] //testing with data use: [{done:false,content:'testing'}]
  },
  methods: {
    check: function(e) {
    console.log(this.checkedCategories,e)
    }
  }
})

Js fiddle:http://jsfiddle.net/bmpfs2w2/

4 Answers 4

192

Use @change instead of @click. Click event is triggered before value is really changed.

<input type="checkbox" 
  :value="mainCat.merchantId" 
  id="mainCat.merchantId" 
  v-model="checkedCategories" 
  @change="check($event)"
>

http://jsfiddle.net/eLzavj5f/

Sign up to request clarification or add additional context in comments.

5 Comments

"Click event is triggered before value is really changed." I just spent half a day trying to figure out why my events were reflecting properly. This saved me.
Thanks! Who can't catch the correct event with boostrap-vue, just replace b-form-checkbox component to plain code.
Thank you for the example! The interesting finding was the param value in the event handler reflects the current checked/unchecked status whereas the v-model bound property was showing the previous state.
There is a caveat here - @change is called before the value is actually changed. If you aren't passing the $event then whatever function you call will still have the old value.
This fiddle is broken, and (e) has never been used.
9

If you'd like the function to be called after the value has been changed, you can wrap your handler functionality inside of this.$nextTick(). You can read about $nextTick, but the gist is

Defer the callback to be executed after the next DOM update cycle. Use it immediately after you’ve changed some data to wait for the DOM update.

So your handler will get called after the DOM gets updated, aka after your state has changed and the effects have been reflected in the DOM.

<input 
  type="checkbox" 
  :value="mainCat.merchantId"     
  id="mainCat.merchantId" 
  v-model="checkedCategories" 
  @change="check($event)"
> 

// ...

check (e) {
  this.$nextTick(() => {
    console.log(checkedCategories, e)
  })
}

2 Comments

e is not defined
true, got to define $event: @change="check($event)" otherwise great, got the event object. Thanks. Also console.log(e.target.id) will return the checkbox that was clicked.
3

Altered Grant's solution

<input 
  type="checkbox" 
  :value="mainCat.merchantId"     
  id="mainCat.merchantId" 
  v-model="checkedCategories" 
  @change="check($event)"
/> 

// ...

check (e) {
  this.$nextTick(() => {
    console.log(e.target.id)
  })
}

Thanks Grant

Comments

0

If someone is looking just for change event actual value then you can use:

<input 
  type="checkbox" 
  ...
  @change="check($event)"
/> 

// ...

check(e) {
  console.log(e.srcElement.checked);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.