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>
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)
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)