I am using checkboxes to behave like radio buttons but the one behavior that I want to fix is the ability to keep the checkbox checked until the second one is checked (which will then uncheck the first one). I don't want the ability to deselect the checkbox by clicking on it again, just to hit the "none" checkbox to deselect the one below.
Referring to the image above, the label selects the checkbox as well. Once the checkbox is selected and is tapped on again, it goes back to the none checkbox on the left. Maybe radio buttons would be better, but I like checkboxes more. Here's the code:
<label :for="'none-' product.id"
:
>
<input
type="checkbox"
:id="'none-' product.id"
:true-value="false"
:false-value="true"
:value="false"
v-model="selected"
checked
/>
<span ></span>
<div >None</div>
</label>
<label :for="'product-' product.id"
:
:data-product-id="product.id"
>
<div >
<input
type="checkbox"
:true-value="true"
:false-value="false"
:id="'product-' product.id"
v-model="selected"/>
<span ></span>
CodePudding user response:
You can use watch
to check if the value of the checkbox has changed, and then either select all or deselect all, based on that.
Here's a quick demo
Vue.config.devtools = false;
Vue.config.productionTip = false;
new Vue({
el: '#app',
data: () => {
return {
options: {
check1: null,
check2: null,
check3: null,
},
check1: null,
check2: null,
check3: null,
deselect: null,
};
},
watch: {
deselect(isDeselected) {
if (isDeselected) {
this.options.check1 = false;
this.options.check2 = false;
this.options.check3 = false;
}
},
options() {
console.log("Change");
},
...["options.check1", "options.check2", "options.check3"].reduce(function (
acc,
currentKey
) {
acc[currentKey] = function (newValue) {
if (newValue) this.deselect = false;
};
return acc;
},
{}),
},
})
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<div id="app">
<label for="check1">Check 1</label>
<input type="checkbox" v-model="options.check1" id="check1" />
<br />
<label for="check2">Check 2</label>
<input type="checkbox" v-model="options.check2" id="check2" />
<br />
<label for="check3">Check 3</label>
<input type="checkbox" v-model="options.check3" id="check3" />
<br />
<label for="deselect-check">Deselect All</label>
<input type="checkbox" v-model="deselect" id="deselect-check" />
</div>
CodePudding user response:
To do this, you just need to have two v-models, one for each button, and to create a function that when one of the two buttons changes, each of the values takes its opposite value.
Then, in order to avoid deselection by clicking on its own button, you use :disabled=
with the reference of your button
Vue.js 3 with Composition
<script setup lang="ts">
import { ref } from "vue";
let selectedNone = ref(true);
let selectedChoice = ref(false);
function selectOption() {
selectedNone.value = !selectedNone;
selectedChoice.value = !selectedChoice;
}
</script>
<template>
<label>
<input
type="checkbox"
:value="false"
v-model="selectedNone"
:disabled="selectedNone"
@click="selectOption"
/>
<span>None</span>
</label>
<label >
<input
type="checkbox"
v-model="selectedChoice"
:disabled="selectedChoice"
@click="selectOption"
/>
<span>Choice</span>
</label>
</template>