Vue: v-model does not update value when external input/change event is fired on a checkbox

Created on 4 May 2016  Â·  10Comments  Â·  Source: vuejs/vue

Problem

A checkbox input with v-model does not update the value when an "input" or "change" event was triggered externally, whereas this does work with a text input element.

Vue.js version

1.0.21

Reproduction Link

http://jsfiddle.net/7ud6jL42/3

Steps to reproduce

Click the button titled "Uncheck the checkbox" and the button titled "Fill text".

What is Expected?

The value of foo should change to false and the value of bar should change to "foobar".

What is actually happening?

The value of foo stays false whereas the value of bar changes to "foobar". It appears that the v-model does not pick up the fired "input" or "change" event on a checkbox input element but it does on a text input element.

Most helpful comment

Just in case someone else stumbles upon this, you can make sure the model is updated by using:

elem.dispatchEvent(new Event('input')) 

for <input> and <textarea>

or

elem.dispatchEvent(new Event('change')) 

for <select> elements

All 10 comments

This is a jQuery problem, trigger doesn't dispatch native events in some cases. See: http://stackoverflow.com/questions/21290775/jquery-el-triggerchange-doesnt-fire-native-listeners

I will add another note: checkbox does not emit input event, only change.

Sorry for buzz..

After reading this i have no clue on how to update the v-model when i update the checkbox by JavaScript.

I tried the document.

http://vuejs.org/guide/forms.html#Radio

With code like this.

var example4= document.getElementById("example-4")
example4.firstElementChild.checked=true

The v-model not updated accordingly.

What should i do without jQuery?

@flyyang You should directly update the model and never change the element variables manually

@yyx990803 Thanks for this — you saved me some headaches.

Just in case someone else stumbles upon this, you can make sure the model is updated by using:

elem.dispatchEvent(new Event('input')) 

for <input> and <textarea>

or

elem.dispatchEvent(new Event('change')) 

for <select> elements

I think it can be anywhere @atilkan, as long as you have a direct reference to the element in question. Placing a ref attribute on the element in question should work.

E.g. in this vue component ...

<template>
  <input type="checkbox" ref="checkbox" />
</template>

<script>
  export default {
    mounted () {
      //you can directly reference the checkbox via its ref attribute value:
     console.log(this.$refs.checkbox)
   }
  }
</script>

You could also reference it from a different component directly (not advisable) if you have direct access to this component like:

<template>
  <div>
    <MyCheckbox ref="myCheckbox" />
  </div>
</template>

<script>
  import MyCheckbox from './path/to/checkbox.vue'
  export default {
    components: {
      MyCheckbox
    },
    mounted () {
      const myCheckbox = this.$refs.myCheckbox //references the MyCheckbox component
      const checkboxElement = myCheckbox.$refs.checkbox //references the input[type='checkbox'] within the MyCheckbox component
      checkboxElement.dispatchEvent(new Event('change')) //to trigger the "change" event
    }
  }
</script>

If you must trigger the event from an external component, I'd suggest using vue's event emitters rather than a direct reference, to keep your components clean.


Also, it looks like the fiddle link doesn't work anymore @djam90 ... the URL for the vue script is broken.

I got the 'input' event emit to happen when the checkbox value changes by using a computed for the template input.

            inputValue() {
                this.$emit('input', this.value);
                return this.value;
            }

@mykeels update his answer :
use elem.dispatchEvent(new Event('change')) for check box and radio input.

I think this should be re-opened, the issue is still present and is actually not releated to jQuery, which was the argument given for closing this. Vue not being able to react as expected to externally invoked events is especially problematic when we are talking about things like Selenium-driven regression testing, but it also affects cross-app interaction for Vue-based Widgets and many other things.

Check out this fiddle to see the problem in action:
https://jsfiddle.net/Sigma90/f9j5a8ny/

The first checkbox uses "v-bind:checked" and "v-on:change", the second one uses "v-model", which is supposed to be a shortcut for those two. Calling "dispatchEvent(new Event('change'))" on the first one changes the data as expected, but the same operation on the second one does nothing, despite the fact that the documentation and the previous commenter both state that the change event should work.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Jokcy picture Jokcy  Â·  3Comments

robertleeplummerjr picture robertleeplummerjr  Â·  3Comments

aviggngyv picture aviggngyv  Â·  3Comments

loki0609 picture loki0609  Â·  3Comments

fergaldoyle picture fergaldoyle  Â·  3Comments