0
# Row Grouping
1
2
Advanced row grouping functionality for organizing table data into hierarchical groups with collapsible sections, group headers, and aggregation support.
3
4
## Capabilities
5
6
### Group Configuration
7
8
Configure table grouping by field, starting state, and header generation.
9
10
```javascript { .api }
11
/**
12
* Set the field to group rows by
13
* @param groupBy - Field name or array of field names for multi-level grouping
14
*/
15
setGroupBy(groupBy: string | string[]): void;
16
17
/**
18
* Set which group values are allowed
19
* @param values - Array of values or function returning allowed values
20
*/
21
setGroupValues(values: any[] | Function): void;
22
23
/**
24
* Set the default open/closed state for groups
25
* @param open - Boolean, function, or array defining open state
26
*/
27
setGroupStartOpen(open: boolean | Function | boolean[]): void;
28
29
/**
30
* Set group header generation function
31
* @param generator - Function or array of functions for multi-level headers
32
*/
33
setGroupHeader(generator: Function | Function[]): void;
34
```
35
36
**Configuration Options:**
37
38
```javascript { .api }
39
interface GroupingOptions {
40
groupBy?: string | string[];
41
groupStartOpen?: boolean | Function | boolean[];
42
groupValues?: any[] | Function;
43
groupUpdateOnCellEdit?: boolean;
44
groupHeader?: Function | Function[];
45
groupHeaderPrint?: Function | Function[];
46
groupHeaderClipboard?: Function | Function[];
47
groupHeaderHtmlOutput?: Function | Function[];
48
groupHeaderDownload?: Function | Function[];
49
groupToggleElement?: "arrow" | string;
50
groupClosedShowCalcs?: boolean;
51
}
52
```
53
54
### Group Data Retrieval
55
56
Access group data and structure information.
57
58
```javascript { .api }
59
/**
60
* Get all groups in the table
61
* @param active - Return only visible groups
62
* @returns Array of GroupComponent objects
63
*/
64
getGroups(active?: boolean): GroupComponent[];
65
66
/**
67
* Get data structured by groups
68
* @param active - Include only visible groups
69
* @returns Grouped data structure
70
*/
71
getGroupedData(active?: boolean): any[];
72
```
73
74
### Row Group Access
75
76
Access group information from row components.
77
78
```javascript { .api }
79
// Added to RowComponent by GroupRows module
80
/**
81
* Get the group this row belongs to
82
* @returns GroupComponent or false if not grouped
83
*/
84
getGroup(): GroupComponent | false;
85
```
86
87
**Usage Examples:**
88
89
```javascript
90
import { Tabulator } from "tabulator-tables";
91
92
// Basic grouping
93
const table = new Tabulator("#table", {
94
data: [
95
{ name: "Alice", department: "Engineering", salary: 75000 },
96
{ name: "Bob", department: "Engineering", salary: 85000 },
97
{ name: "Charlie", department: "Sales", salary: 65000 },
98
{ name: "Diana", department: "Sales", salary: 70000 }
99
],
100
columns: [
101
{ title: "Name", field: "name" },
102
{ title: "Department", field: "department" },
103
{ title: "Salary", field: "salary", formatter: "money" }
104
],
105
groupBy: "department",
106
groupStartOpen: true,
107
groupHeader: function(value, count, data, group) {
108
return `${value} <span style="color:#d00;">(${count} employees)</span>`;
109
}
110
});
111
112
// Multi-level grouping
113
table.setGroupBy(["department", "level"]);
114
table.setGroupHeader([
115
function(value, count) { return `Department: ${value} (${count})`; },
116
function(value, count) { return `Level: ${value} (${count})`; }
117
]);
118
119
// Dynamic grouping
120
table.setGroupBy("status");
121
table.setGroupStartOpen(function(value, count, data, group) {
122
// Open groups with more than 5 items
123
return count > 5;
124
});
125
126
// Access group data
127
const groups = table.getGroups();
128
groups.forEach(group => {
129
console.log(`Group: ${group.getKey()}, Rows: ${group.getRows().length}`);
130
});
131
132
// Get grouped data structure
133
const groupedData = table.getGroupedData();
134
console.log(groupedData);
135
```
136
137
## GroupComponent Class
138
139
Component class representing a data group with methods for group manipulation and data access.
140
141
```javascript { .api }
142
class GroupComponent {
143
/**
144
* Get the group key/value
145
* @returns The value that defines this group
146
*/
147
getKey(): any;
148
149
/**
150
* Get the field name this group is organized by
151
* @returns Field name
152
*/
153
getField(): string;
154
155
/**
156
* Get the DOM element for this group
157
* @returns Group header element
158
*/
159
getElement(): HTMLElement;
160
161
/**
162
* Get all rows in this group
163
* @returns Array of RowComponent objects
164
*/
165
getRows(): RowComponent[];
166
167
/**
168
* Get sub-groups (for multi-level grouping)
169
* @returns Array of GroupComponent objects
170
*/
171
getSubGroups(): GroupComponent[];
172
173
/**
174
* Get parent group (for multi-level grouping)
175
* @returns Parent GroupComponent or false if top-level
176
*/
177
getParentGroup(): GroupComponent | false;
178
179
/**
180
* Check if group is visible
181
* @returns True if group is visible
182
*/
183
isVisible(): boolean;
184
185
/**
186
* Show/expand the group
187
*/
188
show(): void;
189
190
/**
191
* Hide/collapse the group
192
*/
193
hide(): void;
194
195
/**
196
* Toggle group visibility
197
*/
198
toggle(): void;
199
}
200
```
201
202
**Advanced Usage Examples:**
203
204
```javascript
205
// Group header with calculations
206
const table = new Tabulator("#table", {
207
groupBy: "department",
208
groupHeader: function(value, count, data, group) {
209
// Calculate average salary for group
210
const avgSalary = data.reduce((sum, row) => sum + row.salary, 0) / count;
211
return `${value} - ${count} employees (Avg: $${avgSalary.toFixed(0)})`;
212
},
213
groupToggleElement: "header", // Make entire header clickable
214
groupClosedShowCalcs: true // Show calculations even when closed
215
});
216
217
// Conditional group values
218
table.setGroupValues(function(data) {
219
// Only group active employees
220
return data.filter(row => row.active).map(row => row.department);
221
});
222
223
// Access specific group
224
const groups = table.getGroups();
225
const engineeringGroup = groups.find(group => group.getKey() === "Engineering");
226
if (engineeringGroup) {
227
console.log(`Engineering has ${engineeringGroup.getRows().length} employees`);
228
229
// Access sub-groups in multi-level grouping
230
const subGroups = engineeringGroup.getSubGroups();
231
subGroups.forEach(subGroup => {
232
console.log(` ${subGroup.getField()}: ${subGroup.getKey()}`);
233
});
234
}
235
236
// Update grouping dynamically
237
document.getElementById("group-by-dept").addEventListener("click", () => {
238
table.setGroupBy("department");
239
});
240
241
document.getElementById("group-by-level").addEventListener("click", () => {
242
table.setGroupBy(["department", "level"]);
243
});
244
```
245
246
## Types
247
248
```javascript { .api }
249
interface GroupHeaderFunction {
250
(value: any, count: number, data: any[], group: GroupComponent): string;
251
}
252
253
interface GroupStartOpenFunction {
254
(value: any, count: number, data: any[], group: GroupComponent): boolean;
255
}
256
257
interface GroupValuesFunction {
258
(data: any[]): any[];
259
}
260
```