[Feature Request] VDataTable should provide a possibility to control groups open/close from outside
Problem to solve
I tried to convert a grouped List to a DataTable which also supports grouping. But it is not possible to access the opened group list.
Proposed solution
Similar like in List providing v-model:open
~I believe that is what the expanded prop is for, but so far I can't get it working.~
@hackel I think expanded state is not related with grouping. It is used to display an additional row of information.
I agree. I want to auto-expand the groups by default (which Vuetify 2 did). Related to #17707. Take this example data:
const items = [
{ id: 1, name: 'Alice', age: 30, group: 'Group A' },
{ id: 2, name: 'Bob', age: 25, group: 'Group B' },
// More items...
];
And the example table:
<v-data-table
:items="items"
:group-by="[{ key: 'group' }]"
> ... </v-data-table>
If I want to expand all the groups, I have no way of doing this. The group-header slot (and others) expose a toggleGroup function. This is exactly what we want, just available outside of the template, for example in the mounted hook.
I stumbled upon this problem today...
Inspired by Chris' answer and the Group header slot example, I came up with the code below:
We initially save the properties we need in the groupHeaders object.
Then we replicate the current group header functionality of Vuetify.
<template #group-header="{ item, columns, toggleGroup, isGroupOpen }">
<template :ref="(el) => { this.groupHeaders[item.value] = { item, toggleGroup, isGroupOpen } }" />
<tr>
<td :colspan="columns.length">
<v-btn
:icon="isGroupOpen(item) ? '$expand' : '$next'"
size="small"
variant="text"
@click="toggleGroup(item)"
/>
{{ item.value }} ({{ item.items.length }})
</td>
</tr>
</template>
Now we can toggle one or more groups when we need them (e.g. onMounted):
Either on a specific group header by filtering OUR_VALUE:
const headerToToggle = this.groupHeaders[OUR_VALUE]
headerToToggle?.toggleGroup(headerToToggle.item)
Or on all group headers massively:
Object.values(this.groupHeaders).forEach((header) => {
header.toggleGroup(header.item))
})
EDIT: A bit of refactoring for better results.
@crazyrabbit0
this only works on visible rows. I have a table with multiple nested groups and the ones off-screen (nested or root) are ignored. I tried both v-data-table-virtual and v-data-table with :items-per-page="-1"
Interesting, can you share your code to check what went wrong ?