Home > OS >  Vue Checkboxes - Keep selected unless another checkbox is checked
Vue Checkboxes - Keep selected unless another checkbox is checked

Time:05-12

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.

enter image description here

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>
  • Related