DEV Community

Daniel P πŸ‡¨πŸ‡¦
Daniel P πŸ‡¨πŸ‡¦

Posted on • Updated on

 

How to create a Vuetify data table that has only some expandable rows

Uses vuetify v2.0.0

To make only some of the items expandable use the data-table-expand slot. The slot provides the following props.

{
  item: any
  select: (v: boolean) => void
  isSelected: boolean
  expand: (v: boolean) => void
  isExpanded: boolean
  headers: TableHeader[]
}
Enter fullscreen mode Exit fullscreen mode

Using the item object and the expand function, you can add custom expend functionality.

<template>
  <v-data-table
    :headers="myHeaders"
    :items="myItems"
    :single-expand="true"
    show-expand
  >
    <!-- expand column -->
    <template v-slot:item.data-table-expand="{ item, isExpanded, expand }">
      <v-btn @click="expand(true)" v-if="item.canExpand && !isExpanded">Expand</v-btn>
      <v-btn @click="expand(false)" v-if="item.canExpand && isExpanded">close</v-btn>
    </template>

    <!-- expand item/row -->
    <template v-slot:expanded-item="{ headers, item }">
      <td :colspan="headers.length">
        <pre>{{item}}</pre>
      </td>
    </template>
  </v-data-table>
</template>
Enter fullscreen mode Exit fullscreen mode

The items objects use a canExpand boolean for determining if it can be expanded.

Vuetify, by default adds a text-start class to the expand td element. To change alignment, update the header object for that column, by adding an align property.

Available values are: 'start' | 'center' | 'end'

The expand column is always first though, If you want to make it last, you need to add a custom column.

steps:

  1. Remove the show-expand prop from v-data-table, we're no longer using it.

  2. Add :expanded.sync="expanded" prop to the data table, and a expanded:[] variable to your component data.

  3. Add a new column { text: '', value: 'expand', align:'end' }, to myHeaders.

  4. Add a row slot for the new column. Because the row slot does not provide a expand function, you need to use the expanded variable to toggle selection.

<template v-slot:item.expand="{ item }">
  <v-btn x-small @click="expanded = [item]" v-if="item.canExpand && !expanded.includes(item)">compare</v-btn>
  <v-btn x-small @click="expanded = []" v-if="item.canExpand && expanded.includes(item)">close</v-btn>
</template>
Enter fullscreen mode Exit fullscreen mode

More info here: https://vuetifyjs.com/en/components/data-tables#api

Top comments (4)

Collapse
 
plekleft profile image
Pavel Levin
Collapse
 
wwwolfgang profile image
Wwwolfgang

Do you have a solution for this problem? Im realy interested to be able to expand rows conditionaly.

Collapse
 
jonahbranch profile image
Jonah Branch

Yes. Use the above codepen and add a "canExpand" attribute to each item, and a v-if="item.canExpand" to the expand button

Collapse
 
dwweb0309 profile image
dwweb0309

Great Article!

An Animated Guide to Node.js Event Loop

Node.js doesn’t stop from running other operations because of Libuv, a C++ library responsible for the event loop and asynchronously handling tasks such as network requests, DNS resolution, file system operations, data encryption, etc.

What happens under the hood when Node.js works on tasks such as database queries? We will explore it by following this piece of code step by step.