Vuejs: how to check all checks and count your quantity?

Asked

Viewed 761 times

7

The problem is this:

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

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

I made 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>
<div id="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>

1 answer

1


Use one more array multipleChecks to keep the marked 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 the checks.

Also uses a watch in the 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>
<div id="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>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.