skip to Main Content

I am working on a project which is made in laravel 10 and Vue3.
In the form the users can only select 3 checkboxes and after that all checkboxes should get disabled.

I have tried it in this way as you can see below. But the problem is after 3 selected checkboxes all checkboxes are disabled even the ones which are selected so I can not deselect the selected ones.
How can I solve the problem? Thanks in advanced

<div class="form-group group-sm offset-top-20">
  <div v-if="professions_data !== null" v-for="(profession, index) in professions_data" 
 :key="profession.id">
  <div class="custom-control custom-checkbox d-inline-block" style="width:350px">
     <input class="custom-control-input" :id="profession.name_slug + '-' + profession.id"
     name="profession"
     :value="profession.id"
     v-model="value"
     type="checkbox"
     @change="updateField"
     :disabled="value.length > max && value.indexOf(n) === -1" >
      
     <label class="custom-control-label" :for="profession.name_slug + '-' + rofession.id">{{ profession.name }}</label>

    </div>
    </div>
    </div>

 data() {
        return {
            name: 'profession',
            professions_data: null,
            value: [],
            max:3
        }
    },
methods: {
        updateField() {
            this.clearErrors(this.name);
            this.$emit('update:field', this.value)
        },
}

2

Answers


  1. Use a computed value to hold an array of the inactivated values (or an empty array if none). Something like:

    <script setup>
    import { ref, computed } from 'vue'
    
    const checkBoxData = ref([
        1, 2, 3, 4, 5, 6, 7, 8, 9, 10
    ]);
    const mySelected = ref([]);
    const inactivated = computed(() => {
        if (mySelected.value.length >= 3) {
            return checkBoxData.value.filter(cbd => !mySelected.value.includes(cbd));
        } else {
            return [];
        }
    });
    
    const disabled = (datum) => {
        return inactivated.value.includes(datum);
    }
    </script>
    
    <template>
        <div>
            <div
                v-for="chkboxDatum in checkBoxData"
                :key="chkboxDatum"
            >
                <input
                    type="checkbox"
                    id="chkboxDatum"
                    v-model="mySelected"
                    :value="chkboxDatum"
                    :disabled="disabled(chkboxDatum)"
                >
                <label for="chkboxDatum">{{ chkboxDatum }}</label>
            </div>
        </div>
        <div>
            My Selected: {{ mySelected }}
        </div>
        <div>
            inactivated: {{ inactivated }}
        </div>
    </template>
    

    Explanation

    In this example the data is simple:

    const checkBoxData = ref([
        1, 2, 3, 4, 5, 6, 7, 8, 9, 10
    ]);
    

    I create a ref to hold the selected values:

    const mySelected = ref([]);
    

    and then a computed property that I called inactivated to hold the data points that I want to be inactivated. It should return an array, initially an empty array if the number of selected items is less than 3, but as soon as 3 items have been selected, it returns all the remaining values:

    const inactivated = computed(() => {
        if (mySelected.value.length >= 3) {
            return checkBoxData.value.filter(cbd => !mySelected.value.includes(cbd));
        } else {
            return [];
        }
    });
    

    Then this function can be used by the checkbox edit item to determine if it should be inactivated or not:

    const disabled = (datum) => {
        return inactivated.value.includes(datum);
    }
    
    Login or Signup to reply.
  2. i made you a working example.
    See here: Stackblitz

    but this is the code:

    <template>
      <div v-for="checkbox in checkboxes">
        <label :for="checkbox.label">{{ checkbox.label }}</label>
        <input
          :name="checkbox.label"
          type="checkbox"
          :checked="checkbox.isChecked"
          :disabled="
            !checkbox.isChecked && checkSelectedCount >= maxPossibleSelected
          "
          @click="checkbox.isChecked = !checkbox.isChecked"
        />
      </div>
      MaxCheckable: {{ checkSelectedCount }}
    </template>
    
    <script setup>
    import { ref, onMounted, computed } from 'vue';
    
    function createCheckboxes(amount) {
      for (let i = 0; i <= amount; i++) {
        const checkboxItem = {
          isChecked: false,
          label: `checkbox-${i}`,
        };
        checkboxes.value.push(checkboxItem);
      }
    }
    
    const maxPossibleSelected = ref(3);
    const checkboxes = ref([]);
    
    const checkSelectedCount = computed(() => {
      return checkboxes.value.filter((checkbox) => checkbox.isChecked).length;
    });
    
    onMounted(() => {
      createCheckboxes(10);
    });
    </script>
    
    <style scoped></style>
    

    Written in Vue3 Composition API

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search