Skip to content

Grouping Basics

By default, grouping in Pantanal Grid is disabled. To enable grouping, set the groupable prop to true. This will render a drop zone above the grid header where you can drag column headers to group the data by that column.

Drag column headers to the drop zone above the grid to group by that column. You can group by multiple columns and reorder groups by dragging the badges.

Drag a column header here to group by that column
Product Name
Unit Price
Category
Discontinued
Chai
$18.00
Beverages
false
Chef Anton
$22.00
Beverages
false
Chef Gumbo Mix
$21.35
Dairy Products
true
Boysenberry Spread
$25.00
Condiments
false
Alice Mutton
$39.00
Meat/Poultry
true
Aniseed Syrup
$10.00
Condiments
false

Basic Example

vue
<script setup lang="ts">
import { ref } from 'vue'
import { PantanalGrid, type ColumnDef } from '@pantanal/grid'

const rows = ref([
  {
    ProductID: 1,
    ProductName: 'Chai',
    UnitPrice: 18,
    UnitsInStock: 39,
    Discontinued: false,
    Category: 'Beverages'
  },
  {
    ProductID: 4,
    ProductName: 'Chef Anton',
    UnitPrice: 22,
    UnitsInStock: 53,
    Discontinued: false,
    Category: 'Beverages'
  },
  {
    ProductID: 5,
    ProductName: 'Chef Gumbo Mix',
    UnitPrice: 21.35,
    UnitsInStock: 0,
    Discontinued: true,
    Category: 'Dairy Products'
  },
  {
    ProductID: 6,
    ProductName: 'Boysenberry Spread',
    UnitPrice: 25,
    UnitsInStock: 120,
    Discontinued: false,
    Category: 'Condiments'
  }
])

const columns: ColumnDef[] = [
  { field: 'ProductName', title: 'Product Name', width: 180 },
  { field: 'UnitPrice', title: 'Unit Price', width: 120, format: (v: number) => `$${v.toFixed(2)}` },
  { field: 'Category', title: 'Category', width: 180 },
  { field: 'Discontinued', title: 'Discontinued', width: 120 }
]
</script>

<template>
  <PantanalGrid
    :rows="rows"
    :columns="columns"
    groupable
    key-field="ProductID"
    locale="en"
  />
</template>

How It Works

  1. Enable Grouping: Set groupable to true on the Grid component
  2. Drag Column Headers: Click and drag any column header to the drop zone above the grid
  3. Multiple Groups: You can group by multiple columns by dragging additional column headers
  4. Reorder Groups: Drag group badges within the drop zone to reorder the grouping hierarchy
  5. Remove Groups: Click the × button on a group badge to remove that grouping

Column-Level Control

You can disable grouping for specific columns by setting groupable: false on the column definition:

Notice that "Unit Price" column cannot be dragged to the drop zone because it has groupable: false.

Drag a column header here to group by that column
Product Name
Unit Price
Category
Discontinued
Chai
$18.00
Beverages
false
Chef Anton
$22.00
Beverages
false
Chef Gumbo Mix
$21.35
Dairy Products
true
Boysenberry Spread
$25.00
Condiments
false
vue
const columns: ColumnDef[] = [
  { field: 'ProductName', title: 'Product Name', width: 180 },
  { field: 'UnitPrice', title: 'Unit Price', width: 120, groupable: false }, // Cannot be grouped
  { field: 'Category', title: 'Category', width: 180 },
]

Group Direction

Groups are sorted in ascending order by default. The group direction is indicated by an arrow (↑ for ascending, ↓ for descending) in the group badge.

Multiple Groups Example

You can group by multiple columns by dragging additional column headers to the drop zone. The order of groups determines the hierarchy:

Drag "Category" first, then drag "Brand" to create nested groups (Category → Brand).

Drag a column header here to group by that column
Product Name
Category
Brand
Price
Stock
Product A
Electronics
Brand X
$29.99
150
Product B
Electronics
Brand X
$49.99
75
Product C
Electronics
Brand Y
$19.99
200
Product D
Clothing
Brand X
$39.99
50
Product E
Clothing
Brand Z
$59.99
100
Product F
Accessories
Brand X
$14.99
200
vue
<script setup lang="ts">
import { ref } from 'vue'
import { PantanalGrid, type ColumnDef } from '@pantanal/grid'

const rows = ref([
  { id: 1, name: 'Product A', category: 'Electronics', brand: 'Brand X', price: 29.99, stock: 150 },
  { id: 2, name: 'Product B', category: 'Electronics', brand: 'Brand X', price: 49.99, stock: 75 },
  { id: 3, name: 'Product C', category: 'Electronics', brand: 'Brand Y', price: 19.99, stock: 200 },
  { id: 4, name: 'Product D', category: 'Clothing', brand: 'Brand X', price: 39.99, stock: 50 },
  { id: 5, name: 'Product E', category: 'Clothing', brand: 'Brand Z', price: 59.99, stock: 100 },
  { id: 6, name: 'Product F', category: 'Accessories', brand: 'Brand X', price: 14.99, stock: 200 }
])

const columns: ColumnDef[] = [
  { field: 'name', title: 'Product Name', width: 200 },
  { field: 'category', title: 'Category', width: 150 },
  { field: 'brand', title: 'Brand', width: 150 },
  { field: 'price', title: 'Price', width: 120, format: (v: number) => `$${v.toFixed(2)}` },
  { field: 'stock', title: 'Stock', width: 100 }
]
</script>

<template>
  <PantanalGrid
    :rows="rows"
    :columns="columns"
    groupable
    key-field="id"
    locale="en"
    :height="400"
  />
</template>

Try it: Drag "Category" first, then drag "Brand" to create nested groups (Category → Brand).

Initial Grouping with Drag-and-Drop

You can set initial groups programmatically while still allowing users to modify them via drag-and-drop:

The grid starts with initial grouping by category. You can still drag columns to add more groups or remove existing ones.

Category
Product Name
Category
Brand
Price
Category: Clothing
Category: Electronics
vue
<script setup lang="ts">
import { ref } from 'vue'
import { PantanalGrid, type ColumnDef, type GroupDescriptor } from '@pantanal/grid'

const rows = ref([
  { id: 1, name: 'Product A', category: 'Electronics', brand: 'Brand X', price: 29.99 },
  { id: 2, name: 'Product B', category: 'Electronics', brand: 'Brand Y', price: 49.99 },
  { id: 3, name: 'Product C', category: 'Clothing', brand: 'Brand X', price: 19.99 },
  { id: 4, name: 'Product D', category: 'Clothing', brand: 'Brand Z', price: 39.99 }
])

const columns: ColumnDef[] = [
  { field: 'name', title: 'Product Name', width: 200 },
  { field: 'category', title: 'Category', width: 150 },
  { field: 'brand', title: 'Brand', width: 150 },
  { field: 'price', title: 'Price', width: 120, format: (v: number) => `$${v.toFixed(2)}` }
]

// Start with initial grouping by category
const group = ref<GroupDescriptor[]>([
  { field: 'category', dir: 'asc' }
])
</script>

<template>
  <PantanalGrid
    :rows="rows"
    :columns="columns"
    groupable
    :group="group"
    key-field="id"
    locale="en"
  />
</template>

Users can still drag columns to add more groups or remove existing ones.

Listening to Group Changes

You can listen to group changes when users modify groups via drag-and-drop:

Group changes are tracked. Check the console or the info below the grid.

Current grouping: No groups applied
Drag a column header here to group by that column
Product Name
Category
Brand
Price
Product A
Electronics
Brand X
$29.99
Product B
Electronics
Brand Y
$49.99
Product C
Clothing
Brand X
$19.99
Product D
Clothing
Brand Z
$39.99
vue
<script setup lang="ts">
import { ref } from 'vue'
import { PantanalGrid, type ColumnDef, type GroupDescriptor } from '@pantanal/grid'

const rows = ref([
  { id: 1, name: 'Product A', category: 'Electronics', brand: 'Brand X', price: 29.99 },
  { id: 2, name: 'Product B', category: 'Electronics', brand: 'Brand Y', price: 49.99 },
  { id: 3, name: 'Product C', category: 'Clothing', brand: 'Brand X', price: 19.99 }
])

const columns: ColumnDef[] = [
  { field: 'name', title: 'Product Name', width: 200 },
  { field: 'category', title: 'Category', width: 150 },
  { field: 'brand', title: 'Brand', width: 150 },
  { field: 'price', title: 'Price', width: 120, format: (v: number) => `$${v.toFixed(2)}` }
]

const group = ref<GroupDescriptor[]>([])

function handleGroupChange(newGroup: GroupDescriptor[]) {
  group.value = newGroup
  console.log('Group changed:', newGroup)
  // You can save to localStorage, send to server, etc.
}
</script>

<template>
  <PantanalGrid
    :rows="rows"
    :columns="columns"
    groupable
    :group="group"
    @update:group="handleGroupChange"
    key-field="id"
    locale="en"
  />
</template>

Disabling Grouping for Specific Columns

Prevent certain columns from being grouped by setting groupable: false:

Try dragging columns. Notice that "ID" and "Price" columns cannot be dragged to the drop zone because they have groupable: false.

Drag a column header here to group by that column
ID
Product Name
Category
Price
Brand
1
Product A
Electronics
$29.99
Brand X
2
Product B
Electronics
$49.99
Brand Y
3
Product C
Clothing
$19.99
Brand X
4
Product D
Clothing
$39.99
Brand Z
vue
<script setup lang="ts">
const columns: ColumnDef[] = [
  { field: 'id', title: 'ID', width: 80, groupable: false }, // Cannot be grouped
  { field: 'name', title: 'Product Name', width: 200 },
  { field: 'category', title: 'Category', width: 150 },
  { field: 'price', title: 'Price', width: 120, format: (v: number) => `$${v.toFixed(2)}`, groupable: false }, // Cannot be grouped
  { field: 'brand', title: 'Brand', width: 150 }
]
</script>

Columns with groupable: false won't be draggable to the drop zone.