VueJS: how to check all the checks and count their amount?

7

The problem is as follows:

I have several lists with a title, where it serves as a "select all" but it should only select the checkboxes that are its "siblings".

But I can not check them in the "select all" of each list and update the final quantity at the same time.

I've done an example showing a list being used:

var app = new Vue({
  el: '#app',
  data: {
    checks: [],
    lista: [{
        "proprietario": "Jon Snow",
        "id": "0",
        "lojas": [{
            "id": "0",
            "nome": "Loja 1"
          },
          {
            "id": "1",
            "nome": "Loja 2"
          },
        ],
      },
      {
        "proprietario": "Jon Snow 2",
        "id": "1",
        "lojas": [{
            "id": "3",
            "nome": "Loja 12323"
          },
          {
            "id": "4",
            "nome": "Loja 2123123"
          },
        ],
      },

    ],
  },
})
<script src="https://unpkg.com/vue/dist/vue.min.js"></script><divid="app">
  <p>Quantidade Final: {{checks.length}}</p>
  <div class="wrapper" v-for="(list,i) in lista">
    <div class="w-select-all">
      <input type="checkbox" value="" :id="'selectAll'+list.id">
      <label for="selectAll0">Selecionar Todos</label>
    </div>
    <div class="w-check" v-for="(loja,i) in list.lojas">
      <input type="checkbox" :value="loja.id" :id="'chk'+loja.id" v-model="checks">
      <label :for="'chk'+loja.id">{{loja.nome}}</label>
    </div>
  </div>
  {{checks}}
</div>
    
asked by anonymous 17.10.2017 / 18:43

1 answer

1

Use a multipleChecks array to store the checked owner IDs. Use @click="toggle($event, lista[i].lojas)" to be able to call a method with the stores of a given owner and be able to insert / remove these stores from checks .

It also uses a watch in checks to detect stores within a group that are removed to deselect the group.

const proprietarios = [{
    proprietario: "Jon Snow",
    id: "0",
    lojas: [{
        id: "0",
        nome: "Loja 1"
      },
      {
        id: "1",
        nome: "Loja 2"
      }
    ]
  },
  {
    proprietario: "Jon Snow 2",
    id: "1",
    lojas: [{
        id: "3",
        nome: "Loja 12323"
      },
      {
        id: "4",
        nome: "Loja 2123123"
      }
    ]
  }
];

new Vue({
  el: "#app",
  data: {
    checks: [],
    multipleChecks: [],
    lista: proprietarios
  },
  watch: {
    checks(lojas) {
      this.lista.forEach(lista => {
        const completa = lista.lojas.every(loja => lojas.includes(loja.id));
        if (completa) {
          this.multipleChecks = this.multipleChecks.concat(lista.id).filter((el, i, arr) => arr.indexOf(el) == i);
        } else {
          this.multipleChecks = this.multipleChecks.filter(id => id != lista.id);
        }
      });
    }
  },
  methods: {
    toggle(e, lojas) {
      const addAll = e.target.checked;
      var idsLojas = lojas.map(l => l.id);
      if (addAll) {
        this.checks = this.checks.concat(idsLojas).filter((el, i, arr) => arr.indexOf(el) == i);
      } else {
        this.checks = this.checks.filter(loja => !idsLojas.includes(loja));
      }
    }
  }
});
<script src="https://unpkg.com/vue/dist/vue.min.js"></script><divid="app">
  <p>Quantidade Final: {{checks.length}}</p>
  <div class="wrapper" v-for="(list, i) in lista">
    <div class="w-select-all">
      <input type="checkbox" @click="toggle($event, lista[i].lojas)" :value="list.id" v-model="multipleChecks">
      <label>Selecionar Todos ({{list.proprietario}})</label>
    </div>
    <div class="w-check" v-for="(loja, i) in list.lojas">
      <input type="checkbox" :value="loja.id" v-model="checks">
      <label :for="'chk'+loja.id">{{loja.nome}}</label>
    </div>
  </div>
</div>
    
17.10.2017 / 20:47