Search code examples
javascriptvue.jsbootstrap-vuecomputed-properties

Bootstrap check box not updating on Computed Properties


I'm trying to create a checkbox that selects all checkboxes.

I have an array of objects. Inside each object is a allowed value. Which states if a checkbox is active. The array is coming from a computed propertie which is getting the data from a getter in my store.

I have created a single checkbox and when it's selected it mutates my state. The state is getting updated, but my template isn't rendering the correct value.

I can see in my Vue console the state is being updated and in the console.log() in the computed properties.

I want the computed properties to display to correct data. I've tried moving everything to a method and calling the method, but it still isn't showing. When i'm understand of the Vue docs. Computed props should update if a value is updated.

How is it that my template isn't updating? and how can I update it?

template

<b-form-checkbox
   v-model="allSelected"
   :indeterminate="indeterminate"
   @change="toggleAll"
>Select All

</b-form-checkbox>
   <b-row>
    <b-col v-for="cat in categories" :key="cat.id" sm="12" md="6" lg="4">
      <b-form-checkbox
        
        :value="cat"
        v-model="cat.allowed"
      />
      <span>{{ cat.name }}</span>
    </b-col>
  </b-row>


  computed: {
    ...mapGetters("categories", ["customerCategories"]),

  categories() {
   return this.customerCategories;
  },

},

  methods: {
    ...mapActions("categories", ["updateToggle"]),

   toggleAll() {
    this.updateToggle(this.allSelected);
   },
  }

....store

  updateToggle({ commit }, data) {
    commit("isCategoriesActive", data);
  }

    isCategoriesActive: (state, value) =>
      (state.list = state.list.map(cat => {
      cat.allowed = value
    return cat
   })),

Solution

  • Check out this solution, with v-model reference to a computed getter/setter: Playground

    The only thing from my example you need to change is:

    1. Where the cats array is stored
    2. getter/setter in the computed allSelected
    <script>
    export default({
      data () {
        return {
          cats: [
            { name: "one", allowed: false},
            { name: "two", allowed: false},
            { name: "three", allowed: false},
            { name: "four", allowed: false},
            { name: "five", allowed: false}
          ]
        }
      },
      computed: {
        allSelected: {
          get () {
            return this.cats.every(cat => cat.allowed)
          },
          set (value) {
            this.cats.map(cat => cat.allowed = value)
          }
        }
      }
    })
    </script>
    
    <template>
    allSelected: <input type="checkbox" v-model="allSelected" />
      <hr />
      <template v-for="cat in cats" :key="JSON.stringify(cat)">
      <div>
        {{cat.name}} : <input type="checkbox" v-model="cat.allowed" />
        </div>
      </template>
    </template>