I'm trying to set up a simple Vue instance with a collection of radio buttons. The goal is that, if the user clicks on a radio button that is already checked, it will uncheck the respective radio button. But I couldn't do this using Vue yet. Here's my code so far:
HTML:
<div id="app">
<div v-for="(val, key) in list">
<input type="radio" name="radio" :value="val" v-model="selected" :id="val">
<label :for="val" @click="uncheck( val )">{{ val }}</label>
</div>
<button @click="uncheckAll">Uncheck all</button>
</div>
JS:
var app = new Vue({
el: '#app',
data : {
list: [ 'one', 'two', 'three' ],
selected: 'two',
},
methods : {
uncheck: function( val ){
console.log( val, this.selected );
if ( val == this.selected ){
this.selected = false;
}
},
uncheckAll: function(){
this.selected = false;
}
}
})
Seems like the uncheck
method is called, but then the radio button triggers a change
event and then updates the value of selected
again. uncheckAll
method works as expected, probably because it's not tied to the data using v-model
.
Any tips or suggestions to make this work? Here's a pen I created for this example: https://codepen.io/diegoliv/pen/JrPBbG
You can use the
prevent
modifier to prevent the default behavior of clicking the label:Here's a working Codepen.
The difficulty is that
v-model
is changing the value ofselected
before you can examine it to see what its previous value is. You need another variable.The idea is: when you click an item, it checks whether it matches
previouslySelected
(rather thanselected
). If it matches, unselect. Then setpreviouslySelected
to the value ofselected
.The
click
handler should be on the input, not on the label; it is the function of the label to forward clicks to the input, anyway.set
to happen. (thanks to Vlad T. in the comments)A more in-the-data way of approaching it would be to have a computed based on your selected, and have its setter do the check for re-selecting. No click handler. Everything is handled in the normal course of setting the value.
Here goes a simple one without using
v-model
and just only takes one variable for storing the current selected value.