web-dev-qa-db-fra.com

Cochez toutes les cases à cocher

J'affiche une liste d'utilisateurs dans une table, chaque ligne a une case à cocher pour sélectionner l'utilisateur et la valeur de case à cocher est l'ID de l'utilisateur. Les identifiants sélectionnés sont à leur tour affichés dans une étendue au-dessous du tableau.

Comment puis-je sélectionner toutes les cases à cocher et désélectionner toutes les cases au clic d'une case à cocher "Tout sélectionner" dans l'en-tête de ma table? Est-ce que j'interagis avec le DOM pour faire ceci ou par le biais de l'objet vue, je pense que ce devrait être le dernier mais je ne sais pas trop comment aborder ce qui semble être une tâche facile?! Toute aide serait appréciée!

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

new Vue({
    el: '#app',
    data: {
        users: [ 
            { "id": "1", "name": "Shad Jast", "email": "[email protected]", 
            { "id": "2", "name": "Duane Metz", "email": "[email protected]"}, 
            { "id": "3", "name": "Myah Kris", "email": "[email protected]"}, 
            { "id": "4", "name": "Dr. Kamron Wunsch", "email": "[email protected]"}, 
            { "id": "5", "name": "Brendon Rogahn", "email": "[email protected]"}
        ],
        selected: []
    },
    methods: {
        selectAll: function() {
            // ?
        }
    }
})
16
haakym

L'ajout de ma propre réponse en tant que modifications sur la réponse de nhydock n'a pas été accepté (je pense?).

La solution sélectionne et sélectionne tout.

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

new Vue({
    el: '#app',
    data: {
        users: [ 
            { "id": "1", "name": "Shad Jast", "email": "[email protected]"}, 
            { "id": "2", "name": "Duane Metz", "email": "[email protected]"}, 
            { "id": "3", "name": "Myah Kris", "email": "[email protected]"}, 
            { "id": "4", "name": "Dr. Kamron Wunsch", "email": "[email protected]"}, 
            { "id": "5", "name": "Brendon Rogahn", "email": "[email protected]"}
        ],
        selected: [],
        allSelected: false,
        userIds: []
    },
    methods: {
        selectAll: function() {
            this.userIds = [];

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

Travail du violon: https://jsfiddle.net/okv0rgrk/3747/

5
haakym

Je pense que la réponse de @ Jeremy est plus claire, mais elle nécessite la propriété checked sur chaque objet utilisateur, ce qui n'a aucun sens si les données proviennent d'une demande d'API.

Voici un code de travail et de nettoyage pour sélectionner/désélectionner toutes les lignes sans avoir à ajouter la propriété checked sur l'objet utilisateur:

new Vue({
    el: '#app',
    data: {
        users: [ 
            { "id": "1", "name": "Shad Jast", "email": "[email protected]" },
            { "id": "2", "name": "Duane Metz", "email": "[email protected]" }, 
            { "id": "3", "name": "Myah Kris", "email": "[email protected]" }, 
            { "id": "4", "name": "Dr. Kamron Wunsch", "email": "[email protected]" }
        ],
        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>

Veuillez noter que l'attribut number sur la case à cocher de la ligne est obligatoire, sinon vous devez pousser la méthode id utilisateur selectAll en tant que chaîne, comme selected.Push(user.id.toString());

33
Rifki

Que diriez-vous de ma réponse, avec moins de propriétés, facile à comprendre?

new Vue({
  el: '#app',
  data: {
    users: [{
      "id": "1",
      "name": "Shad Jast",
      "email": "[email protected]",
      'checked': false
    }, {
      "id": "2",
      "name": "Duane Metz",
      "email": "[email protected]",
      'checked': false
    }, {
      "id": "3",
      "name": "Myah Kris",
      "email": "[email protected]",
      'checked': false
    }, {
      "id": "4",
      "name": "Dr. Kamron Wunsch",
      "email": "[email protected]",
      '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>

5
Jeremy

Je tiens à remercier tout le monde d'avoir partagé leurs solutions. Cela a beaucoup aidé à apprendre. Un développeur de gitter m'a aidé à ajouter une case à cocher par défaut permettant de sélectionner un sous-ensemble du tableau ayant une propriété appelée "par défaut" définie sur true.

voici le 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>

2
jh-thank-you

Tout ce que vous avez à faire est d’ajouter vos utilisateurs, en utilisant leur ID puisque c’est ainsi que vous faites référence à leurs valeurs avec la case à cocher, et les ajouter à votre tableau sélectionné.

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

Exécuter JSFiddle

1
nhydock

je pense que cela pourrait être un peu plus facile.

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