Skip to content

feat(VDataTable): add v-model:opened for group-by#22772

Draft
J-Sek wants to merge 1 commit intodevfrom
feat/vdatatable-open-groups
Draft

feat(VDataTable): add v-model:opened for group-by#22772
J-Sek wants to merge 1 commit intodevfrom
feat/vdatatable-open-groups

Conversation

@J-Sek
Copy link
Copy Markdown
Contributor

@J-Sek J-Sek commented Mar 27, 2026

resolves #22300
resolves #17707

Adds two-way binding support external control over opened groups.

Affects VDataTable, VDataTableServer, VDataTableVirtual, VDataIterator

New props

  • opened (string[]) — array of open group IDs. Supports v-model:opened.
  • open-all-groups (boolean) — opens all groups initially. Individual groups can still be toggled.
  • group-key - accepts custom function to generate group IDs. parentKey is null for top-level groups.
<template>
  <v-app theme="dark">
    <v-container>
      <h2 class="mb-4">VDataTable v-model:opened</h2>

      <div class="d-flex ga-4 mb-4 align-center">
        <v-switch v-model="openAll" label="openAllGroups" hide-details />
        <v-btn variant="tonal" @click="opened = []">Close all</v-btn>
        <v-btn variant="tonal" @click="opened = someGroupIds">Open manual</v-btn>
      </div>

      <pre class="mb-4 pa-2 bg-surface-variant rounded">opened: {{ opened }}</pre>

      <v-data-table
        v-model:opened="opened"
        :items="items"
        :headers="headers"
        :group-by="groupBy"
        :group-key="({ value, parentKey }) => [parentKey, value].filter(Boolean).join('|')"
        item-value="name"
        :open-all-groups="openAll"
        page-by="auto"
        :items-per-page="3"
        :items-per-page-options="[3, 6]"
        show-select
      />
    </v-container>
  </v-app>
</template>

<script setup lang="ts">
  import { ref } from 'vue'

  const opened = ref<string[]>([])
  const openAll = ref(false)

  const groupBy = ref([{ key: 'category' }, { key: 'origin' }])

  const headers = [
    { title: 'Name', key: 'name' },
    { title: 'Calories', key: 'calories' },
    { title: 'Category', key: 'category' },
    { title: 'Origin', key: 'origin' },
  ]

  const items = [
    { name: 'Frozen Yogurt', calories: 159, category: 'Dairy', origin: 'USA' },
    { name: 'Ice cream sandwich', calories: 237, category: 'Dairy', origin: 'USA' },
    { name: 'Milk', calories: 120, category: 'Dairy', origin: 'USA' },
    { name: 'Cheese', calories: 402, category: 'Dairy', origin: 'France' },
    { name: 'Butter', calories: 717, category: 'Dairy', origin: 'France' },
    { name: 'Cream cheese', calories: 342, category: 'Dairy', origin: 'USA' },
    { name: 'Whipped cream', calories: 257, category: 'Dairy', origin: 'France' },
    { name: 'Brie', calories: 334, category: 'Dairy', origin: 'France' },
    { name: 'Eclair', calories: 262, category: 'Pastry', origin: 'France' },
    { name: 'Cupcake', calories: 305, category: 'Pastry', origin: 'USA' },
    { name: 'Croissant', calories: 231, category: 'Pastry', origin: 'France' },
    { name: 'Danish', calories: 290, category: 'Pastry', origin: 'Denmark' },
    { name: 'Strudel', calories: 274, category: 'Pastry', origin: 'Austria' },
    { name: 'Baklava', calories: 334, category: 'Pastry', origin: 'Turkey' },
    { name: 'Cannoli', calories: 369, category: 'Pastry', origin: 'Italy' },
    { name: 'Gingerbread', calories: 356, category: 'Cookie', origin: 'Germany' },
    { name: 'Oreo', calories: 160, category: 'Cookie', origin: 'USA' },
    { name: 'Shortbread', calories: 502, category: 'Cookie', origin: 'UK' },
    { name: 'Macaron', calories: 404, category: 'Cookie', origin: 'France' },
    { name: 'Biscotti', calories: 410, category: 'Cookie', origin: 'Italy' },
    { name: 'Snickerdoodle', calories: 380, category: 'Cookie', origin: 'USA' },
    { name: 'Stroopwafel', calories: 390, category: 'Cookie', origin: 'Netherlands' },
    { name: 'KitKat', calories: 518, category: 'Candy', origin: 'UK' },
    { name: 'Jelly bean', calories: 375, category: 'Candy', origin: 'USA' },
    { name: 'Lollipop', calories: 392, category: 'Candy', origin: 'USA' },
    { name: 'Skittles', calories: 231, category: 'Candy', origin: 'UK' },
    { name: 'Snickers', calories: 488, category: 'Candy', origin: 'USA' },
    { name: 'Twix', calories: 502, category: 'Candy', origin: 'UK' },
    { name: 'M&Ms', calories: 480, category: 'Candy', origin: 'USA' },
    { name: 'Haribo', calories: 340, category: 'Candy', origin: 'Germany' },
    { name: 'Toblerone', calories: 525, category: 'Candy', origin: 'Switzerland' },
    { name: 'Brownie', calories: 466, category: 'Cake', origin: 'USA' },
    { name: 'Cheesecake', calories: 321, category: 'Cake', origin: 'USA' },
    { name: 'Tiramisu', calories: 283, category: 'Cake', origin: 'Italy' },
    { name: 'Red velvet', calories: 367, category: 'Cake', origin: 'USA' },
    { name: 'Carrot cake', calories: 415, category: 'Cake', origin: 'UK' },
    { name: 'Panna cotta', calories: 222, category: 'Cake', origin: 'Italy' },
    { name: 'Sachertorte', calories: 362, category: 'Cake', origin: 'Austria' },
    { name: 'Mochi', calories: 130, category: 'Confection', origin: 'Japan' },
    { name: 'Daifuku', calories: 220, category: 'Confection', origin: 'Japan' },
    { name: 'Turkish delight', calories: 350, category: 'Confection', origin: 'Turkey' },
    { name: 'Nougat', calories: 400, category: 'Confection', origin: 'France' },
    { name: 'Marzipan', calories: 458, category: 'Confection', origin: 'Germany' },
    { name: 'Praline', calories: 520, category: 'Confection', origin: 'Belgium' },
    { name: 'Churro', calories: 237, category: 'Fried', origin: 'Spain' },
    { name: 'Donut', calories: 452, category: 'Fried', origin: 'USA' },
    { name: 'Beignet', calories: 390, category: 'Fried', origin: 'France' },
    { name: 'Funnel cake', calories: 560, category: 'Fried', origin: 'USA' },
    { name: 'Zeppole', calories: 420, category: 'Fried', origin: 'Italy' },
  ]

  const someGroupIds = [
    'Dairy',
    'Dairy|France',
    'Pastry',
    'Pastry|France',
    'Cookie',
  ]
</script>

@J-Sek J-Sek force-pushed the feat/vdatatable-open-groups branch from 1901339 to 03c05f5 Compare March 27, 2026 22:52
@J-Sek J-Sek changed the base branch from master to dev March 27, 2026 22:52
@J-Sek J-Sek self-assigned this Mar 27, 2026
@J-Sek J-Sek force-pushed the feat/vdatatable-open-groups branch from 03c05f5 to 4efc5c9 Compare March 27, 2026 22:55
@J-Sek J-Sek force-pushed the feat/vdatatable-open-groups branch from 4efc5c9 to df4c2e7 Compare March 27, 2026 23:19
@J-Sek J-Sek force-pushed the dev branch 2 times, most recently from 5b257fd to 86800d9 Compare March 29, 2026 00:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

1 participant