Vuetify Data Table Expand Row on Column Click
Asked Answered
M

2

5

I have a vuetify data table that includes expandable rows. The only real difference I have from the demo is that I would like the item.name column to open/close the expandable row just like the chevron icon. When I put an @click handler on the v-slot for that column I get the error Error in v-on handler: "TypeError: expand is not a function". This is the only column I need to customize so I would like to not have to build out the entire <tr> v-slot by hand. A scaled-down code example is below. Thanks.

<v-data-table
    :headers="headers"
    :items="products"
    item-key="productCode"
    show-expand
    :expanded.sync="expanded"
>

  <template v-slot:item.name="{ item, expand, isExpanded }" >
    <h4 class="my-2" @click="expand(!isExpanded)">{{ item.name }} located in {{ item.depot | camelToWords }}</h4>
  </template>

  <template v-slot:expanded-item="{ headers, item }">
    <ProductDetailExpandedRow :currentProduct="item" :headers="headers"/>
  </template>

</v-data-table>

<script>
export default {
  data() {
    return {
      headers: [
        {
          text: 'Name',
          value: 'name',
        },
        {
          text: 'Product ID',
          value: 'productCode',
        },
        {
          text: 'Stock',
          value: 'stock',
        },
6 more columns continue on here...
      ],
      products: [],
    }
  }
}
</script>
Maggy answered 9/1, 2021 at 4:54 Comment(0)
W
10

Column click

Here is how you could do it with a specific column click. Put a @click handler in the column's slot template. This handler receives the column data on click. In this case, the column's name is name:

<template v-slot:item.name="slotData">
   <div @click="clickColumn(slotData)">{{ slotData.item.name }}</div>
</template>

Expanded rows are tracked in the expanded array, so add this row's data. But if it's already there, remove it (because then you're trying to collapse an already expanded column)

clickColumn(slotData) {
  const indexRow = slotData.index;
  const indexExpanded = this.expanded.findIndex(i => i === slotData.item);
  if (indexExpanded > -1) {
    this.expanded.splice(indexExpanded, 1)
  } else {
    this.expanded.push(slotData.item);
  }
}

Here is the codepen (Rows expand when clicking the first column, within the padding)

Row click

Here is how you could do it with a row click (i.e. any column). In the template, add a listener to the <v-data-table> for the click:row event:

<v-data-table @click:row="clickRow">
...
</v-data-table>

This event passes two arguments: the item, and the item slot data, including the index of the clicked row. Use this information to modify the this.expanded array which tracks all expanded rows:

clickRow(item, event) {
  if(event.isExpanded) {
    const indexExpanded = this.expanded.findIndex(i => i === item);
    this.expanded.splice(indexExpanded, 1)
  } else {
    this.expanded.push(item);
  }
}

This adds the item to the expanded array or it removes it by finding the index and using splice.

Here is the codepen (Rows expand when clicking anywhere in the row)

Winch answered 9/1, 2021 at 5:41 Comment(2)
Dan, is there a way to hide the "expand" column and caret? I am handling the expand icon myself in one of my defined columns and don't want an extra column in my table.Crossfertilization
@MichaelKurtz You can remove the show-expand attribute in the data table. That might be what you're looking for. Otherwise, try CSS by some td:nth-of-type(n)Winch
K
1

I had problem with manually expand items in table

I had to add id in array like this

data() {
    return {
      expanded: [
        {
          id: "cbfa8ad4-4042-4ffa-b909-e8ce49c11aa0",
        },
        {
          id: "6fb8d2b4-0112-4349-afed-e6a6fbdc24fa",
        },
      ],
Knight answered 18/7, 2022 at 12:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.