CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-tabulator-tables

Interactive table generation JavaScript library with sorting, filtering, editing, formatting, and extensive customization capabilities

Pending
Overview
Eval results
Files

data-sorting.mddocs/

Data Sorting

Multi-column sorting with custom sort functions and dynamic sort management for organizing table data.

Capabilities

Sort Configuration

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();

Built-in Sorters

Standard Sorters

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: "."
    }
  }
];

Custom Sorters

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;
    }
  }
];

Sort Configuration Options

Header Sorting

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;
}

Initial Sorting

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);
});

Advanced Sorting Patterns

Multi-level Sorting

// 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 Sorting

// 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 Events and Callbacks

// 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");
    }
  }
});

Performance Optimization

// 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

docs

cell-editing.md

clipboard.md

column-management.md

data-management.md

data-sorting.md

data-trees.md

event-system.md

filtering-search.md

history-undo.md

import-export.md

index.md

pagination.md

range-selection.md

row-grouping.md

table-construction.md

validation.md

tile.json