0
# Data Sorting
1
2
Multi-column sorting with custom sort functions and dynamic sort management for organizing table data.
3
4
## Capabilities
5
6
### Sort Configuration
7
8
Methods for setting and managing table sorting behavior.
9
10
```javascript { .api }
11
/**
12
* Set table sorting configuration
13
* @param sorters - Single sorter or array of sorter objects
14
*/
15
setSort(sorters: SorterParams | SorterParams[]): void;
16
17
/**
18
* Get current active sorters
19
* @returns Array of active sorter objects
20
*/
21
getSorters(): SorterParams[];
22
23
/**
24
* Clear all sorting from table
25
*/
26
clearSort(): void;
27
28
interface SorterParams {
29
/** Column field to sort by */
30
column: string;
31
/** Sort direction */
32
dir: "asc" | "desc";
33
/** Additional sorter parameters */
34
params?: any;
35
}
36
```
37
38
**Usage Examples:**
39
40
```javascript
41
// Single column sort
42
table.setSort("name", "asc");
43
44
// Multiple column sort
45
table.setSort([
46
{ column: "department", dir: "asc" },
47
{ column: "name", dir: "asc" },
48
{ column: "age", dir: "desc" }
49
]);
50
51
// Get current sorting
52
const currentSort = table.getSorters();
53
console.log("Current sort:", currentSort);
54
55
// Clear all sorting
56
table.clearSort();
57
```
58
59
## Built-in Sorters
60
61
### Standard Sorters
62
63
Tabulator provides built-in sorters for common data types.
64
65
```javascript { .api }
66
type BuiltInSorters =
67
| "string" // String comparison
68
| "number" // Numeric comparison
69
| "alphanum" // Alphanumeric sorting (A1, A2, A10, A20)
70
| "boolean" // Boolean values
71
| "exists" // Existence check (defined values first)
72
| "date" // Date comparison
73
| "time" // Time comparison
74
| "datetime" // DateTime comparison
75
| "array" // Array length comparison
76
| "currency"; // Currency value comparison
77
78
interface SorterConfig {
79
/** Sorter type or custom function */
80
sorter?: BuiltInSorters | Function | boolean;
81
/** Parameters for sorter */
82
sorterParams?: {
83
/** Format for date/time parsing */
84
format?: string;
85
/** Locale for string comparison */
86
locale?: string;
87
/** Alignment for alphanum */
88
alignEmptyValues?: "top" | "bottom";
89
/** Currency symbol */
90
symbol?: string;
91
/** Decimal separator */
92
decimal?: string;
93
/** Thousands separator */
94
thousand?: string;
95
};
96
}
97
```
98
99
**Usage Examples:**
100
101
```javascript
102
// Column definitions with sorters
103
const sortableColumns = [
104
{
105
title: "Name",
106
field: "name",
107
sorter: "string",
108
sorterParams: { locale: "en" }
109
},
110
{
111
title: "Code",
112
field: "code",
113
sorter: "alphanum" // Handles A1, A2, A10 correctly
114
},
115
{
116
title: "Age",
117
field: "age",
118
sorter: "number"
119
},
120
{
121
title: "Active",
122
field: "active",
123
sorter: "boolean"
124
},
125
{
126
title: "Start Date",
127
field: "startDate",
128
sorter: "date",
129
sorterParams: { format: "DD/MM/YYYY" }
130
},
131
{
132
title: "Salary",
133
field: "salary",
134
sorter: "currency",
135
sorterParams: {
136
symbol: "$",
137
thousand: ",",
138
decimal: "."
139
}
140
}
141
];
142
```
143
144
### Custom Sorters
145
146
Create custom sorting logic for specialized data types.
147
148
```javascript { .api }
149
interface CustomSorter {
150
/**
151
* Custom sort comparison function
152
* @param a - First value to compare
153
* @param b - Second value to compare
154
* @param aRow - First row component
155
* @param bRow - Second row component
156
* @param column - Column component
157
* @param dir - Sort direction
158
* @param sorterParams - Sorter parameters
159
* @returns Comparison result (-1, 0, 1)
160
*/
161
(
162
a: any, b: any,
163
aRow: RowComponent, bRow: RowComponent,
164
column: ColumnComponent, dir: string,
165
sorterParams: any
166
): number;
167
}
168
```
169
170
**Usage Examples:**
171
172
```javascript
173
// Custom priority sorter
174
function prioritySorter(a, b, aRow, bRow, column, dir, sorterParams) {
175
const priorityOrder = { "high": 3, "medium": 2, "low": 1 };
176
const aVal = priorityOrder[a] || 0;
177
const bVal = priorityOrder[b] || 0;
178
179
return aVal - bVal;
180
}
181
182
// Custom date range sorter
183
function dateRangeSorter(a, b, aRow, bRow, column, dir, sorterParams) {
184
const parseDate = (dateStr) => {
185
if (!dateStr) return new Date(0);
186
return new Date(dateStr);
187
};
188
189
const aDate = parseDate(a);
190
const bDate = parseDate(b);
191
192
return aDate.getTime() - bDate.getTime();
193
}
194
195
// Use custom sorters in columns
196
const customSortColumns = [
197
{
198
title: "Priority",
199
field: "priority",
200
sorter: prioritySorter
201
},
202
{
203
title: "Project Duration",
204
field: "duration",
205
sorter: function(a, b) {
206
// Parse duration strings like "2d 3h"
207
const parseHours = (duration) => {
208
const days = (duration.match(/(\d+)d/) || [0, 0])[1] * 24;
209
const hours = (duration.match(/(\d+)h/) || [0, 0])[1];
210
return parseInt(days) + parseInt(hours);
211
};
212
213
return parseHours(a) - parseHours(b);
214
}
215
},
216
{
217
title: "Version",
218
field: "version",
219
sorter: function(a, b) {
220
// Sort semantic versions like "1.2.3"
221
const parseVersion = (version) => {
222
return version.split('.').map(v => parseInt(v) || 0);
223
};
224
225
const aVer = parseVersion(a);
226
const bVer = parseVersion(b);
227
228
for (let i = 0; i < Math.max(aVer.length, bVer.length); i++) {
229
const diff = (aVer[i] || 0) - (bVer[i] || 0);
230
if (diff !== 0) return diff;
231
}
232
return 0;
233
}
234
}
235
];
236
```
237
238
## Sort Configuration Options
239
240
### Header Sorting
241
242
Configure sorting behavior for column headers.
243
244
```javascript { .api }
245
interface HeaderSortConfig {
246
/** Enable header click sorting */
247
headerSort?: boolean;
248
/** Enable tristate sorting (asc -> desc -> none) */
249
headerSortTristate?: boolean;
250
/** Starting sort direction for new sorts */
251
headerSortStartingDir?: "asc" | "desc";
252
/** Reverse sort order */
253
sortOrderReverse?: boolean;
254
}
255
```
256
257
### Initial Sorting
258
259
Set default sorting when table is first loaded.
260
261
```javascript { .api }
262
interface InitialSortConfig {
263
/** Initial sort configuration */
264
initialSort?: SorterParams[];
265
/** Sort order reverse */
266
sortOrderReverse?: boolean;
267
}
268
```
269
270
**Usage Examples:**
271
272
```javascript
273
// Table with initial sorting
274
const sortedTable = new Tabulator("#sorted-table", {
275
data: tableData,
276
columns: columnDefinitions,
277
initialSort: [
278
{ column: "department", dir: "asc" },
279
{ column: "name", dir: "asc" }
280
],
281
headerSort: true,
282
headerSortTristate: true,
283
sortOrderReverse: false
284
});
285
286
// Dynamic sort updates
287
sortedTable.on("dataSorted", function(sorters, rows) {
288
console.log(`Data sorted by ${sorters.length} column(s)`);
289
console.log("Sort order:", sorters);
290
291
// Update UI to show current sort
292
updateSortIndicators(sorters);
293
});
294
```
295
296
## Advanced Sorting Patterns
297
298
### Multi-level Sorting
299
300
```javascript { .api }
301
// Complex multi-level sorting
302
table.setSort([
303
{ column: "region", dir: "asc" },
304
{ column: "department", dir: "asc" },
305
{ column: "performance", dir: "desc" },
306
{ column: "seniority", dir: "desc" },
307
{ column: "name", dir: "asc" }
308
]);
309
310
// Programmatic sort management
311
function addSortLevel(field, direction) {
312
const currentSort = table.getSorters();
313
314
// Remove existing sort for this field
315
const filteredSort = currentSort.filter(s => s.column !== field);
316
317
// Add new sort level
318
filteredSort.push({ column: field, dir: direction });
319
320
table.setSort(filteredSort);
321
}
322
```
323
324
### Conditional Sorting
325
326
```javascript { .api }
327
// Conditional sort based on data types
328
function smartSorter(a, b, aRow, bRow, column, dir, sorterParams) {
329
// Handle null/undefined values
330
if (a == null && b == null) return 0;
331
if (a == null) return 1;
332
if (b == null) return -1;
333
334
// Auto-detect data type and sort accordingly
335
if (!isNaN(a) && !isNaN(b)) {
336
return parseFloat(a) - parseFloat(b);
337
}
338
339
if (Date.parse(a) && Date.parse(b)) {
340
return new Date(a) - new Date(b);
341
}
342
343
// Default string comparison
344
return a.toString().localeCompare(b.toString());
345
}
346
347
// Use conditional sorter
348
{
349
title: "Mixed Data",
350
field: "mixedValue",
351
sorter: smartSorter
352
}
353
```
354
355
### Sort Events and Callbacks
356
357
```javascript { .api }
358
// Sort event handling
359
table.on("dataSorting", function(sorters) {
360
console.log("About to sort data by:", sorters);
361
showLoadingIndicator();
362
});
363
364
table.on("dataSorted", function(sorters, rows) {
365
console.log("Data sorted successfully");
366
console.log(`${rows.length} rows in new order`);
367
hideLoadingIndicator();
368
369
// Save sort preferences
370
localStorage.setItem("tableSortPrefs", JSON.stringify(sorters));
371
});
372
373
// Restore saved sort preferences
374
table.on("tableBuilt", function() {
375
const savedSort = localStorage.getItem("tableSortPrefs");
376
if (savedSort) {
377
try {
378
const sorters = JSON.parse(savedSort);
379
table.setSort(sorters);
380
} catch (e) {
381
console.warn("Could not restore sort preferences");
382
}
383
}
384
});
385
```
386
387
### Performance Optimization
388
389
```javascript { .api }
390
// Optimize sorting for large datasets
391
const performantSortTable = new Tabulator("#large-sort-table", {
392
data: largeDataset,
393
columns: columnDefinitions,
394
395
// Use pagination to reduce sort overhead
396
pagination: true,
397
paginationSize: 100,
398
paginationMode: "local",
399
400
// Virtual DOM for rendering performance
401
virtualDom: true,
402
virtualDomBuffer: 50,
403
404
// Efficient initial sort
405
initialSort: [{ column: "id", dir: "asc" }],
406
407
// Debounce rapid sort changes
408
sortMode: "local"
409
});
410
411
// Custom sort caching for expensive calculations
412
const expensiveSortCache = new Map();
413
414
function cachedCustomSort(a, b, aRow, bRow, column, dir, sorterParams) {
415
const cacheKey = `${a}-${b}`;
416
417
if (expensiveSortCache.has(cacheKey)) {
418
return expensiveSortCache.get(cacheKey);
419
}
420
421
// Expensive calculation here
422
const result = expensiveCalculation(a, b);
423
424
expensiveSortCache.set(cacheKey, result);
425
return result;
426
}
427
```