简体   繁体   English

检查所有复选框vuejs

[英]Check all checkboxes vuejs

I'm displaying a list of users in a table, each row has a checkbox to select the user and the checkbox value is the user's ID.我在表格中显示用户列表,每一行都有一个复选框来选择用户,复选框值是用户的 ID。 The selected IDs are in turn displayed in a span below the table.选定的 ID 依次显示在表格下方的跨度中。

How can I select all checkboxes and deselect all checkboxes on the click of a "select all" checkbox that I have in the header of my table?如何在单击表格标题中的“全选”复选框时选择所有复选框并取消选择所有复选框? Do I interact with the DOM to do this or through the vue object, I'm thinking it should be the latter but quite unsure how to approach what appears to be an easy task?!我是与 DOM 交互还是通过 vue 对象进行交互,我认为应该是后者,但不确定如何处理看似简单的任务?! Any help would be appreciated!任何帮助,将不胜感激!

HTML HTML

<div id="app">
    <h4>Users</h4>
    <div>
        <table>
            <tr>
                <th>Name</th>
                <th>Select <input type="checkbox" @click="selectAll"></th>
            </tr>
            <tr v-for="user in users">
                <td>{{ user.name }}</td>
                <td><input type="checkbox" v-model="selected" value="{{ user.id }}"></td>
            </tr>
        </table>
    </div>

    <span>Selected Ids: {{ selected| json }}</span>
</div>

Javascript/Vuejs Javascript/Vuejs

new Vue({
    el: '#app',
    data: {
        users: [ 
            { "id": "1", "name": "Shad Jast", "email": "pfeffer.matt@yahoo.com", 
            { "id": "2", "name": "Duane Metz", "email": "mohammad.ferry@yahoo.com"}, 
            { "id": "3", "name": "Myah Kris", "email": "evolkman@hotmail.com"}, 
            { "id": "4", "name": "Dr. Kamron Wunsch", "email": "lenora95@leannon.com"}, 
            { "id": "5", "name": "Brendon Rogahn", "email": "verlie.buckridge@yahoo.com"}
        ],
        selected: []
    },
    methods: {
        selectAll: function() {
            // ?
        }
    }
})

I think @Jeremy's answer is cleaner way, but it require for checked property on each user object which is makes no sense if the data come from an API request.我认为@Jeremy 的答案是更简洁的方式,但它需要checked每个用户对象的属性,如果数据来自 API 请求,这是没有意义的。

Here is working and cleaner code for select/deselect all rows without having to add checked property on user object:这是用于选择/取消选择所有行的工作且更简洁的代码,而无需在用户对象上添加checked的属性:

 new Vue({ el: '#app', data: { users: [ { "id": "1", "name": "Shad Jast", "email": "pfeffer.matt@yahoo.com" }, { "id": "2", "name": "Duane Metz", "email": "mohammad.ferry@yahoo.com" }, { "id": "3", "name": "Myah Kris", "email": "evolkman@hotmail.com" }, { "id": "4", "name": "Dr. Kamron Wunsch", "email": "lenora95@leannon.com" } ], selected: [] }, computed: { selectAll: { get: function () { return this.users ? this.selected.length == this.users.length : false; }, set: function (value) { var selected = []; if (value) { this.users.forEach(function (user) { selected.push(user.id); }); } this.selected = selected; } } } });
 <script src="https://cdn.jsdelivr.net/vue/latest/vue.js"></script> <div id="app"> <h4>User</h4> <div> <table> <tr> <th><input type="checkbox" v-model="selectAll"></th> <th align="left">Name</th> </tr> <tr v-for="user in users"> <td> <input type="checkbox" v-model="selected" :value="user.id" number> </td> <td>{{ user.name }}</td> </tr> </table> </div> </div>

Please note that the number attribute on row's checkbox is required, otherwise you have to push the user id selectAll method as a string, like selected.push(user.id.toString());请注意,行的复选框上的number属性是必需的,否则您必须将用户 id selectAll方法作为字符串推送,例如selected.push(user.id.toString());

Adding my own answer as edits on the answer by nhydock weren't accepted (I think?).不接受添加我自己的答案作为对 nhydock 答案的编辑(我认为?)。

Solution selects and selects all.解决方案选择并选择所有。

HTML HTML

<div id="app">
    <h4>User</h4>
        <div>
            <table>
                <tr>
                    <th>Name</th>
                    <th>Select <input type="checkbox" @click="selectAll" v-model="allSelected"></th>
                </tr>
                <tr v-for="user in users">
                    <td>{{ user.name }}</td>
                    <td><input type="checkbox" v-model="userIds" value="{{ user.id }}"></td>
                </tr>
            </table>
        </div>

        <span>Selected Ids: {{ userIds | json }}</span>
</div>

Javascript/Vuejs Javascript/Vuejs

new Vue({
    el: '#app',
    data: {
        users: [ 
            { "id": "1", "name": "Shad Jast", "email": "pfeffer.matt@yahoo.com"}, 
            { "id": "2", "name": "Duane Metz", "email": "mohammad.ferry@yahoo.com"}, 
            { "id": "3", "name": "Myah Kris", "email": "evolkman@hotmail.com"}, 
            { "id": "4", "name": "Dr. Kamron Wunsch", "email": "lenora95@leannon.com"}, 
            { "id": "5", "name": "Brendon Rogahn", "email": "verlie.buckridge@yahoo.com"}
        ],
        selected: [],
        allSelected: false,
        userIds: []
    },
    methods: {
        selectAll: function() {
            this.userIds = [];

            if (!this.allSelected) {
                for (user in this.users) {
                    this.userIds.push(this.users[user].id);
                }
            }
        },
    }
})

Working fiddle: https://jsfiddle.net/okv0rgrk/3747/工作小提琴: https ://jsfiddle.net/okv0rgrk/3747/

How about my answer, with less properties, easy to understand?我的答案怎么样,属性少,易于理解?

 new Vue({ el: '#app', data: { users: [{ "id": "1", "name": "Shad Jast", "email": "pfeffer.matt@yahoo.com", 'checked': false }, { "id": "2", "name": "Duane Metz", "email": "mohammad.ferry@yahoo.com", 'checked': false }, { "id": "3", "name": "Myah Kris", "email": "evolkman@hotmail.com", 'checked': false }, { "id": "4", "name": "Dr. Kamron Wunsch", "email": "lenora95@leannon.com", 'checked': false }, ], }, computed: { selectAll: function() { return this.users.every(function(user){ return user.checked; }); } }, methods: { toggleSelect: function() { var select = this.selectAll; this.users.forEach(function(user) { user.checked = !select; }); this.selectAll = !select; }, } });
 <script src="https://cdn.jsdelivr.net/vue/latest/vue.js"></script> <div id="app"> <h4>User</h4> <div> <table> <tr> <th>Name</th> <th>Select <input type="checkbox" @click="toggleSelect" :checked="selectAll"> </th> </tr> <tr v-for="user in users"> <td>{{ user.name }}</td> <td> <input type="checkbox" v-model="user.checked"> </td> </tr> </table> </div> </div>

Basically the same answer as @Rifki, but checks if each element exists in both, rather than just the length.基本上与@Rifki 相同的答案,但检查每个元素是否存在于两者中,而不仅仅是长度。

 new Vue({ el: '#app', data: { users: [{ "id": "1", "name": "Shad Jast", "email": "pfeffer.matt@yahoo.com" }, { "id": "2", "name": "Duane Metz", "email": "mohammad.ferry@yahoo.com" }, { "id": "3", "name": "Myah Kris", "email": "evolkman@hotmail.com" }, { "id": "4", "name": "Dr. Kamron Wunsch", "email": "lenora95@leannon.com" } ], selected: [] }, computed: { selectAll: { get() { if (this.users && this.users.length > 0) { // A users array exists with at least one item let allChecked = true; for (const user of this.users) { if (!this.selected.includes(user.id)) { allChecked = false; // If even one is not included in array } // Break out of loop if mismatch already found if(!allChecked) break; } return allChecked; } return false; }, set(value) { const checked = []; if (value) { this.users.forEach((user) => { checked.push(user.id); }); } this.selected = checked; } }, } });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="app"> <h4>User</h4> <div> <table> <tr> <th><input type="checkbox" v-model="selectAll"></th> <th align="left">Name</th> </tr> <tr v-for="user in users"> <td> <input type="checkbox" v-model="selected" :value="user.id" number> </td> <td>{{ user.name }}</td> </tr> </table> </div> </div>

I want to thank everyone for sharing their solutions.我要感谢大家分享他们的解决方案。 It has been a big help with learning.对学习有很大帮助。 A developer on gitter helped me to add a Default checkbox that will select a subset of the array that has a property called "default" set to true. gitter 上的开发人员帮助我添加了一个默认复选框,该复选框将选择数组的一个子集,该子集具有一个名为“default”的属性设置为 true。

here is the code:这是代码:

 // based on https://jsfiddle.net/okv0rgrk/3747/ new Vue({ el: '#app', data: { selected: [], defaultSelects: [], selectsArray: [ {id: 'automotive', name: 'Automotive', class: 'industry', default: false}, {id: 'beauty', name: 'Beauty', class: 'industry', default: true}, {id: 'branding', name: 'Branding', class: 'industry', default: true}, {id: 'btob', name: 'B to B', class: 'industry', default: false} ], selected: [], }, computed: { defaultChecked: { get () { let defaults = this.selectsArray.filter(item => item.default).map(item => item.id) const hasAllItems = (baseArr, haystack) => haystack.every(item => baseArr.includes(item)) const hasSameItems = (baseArr, haystack) => hasAllItems(baseArr, haystack) && hasAllItems(haystack, baseArr) return hasSameItems(this.selected, defaults) }, set (value) { this.selected = [] if (value) { this.selectsArray.forEach((select) => { if (select.default) { this.selected.push(select.id) } }); } } }, // END defaultChecked selectAll: { get () { return this.selected.length === this.selectsArray.length }, set (value) { this.selected = [] if (value) { this.selectsArray.forEach((select) => { this.selected.push(select.id) }) } } }, // END selectAll } })
 <script src="https://cdn.jsdelivr.net/vue/latest/vue.js"></script> <div id="app"> <div id="default-settings"> <label class="pref-button"><input type="checkbox" v-model="defaultChecked"><span>Default</span></label> <label class="pref-button"><input type="checkbox" v-model="selectAll"><span>Select All</span></label> </div> <label :for="select.id" v-for="select in selectsArray" v-bind:key="select.id"><input :value="select.id" v-model="selected" :id="select.id" :sector="select.id" :class="select.class" :default="select.default" type="checkbox">{{ select.name }}</label> <span>Selected Ids: {{ selected }}</span> </div>

All you have to do is add your users, using their ID since that's how you're referencing their values with the checkbox, and add them into your selected array.您所要做的就是使用他们的 ID 添加您的用户,因为这就是您使用复选框引用他们的值的方式,并将它们添加到您选择的数组中。

selectAll: function() {
    this.selected = [];
    for (user in this.users) {
        this.selected.push(this.users[user].id);
    }
}

Running JSFiddle运行 JSFiddle

i think this could be a little bit easier.我认为这可能会更容易一些。

selectAll: function (isSelected) {
  if (!isSelected) {
    this.ids = []
    return false
  }
  if (isSelected) {
    this.rows.map(item => this.ids.push(item.id))
  }
}

I have a more simple solution as following and it has all you want.我有一个更简单的解决方案,如下所示,它有你想要的一切。 The real data should be put into a map indexed the name as the label of checkbox for future easy to access.真实数据应放入以名称为索引的地图中,作为复选框的标签,以方便将来访问。

<template>
  <div align="left">
    <div>
      <input type="checkbox" id="all" :checked="allNamesSelected" @click="selectAll()">
      <label for="all">All</label>
    </div>
    <div v-for="(name) in names" :key="name">
      <input type="checkbox" :id="name" :value="name" :check="isChecked(name)" v-model="selectedNames">
      <label :for="name">{{name}}</label>
    </div>
  </div>
</template>

<script>
export default {
    data() {
        return {
            names: ['Automotive', 'Beauty', 'Branding', 'B to B'],
            selectedNames: [],
        }; 
    },
    computed: {
        allNamesSelected() {
            return this.names.length == this.selectedNames.length;
        },
    },
    methods: {
        selectAll() {
            if (this.allNamesSelected) {
                this.selectedNames = [];
            } else {
                this.selectedNames = this.names.slice();
            }
        },
        isChecked(name) {
            return this.selectedNames.includes(name);
        }
    }
}
</script>

Often there is no need to display selected IDs below the table.通常不需要在表格下方显示选定的 ID。 In such cases the above code can be simplified to:在这种情况下,上面的代码可以简化为:

HTML HTML

<div id="app">
    <h4>Users</h4>
    <div>
        <table>
            <tr>
                <th>Name</th>
                <th>Select <input type="checkbox" v-model="selectAll"></th>
            </tr>
            <tr v-for="user in users">
                <td>{{ user.name }}</td>
                <td><input type="checkbox" :value="user.id" :checked="selectAll"></td>
            </tr>
        </table>
    </div>
</div>

VueJs VueJs

new Vue({
    el: '#app',
    data: {
        users: [ 
            { "id": "1", "name": "Shad Jast", "email": "pfeffer.matt@yahoo.com"}, 
            { "id": "2", "name": "Duane Metz", "email": "mohammad.ferry@yahoo.com"}, 
            { "id": "3", "name": "Myah Kris", "email": "evolkman@hotmail.com"}, 
            { "id": "4", "name": "Dr. Kamron Wunsch", "email": "lenora95@leannon.com"}, 
            { "id": "5", "name": "Brendon Rogahn", "email": "verlie.buckridge@yahoo.com"}
        ],
        selectAll: false
    }
})

Here is the simplest solution with v-models and computed only.这是使用v-models且仅计算的最简单的解决方案。 No additional arrays, @click, :checked needed.不需要额外的数组、@click、:checked

HTML HTML

<div id="app">
   <input type="checkbox" v-model="allSelected"> Select All

   <ul>
      <li v-for="user in users">
         <input type="checkbox" v-model="user.selected"> {{ user.name }}
      </li>
   </ul>

   <button @click="getSelectedUsers">Get Selected Users</button>
</div>

JS JS

new Vue({
  el: "#app",
  data: {
    users: [
      {
        id: 1,
        name: "Alda Myrrhine",
        selected: false,
      },
      {
        id: 2,
        name: "Amrita Rabi",
        selected: false,
      },
      {
        id: 3,
        name: "Ruza Alannah",
        selected: false,
      },
    ]
  },
  computed: {
    allSelected: {
      set (selected) {
        this.users.forEach(function (user) {
          user.selected = selected;
        });
      },
      get () {
        return this.users.every(function (user) {
          return user.selected;
        });
      }
    }
  },
  methods: {
    getSelectedUsers () {
      let users = this.users.filter((user) => {
        return user.selected;
      });
      
      console.log(users);
    }
  }
})

Note that you need property user.selected to exist from beginning (for example if you load data from API or elsewhere).请注意,您需要属性user.selected从一开始就存在(例如,如果您从 API 或其他地方加载数据)。

Working example: https://jsfiddle.net/y8gujf2p/工作示例: https ://jsfiddle.net/y8gujf2p/

In my case, it helped me就我而言,它帮助了我

    <template>
  <div class="container">
    <ul class="list-group pt-1">
      <li class="list-group-item align-center">
        <button data-bs-toggle="collapse" data-bs-target="#dat_input" aria-expanded="false" aria-controls="income-expense" class="btn btn-sm border border-dark">
          Yana
        </button>
        <nuxt-link :to="`/admin/question/excel/create`" class="btn btn-success btn-sm">Excel orqali test qo'shish</nuxt-link>
        <span class="float-end">
          <button type="button" accesskey="1" class="btn btn-green btn-sm ">1 kunlik</button>
          <nuxt-link :to="`/admin/question`" class="btn btn-danger btn-sm " accesskey="b">Orqaga</nuxt-link>
        </span>
      </li>
      <li id="dat_input" class="list-group-item collapse">
        <p>Bu yerga endi biror nima qo`shiladi</p>
      </li>
    </ul>
    <div class="card mt-1">
      <table class="table table-sm">
        <thead class="table-dark table-sm">
        <tr>
          <th scope="col" class="text-center">
            <input class="form-check-input" type="checkbox" @click="selectAll(this, $event)">
          </th>
          <th scope="col" class="text-center"><i class="bi bi-sort-numeric-down-alt"></i></th>
          <th scope="col" class="text-center"><i class="bi bi-calendar3"></i></th>
          <th scope="col" class="float-left">Savol</th>
          <th scope="col" class="float-left">To'g'ri javob</th>
          <th scope="col" class="text-center"><i class="bi bi-alarm"></i></th>
          <th scope="col" class="text-center"><i class="bi bi-cash"></i></th>
          <th scope="col" class="text-center"><i class="bi bi-person-plus"></i></th>
          <th scope="col" style="width: 7%; text-align: center;"><i class="bi bi-diagram-3"></i></th>
        </tr>
        </thead>
        <tbody>
        <tr v-for="(question, id) in questions">
          <td width="1%" class="text-center align-middle">
            <input class="form-check-input" type="checkbox" @click="checkbox($event, question.id)">
          </td>
          <td width="3%" class="text-center align-middle" v-text="question.id"></td>
          <td width="8%" class="text-center  align-middle" v-text="question.create"></td>
          <td class="float-left  align-middle">{{ question.question }} <i class="bi bi-arrow-right"></i></td>
          <td class="float-left  align-middle" v-text="question.answer[0]"></td>
          <td width="1%" class="text-center align-middle" v-text="question.time"></td>
          <td width="1%" class="text-center align-middle"> {{ question.money }}</td>
          <td width="1%" class="text-center align-middle"> {{ question.rating }}</td>
          <td width="8%" class="text-center align-middle">
            <nuxt-link :to="`/admin/question/view/${question.id}`" class="btn btn-success btn-sm padingkichkina"><i class="bi bi-eye"></i></nuxt-link>
            <nuxt-link :to="`/admin/question/edit/${question.id}`" class="btn btn-primary btn-sm padingkichkina"><i class="bi bi-pencil"></i></nuxt-link>
            <a class="btn btn-outline-danger align-middle btn-sm padingkichkina" @click="deleteQuestion(question.id, question.question)"><i class="bi bi-trash"></i></a>
          </td>
        </tr>
        </tbody>
      </table>
    </div>
    <div class="card" v-if="next_page_url !== null">
      <button class="btn btn-success" @click="getPaginateTrade">
        Yana yuklash
      </button>
    </div>
  </div>
</template>
<script>
import Swal from 'sweetalert2'

export default {
  middleware: 'isAdmin',
  data() {
    return {
      questions: [],
      success: false,
      next_page_url: null,
      selected: [],
      isCheckAll: false,
    }
  },
  mounted() {
    this.$loading.show()
    this.getQuestions()
  },
  methods: {
    async getQuestions() {
      this.$axios.get('auth/questionsexcel')
        .then((res) => {
          this.questions = res.data.data.data;
          if (res.data.next_page_url !== null) {
            this.next_page_url = res.data.data.next_page_url
          }
        }).catch((error) => {
        this.has_error = true
        console.log(error.response.data.message)
      });
      this.$loading.hide();
    },
    async getPaginateTrade() {
      this.$axios.get(`${this.next_page_url}`)
        .then((res) => {
          if (res.data.next_page_url !== null) {
            this.next_page_url = res.data.data.next_page_url
            const questions = this.questions;
            this.questions = questions.concat(res.data.data.data)
          } else {
            this.SwalMixin("Boshqa savollar qolmadi", 'error')
          }
        }).catch((error) => {
        this.has_error = true
        console.log(error.response.data.message)
      });
    },
    checkbox(event, id) {
      this.isCheckAll = !this.isCheckAll;
      let array = this.selected;
      if (event.target.checked) {
        this.selected = array.concat(id);
      } else {
        this.selected = array.filter(item => item !== id);
      }
    },
    selectAll(bx, event) {
      var cbs = document.getElementsByTagName('input'), i = 0;
      if (event.target.checked) {
        this.selected = this.questions.map(item => item.id);
        for (i; i < cbs.length; i++) {
          if (cbs[i].type == 'checkbox') {
            cbs[i].checked = true;
          }
        }
      } else {
        this.selected = [];
        for (i; i < cbs.length; i++) {
          if (cbs[i].type == 'checkbox') {
            cbs[i].checked = false;
          }
        }
      }
    },
    deleteQuestion(id, name) {
      Swal.fire({
        title: "O'chirasizmi?",
        html: `<b>${name}</b> ni o'chirmoqchimisiz?`,
        icon: 'warning',
        showCancelButton: true,
        confirmButtonColor: '#3085d6',
        cancelButtonColor: '#d33',
        confirmButtonText: "Ha o'chiraman",
        cancelButtonText: "Yo'q hozir emas"
      }).then((result) => {
        if (result.isConfirmed) {
          this.$axios.post('auth/deleteQuestion', {
            id: id
          }).then((response) => {
            this.SwalMixin(response.data.data.message)
            this.getQuestions()
          }).catch((error) => {
            this.SwalMixin(error.response.data.message, 'error')
          });
        }
      })
    },
  }
}
</script>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM