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.
1.0.21
http://jsfiddle.net/7ud6jL42/3
Click the button titled "Uncheck the checkbox" and the button titled "Fill text".
The value of foo
should change to false and the value of bar
should change to "foobar".
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.
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.
Most helpful comment
Just in case someone else stumbles upon this, you can make sure the model is updated by using:
for
<input>
and<textarea>
or
for
<select>
elements