Select all rows of a Vuetify data table with custom table body implementation

skuallpa picture skuallpa · Aug 27, 2019 · Viewed 12.9k times · Source

I can't figure how to implement the select all option for my data-table using Vuetify v2 when I have a custom implementation for the slot body.

Here is a little example:

<template>
  <v-card
    max-width="300"
    class="pa-6"
  >
    <v-data-table
      :items="tasks"
      :headers="headers"
      show-select
      dense
    >
      <template v-slot:body="{ items }">
        <tbody>
          <tr
            v-for="item in items"
            :key="item.id"
          >
            <td>
              <v-checkbox
                v-model="selectedTasks"
                :value="item.id"
                style="margin:0px;padding:0px"
                hide-details
              />
            </td>
            <td>{{ item.text }}</td>
            <td>
              <v-btn
                text
                icon
                x-small
              >
                <v-icon>pageview</v-icon>
              </v-btn>
            </td>
          </tr>
        </tbody>
      </template>
    </v-data-table>
  </v-card>
</template>
<script>
export default {
  data() {
    return {
      headers: [
        { text: 'task', value: 'text' },
        { text: 'actions' }
      ],
      selectedTasks: []
    }
  },
  computed: {
    tasks() {
      return [
        { id: 1, text: 'Collect packets' },
        { id: 2, text: 'Buy bread' }
      ]
    }
  }
}
</script>

Which produces the following data table:

enter image description here

Now I want to implement that when the checkbox "all" is selected (like above in the picture), it selects all the rows of my table.

The doc says to implement the slot header.data-table-select to customise the select all button, and I could find the example below in the examples about slots for the data-table.

<template v-slot:header.data-table-select="{ on , props }">
    <v-simple-checkbox
       color="purple"
       v-bind="props"
       v-on="on"
    />
</template>

However, I can't make it to select all the rows when I check this box. I didn't find any example on how to implement the select all with a "custom" table body. Hopefully, someone can help me here. Thanks in advance

Answer

Edin Omeragic picture Edin Omeragic · Aug 27, 2019

Data table v-model needs to be set to selectedItems and check box for selecting needs to have value of item collection.

<!DOCTYPE html>
<html>

<head>
  <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
  <link href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
</head>

<body>
  <div id="app">
    <v-app>
      <v-content>
        <v-container>
          <h2>Data Table</h2>

          <v-data-table v-model="selectedTasks" :headers="headers" :items="tasks" item-key="id" show-select>

            <template v-slot:body="{ items }">
            <tbody>
                <tr v-for="item in items" :key="item.id">
                    <td>
                        <v-checkbox v-model="selectedTasks" :value="item" style="margin:0px;padding:0px"
                            hide-details />
                    </td>
                    <td>{{ item.text }}</td>
                    <td>
                        <v-btn text icon x-small>
                            Edit
                        </v-btn>
                    </td>
                </tr>
            </tbody>
            </template>
          </v-data-table>
        </v-container>
      </v-content>
    </v-app>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script>
  <script>
    new Vue({
      el: '#app',
      vuetify: new Vuetify(),

      data() {
        return {
          headers: [{
              text: 'task',
              value: 'text'
            },
            {
              text: 'actions'
            }
          ],
          selectedTasks: []
        }
      },
      computed: {
        tasks() {
          return [{
              id: 1,
              text: 'Collect packets'
            },
            {
              id: 2,
              text: 'Buy bread'
            }
          ]
        }
      }
    })
  </script>
</body>

</html>