Interactive table generation JavaScript library with sorting, filtering, editing, formatting, and extensive customization capabilities
—
Multi-column sorting with custom sort functions and dynamic sort management for organizing table data.
Methods for setting and managing table sorting behavior.
/**
* Set table sorting configuration
* @param sorters - Single sorter or array of sorter objects
*/
setSort(sorters: SorterParams | SorterParams[]): void;
/**
* Get current active sorters
* @returns Array of active sorter objects
*/
getSorters(): SorterParams[];
/**
* Clear all sorting from table
*/
clearSort(): void;
interface SorterParams {
/** Column field to sort by */
column: string;
/** Sort direction */
dir: "asc" | "desc";
/** Additional sorter parameters */
params?: any;
}Usage Examples:
// Single column sort
table.setSort("name", "asc");
// Multiple column sort
table.setSort([
{ column: "department", dir: "asc" },
{ column: "name", dir: "asc" },
{ column: "age", dir: "desc" }
]);
// Get current sorting
const currentSort = table.getSorters();
console.log("Current sort:", currentSort);
// Clear all sorting
table.clearSort();Tabulator provides built-in sorters for common data types.
type BuiltInSorters =
| "string" // String comparison
| "number" // Numeric comparison
| "alphanum" // Alphanumeric sorting (A1, A2, A10, A20)
| "boolean" // Boolean values
| "exists" // Existence check (defined values first)
| "date" // Date comparison
| "time" // Time comparison
| "datetime" // DateTime comparison
| "array" // Array length comparison
| "currency"; // Currency value comparison
interface SorterConfig {
/** Sorter type or custom function */
sorter?: BuiltInSorters | Function | boolean;
/** Parameters for sorter */
sorterParams?: {
/** Format for date/time parsing */
format?: string;
/** Locale for string comparison */
locale?: string;
/** Alignment for alphanum */
alignEmptyValues?: "top" | "bottom";
/** Currency symbol */
symbol?: string;
/** Decimal separator */
decimal?: string;
/** Thousands separator */
thousand?: string;
};
}Usage Examples:
// Column definitions with sorters
const sortableColumns = [
{
title: "Name",
field: "name",
sorter: "string",
sorterParams: { locale: "en" }
},
{
title: "Code",
field: "code",
sorter: "alphanum" // Handles A1, A2, A10 correctly
},
{
title: "Age",
field: "age",
sorter: "number"
},
{
title: "Active",
field: "active",
sorter: "boolean"
},
{
title: "Start Date",
field: "startDate",
sorter: "date",
sorterParams: { format: "DD/MM/YYYY" }
},
{
title: "Salary",
field: "salary",
sorter: "currency",
sorterParams: {
symbol: "$",
thousand: ",",
decimal: "."
}
}
];Create custom sorting logic for specialized data types.
interface CustomSorter {
/**
* Custom sort comparison function
* @param a - First value to compare
* @param b - Second value to compare
* @param aRow - First row component
* @param bRow - Second row component
* @param column - Column component
* @param dir - Sort direction
* @param sorterParams - Sorter parameters
* @returns Comparison result (-1, 0, 1)
*/
(
a: any, b: any,
aRow: RowComponent, bRow: RowComponent,
column: ColumnComponent, dir: string,
sorterParams: any
): number;
}Usage Examples:
// Custom priority sorter
function prioritySorter(a, b, aRow, bRow, column, dir, sorterParams) {
const priorityOrder = { "high": 3, "medium": 2, "low": 1 };
const aVal = priorityOrder[a] || 0;
const bVal = priorityOrder[b] || 0;
return aVal - bVal;
}
// Custom date range sorter
function dateRangeSorter(a, b, aRow, bRow, column, dir, sorterParams) {
const parseDate = (dateStr) => {
if (!dateStr) return new Date(0);
return new Date(dateStr);
};
const aDate = parseDate(a);
const bDate = parseDate(b);
return aDate.getTime() - bDate.getTime();
}
// Use custom sorters in columns
const customSortColumns = [
{
title: "Priority",
field: "priority",
sorter: prioritySorter
},
{
title: "Project Duration",
field: "duration",
sorter: function(a, b) {
// Parse duration strings like "2d 3h"
const parseHours = (duration) => {
const days = (duration.match(/(\d+)d/) || [0, 0])[1] * 24;
const hours = (duration.match(/(\d+)h/) || [0, 0])[1];
return parseInt(days) + parseInt(hours);
};
return parseHours(a) - parseHours(b);
}
},
{
title: "Version",
field: "version",
sorter: function(a, b) {
// Sort semantic versions like "1.2.3"
const parseVersion = (version) => {
return version.split('.').map(v => parseInt(v) || 0);
};
const aVer = parseVersion(a);
const bVer = parseVersion(b);
for (let i = 0; i < Math.max(aVer.length, bVer.length); i++) {
const diff = (aVer[i] || 0) - (bVer[i] || 0);
if (diff !== 0) return diff;
}
return 0;
}
}
];Configure sorting behavior for column headers.
interface HeaderSortConfig {
/** Enable header click sorting */
headerSort?: boolean;
/** Enable tristate sorting (asc -> desc -> none) */
headerSortTristate?: boolean;
/** Starting sort direction for new sorts */
headerSortStartingDir?: "asc" | "desc";
/** Reverse sort order */
sortOrderReverse?: boolean;
}Set default sorting when table is first loaded.
interface InitialSortConfig {
/** Initial sort configuration */
initialSort?: SorterParams[];
/** Sort order reverse */
sortOrderReverse?: boolean;
}Usage Examples:
// Table with initial sorting
const sortedTable = new Tabulator("#sorted-table", {
data: tableData,
columns: columnDefinitions,
initialSort: [
{ column: "department", dir: "asc" },
{ column: "name", dir: "asc" }
],
headerSort: true,
headerSortTristate: true,
sortOrderReverse: false
});
// Dynamic sort updates
sortedTable.on("dataSorted", function(sorters, rows) {
console.log(`Data sorted by ${sorters.length} column(s)`);
console.log("Sort order:", sorters);
// Update UI to show current sort
updateSortIndicators(sorters);
});// Complex multi-level sorting
table.setSort([
{ column: "region", dir: "asc" },
{ column: "department", dir: "asc" },
{ column: "performance", dir: "desc" },
{ column: "seniority", dir: "desc" },
{ column: "name", dir: "asc" }
]);
// Programmatic sort management
function addSortLevel(field, direction) {
const currentSort = table.getSorters();
// Remove existing sort for this field
const filteredSort = currentSort.filter(s => s.column !== field);
// Add new sort level
filteredSort.push({ column: field, dir: direction });
table.setSort(filteredSort);
}// Conditional sort based on data types
function smartSorter(a, b, aRow, bRow, column, dir, sorterParams) {
// Handle null/undefined values
if (a == null && b == null) return 0;
if (a == null) return 1;
if (b == null) return -1;
// Auto-detect data type and sort accordingly
if (!isNaN(a) && !isNaN(b)) {
return parseFloat(a) - parseFloat(b);
}
if (Date.parse(a) && Date.parse(b)) {
return new Date(a) - new Date(b);
}
// Default string comparison
return a.toString().localeCompare(b.toString());
}
// Use conditional sorter
{
title: "Mixed Data",
field: "mixedValue",
sorter: smartSorter
}// Sort event handling
table.on("dataSorting", function(sorters) {
console.log("About to sort data by:", sorters);
showLoadingIndicator();
});
table.on("dataSorted", function(sorters, rows) {
console.log("Data sorted successfully");
console.log(`${rows.length} rows in new order`);
hideLoadingIndicator();
// Save sort preferences
localStorage.setItem("tableSortPrefs", JSON.stringify(sorters));
});
// Restore saved sort preferences
table.on("tableBuilt", function() {
const savedSort = localStorage.getItem("tableSortPrefs");
if (savedSort) {
try {
const sorters = JSON.parse(savedSort);
table.setSort(sorters);
} catch (e) {
console.warn("Could not restore sort preferences");
}
}
});// Optimize sorting for large datasets
const performantSortTable = new Tabulator("#large-sort-table", {
data: largeDataset,
columns: columnDefinitions,
// Use pagination to reduce sort overhead
pagination: true,
paginationSize: 100,
paginationMode: "local",
// Virtual DOM for rendering performance
virtualDom: true,
virtualDomBuffer: 50,
// Efficient initial sort
initialSort: [{ column: "id", dir: "asc" }],
// Debounce rapid sort changes
sortMode: "local"
});
// Custom sort caching for expensive calculations
const expensiveSortCache = new Map();
function cachedCustomSort(a, b, aRow, bRow, column, dir, sorterParams) {
const cacheKey = `${a}-${b}`;
if (expensiveSortCache.has(cacheKey)) {
return expensiveSortCache.get(cacheKey);
}
// Expensive calculation here
const result = expensiveCalculation(a, b);
expensiveSortCache.set(cacheKey, result);
return result;
}Install with Tessl CLI
npx tessl i tessl/npm-tabulator-tables