I am trying to render a v-data-table with a "panel" title as the expandable section of a v-data-table, and would like the data inside the expansion to align with the headers that I have set on the root. So far, I have found no way in the Vuetify documentation or in trial and error to do this, I have had to resort to putting the headers inside the expansion for alignment. This will work as a secondary option, but I just know there has to be a way to do the first.
I am trying to match what would be in this image:enter image description here
The code for what I have for the headers inside the expansion is as follows:
`<template>
<v-data-table
:headers="panelHeaders"
:items="panels"
item-key="panel"
show-expand
:expanded.sync="expandedItems"
>
<template v-slot:[`item.panel`]="{ item }">
{{ item.panel }}
</template>
<template v-slot:expanded-item="{ headers, item }">
<td :colspan="headers.length">
<v-data-table
:headers="expandedPanelHeaders"
:items="item.vendors"
>
<v-row v-for="(expandedVendor, vendorIndex) in item.vendors" :key="vendorIndex">
<template v-slot:item="{ item }">
<td>
<p>notes here</p>
</td>
<td>
<span>{{ expandedVendor.name }}</span>
</td>
<td>
<span>{{ expandedVendor.status }}</span>
</td>
<td>
<span>{{ expandedVendor.distance }}</span>
</td>
<td>
<span>{{ expandedVendor.on_time }}</span>
</td>
<td>
<v-chip-group column>
<v-chip
v-for="(tag, tagIndex) in expandedVendor.vendor_tags"
:key="tagIndex"
:color="tag.color"
>
{{ tag.tag }}
</v-chip>
</v-chip-group>
</td>
<td>
<v-btn>Assign</v-btn>
</td>
</template>
</v-row>
</v-data-table>
</td>
</template>
</v-data-table>
</template>
<script lang="ts">
import { defineComponent, ref } from '@vue/composition-api'
import { order } from '@/plugins/order/Order'
import { PanelData } from "@/types";
/**
* @name AssignPanels
*
*/
export default defineComponent({
props:{
panels: {
default: () => [],
type: Array as () => PanelData[]
}
},
setup() {
const panelHeaders = ref([
{ text: 'Panel', value: 'panel', sortable: false, align: 'start'},
])
const expandedPanelHeaders = ref([
{text: 'Notes', sortable: false, value: 'notes'},
{text: 'Name', sortable: false, value: 'name'},
{text: 'Assign Status', sortable: false, value: 'assign_status'},
{text: 'Distance', sortable: false, value: 'distance'},
{text: 'On-Time %', sortable: false, value: 'on_time'},
{text: 'Tags', sortable: false, value: 'tags'},
{text: 'Assign', sortable: false, value: 'assign_action'},
])
const expandedItems = ref([])
return {
panelHeaders,
expandedPanelHeaders,
expandedItems,
order,
}
},
})
</script>
`
Any help or advice would be greatly appreciated, I am fairly new to front end development and am eager to find a better way to do this.
Hmm, closest option is probably to use grouping.
Override the default group header to remove the button that undoes grouping.
However, there is no way to close groups initially.
new Vue({
el: '#app',
vuetify: new Vuetify(),
template: `
<v-app>
<v-main>
<v-container>
<v-data-table
:headers="headers"
:items="items"
group-by="panel"
mobile-breakpoint="0"
:expanded="[]"
>
<template #group.header="{group, groupBy, toggle, isOpen, headers}">
<td :colspan="headers.length">
<v-btn icon @click="toggle">
<v-icon>mdi-{{isOpen ? 'minus' : 'plus'}}</v-icon>
</v-btn>
Custom Panel {{group}}
</td>
</template>
</v-data-table>
</v-container>
</v-main>
</v-app>
`,
data(){
return {
headers: [
{text: 'Panel', value: 'panel'},
{text: 'Notes', value: 'notes'},
{text: 'Name', value: 'name'},
],
items: Array.from({length: 10}, (_,i) => ({
id: i,
name: 'Han Solo',
panel: i/3|0,
notes: Math.random()*20|0,
}))
}
}
})
<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/font@6.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet">
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script>