Property of object in array is reactive when all elements are changed, but not if only some are changed

443 Views Asked by At

I have this selectAllToggle function, which reactively selects or deselects all elements in the array. Reactively in that when the selectButton is used, all the checkboxes in the browser show selected or deselected.

The problem arise when one or more (but not all) checkboxes were manually selected. If any checkboxes are selected, the selectButtonName changes to "Deselect All", and when pressed, I want it to deselect all. The code I have correctly updates the array, in that it sets the 'selected' property to false for every student in the array, but the reactivity of it doesn't work - the tick boxes of the students that were selected manually, remain ticked in the browser.

selectAllToggle: function(key, row, $event) {
    var setTo = false;
    var newname = "Select All";
    if (this.selectButtonName === "Select All") {
        setTo = true;
        newname = "Deselect All";
    }
    if (this.selectButtonName === "Deselect All") {
        setTo = false;
        newname = "Select All";
    }

    if (this.students.length > 0) {
        for (var i = 0; i < this.students.length; i++) {
            this.students[i]['selected'] = setTo;
        }
    }
    this.selectButtonName = newname;
    
    console.log(this.students);    //shows the correct 'selected' state for all
},

The view looks like this (using vue-tables-2)

<v-client-table 
   v-if="gridReady" 
   v-model.sync="students" 
   :columns="gridcolumns" 
   :options="gridoptions"
   ref="grid">

<input type="checkbox" 
    slot="selected" 
    slot-scope="{row, update}" 
    v-model="row.selected"
    @change="selectStudent('select', row, $event)">

</v-client-table>

What can I do to make this function reactive?

1

There are 1 best solutions below

0
tuhin47 On

For deselecting after one or more element selection, you may use a computed property as the snippet below for reactively perform.

new Vue({
  el: '#app',

  data: {
    selected: [],
    clientList: [1, 2, 3, 4, 5]

  },
  computed: {
    selectAll: {
      get: function() {
        return this.selected.length > 0 &&
          this.selected.length <= this.clientList.length
      },
      set: function(value) {
        let list = [];
        if (value) {
          this.selected = this.clientList
        } else {
          this.selected = []
        }

      }
    }
  },
});
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">

  <title>Document</title>
</head>

<body>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.7/vue.js"></script>

  <div id='app'>
    <table id="example1" class="table table-bordered table-striped">
      <thead>
        <tr>
          <th>Client Name</th>
          <th style="width: 10%"><input type="checkbox" v-model="selectAll" /></th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="(item,index) in clientList">
          <td style="font-weight: bold;width: 75%">{{item}}
          </td>
          <td style="width: 25%">
            <input type="checkbox" :value="item" v-model="selected" />
          </td>
        </tr>
      </tbody>
    </table>
  </div>


</body>

</html>