I want to always have at least one checkbox checked but I mix the concepts of v-model
and :checked
.
The doc says:
v-model
will ignore the initialvalue
,checked
orselected
attributes found on any form elements. It will always treat the Vue instance data as the source of truth.
I can prevent my model to be modified but I can't prevent the checkbox to be checked...
Some code:
The template
<div class="wrapper" v-for="(s, id) in userOutputSeries" :key="id">
<input type="checkbox" :id="id" :value="id" @change="preventIfLessThanOneChecked" :checked="s.active">
<label :for="id">{{ s.display }}</label>
</div>
The model userOutputSeries
data () {
return {
userOutputSeries: {
foo: {
display: 'Awesome Foo',
active: true
},
bar: {
display: 'My Bar',
active: false
}
}
}
}
The preventIfLessThanOneChecked
handler
preventIfLessThanOneChecked (event) {
// I don't update the model so it stay at the same state
// But only need to count the active series and do what we want.
console.log(event.target.value, event.target.checked)
}
Any ideas to stop the native checkbox propagation?
You should use v-model
instead of :checked
so that changes to the userOutputSeries
data property will be reflected in the checkbox input.
Then, pass the s
reference from the v-for
to the method and set that object's active
property to true
if there are no active
checkboxes:
new Vue({
el: '#app',
data() {
return {
userOutputSeries: {
foo: {
display: 'Awesome Foo',
active: true
},
bar: {
display: 'My Bar',
active: false
}
}
}
},
methods: {
preventIfLessThanOneChecked(item) {
if (item.active) {
return;
}
let items = Object.values(this.userOutputSeries);
if (!items.find(i => i.active)) {
item.active = true;
}
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.min.js"></script>
<div id="app">
<div class="wrapper" v-for="(s, id) in userOutputSeries" :key="id">
<input type="checkbox" :id="id" :value="id" @change="preventIfLessThanOneChecked(s)" v-model="s.active">
<label :for="id">{{ s.display }}</label>
</div>
</div>
Try using disabled
on your single checked checkbox:
<div class="wrapper" v-for="(s, id) in userOutputSeries" :key="id">
<input type="checkbox" :id="id" :value="id"
:disabled="(s.active && numberOfChecked == 1) ? disabled : null"
@change="preventIfLessThanOneChecked" :checked="s.active">
<label :for="id">{{ s.display }}</label>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With