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

row-grouping.mddocs/

Row Grouping

Advanced row grouping functionality for organizing table data into hierarchical groups with collapsible sections, group headers, and aggregation support.

Capabilities

Group Configuration

Configure table grouping by field, starting state, and header generation.

/**
 * Set the field to group rows by
 * @param groupBy - Field name or array of field names for multi-level grouping
 */
setGroupBy(groupBy: string | string[]): void;

/**
 * Set which group values are allowed 
 * @param values - Array of values or function returning allowed values
 */
setGroupValues(values: any[] | Function): void;

/**
 * Set the default open/closed state for groups
 * @param open - Boolean, function, or array defining open state
 */
setGroupStartOpen(open: boolean | Function | boolean[]): void;

/**
 * Set group header generation function
 * @param generator - Function or array of functions for multi-level headers
 */
setGroupHeader(generator: Function | Function[]): void;

Configuration Options:

interface GroupingOptions {
  groupBy?: string | string[];
  groupStartOpen?: boolean | Function | boolean[];
  groupValues?: any[] | Function;
  groupUpdateOnCellEdit?: boolean;
  groupHeader?: Function | Function[];
  groupHeaderPrint?: Function | Function[];
  groupHeaderClipboard?: Function | Function[];
  groupHeaderHtmlOutput?: Function | Function[];
  groupHeaderDownload?: Function | Function[];
  groupToggleElement?: "arrow" | string;
  groupClosedShowCalcs?: boolean;
}

Group Data Retrieval

Access group data and structure information.

/**
 * Get all groups in the table
 * @param active - Return only visible groups
 * @returns Array of GroupComponent objects
 */
getGroups(active?: boolean): GroupComponent[];

/**
 * Get data structured by groups
 * @param active - Include only visible groups
 * @returns Grouped data structure
 */
getGroupedData(active?: boolean): any[];

Row Group Access

Access group information from row components.

// Added to RowComponent by GroupRows module
/**
 * Get the group this row belongs to
 * @returns GroupComponent or false if not grouped
 */
getGroup(): GroupComponent | false;

Usage Examples:

import { Tabulator } from "tabulator-tables";

// Basic grouping
const table = new Tabulator("#table", {
  data: [
    { name: "Alice", department: "Engineering", salary: 75000 },
    { name: "Bob", department: "Engineering", salary: 85000 },
    { name: "Charlie", department: "Sales", salary: 65000 },
    { name: "Diana", department: "Sales", salary: 70000 }
  ],
  columns: [
    { title: "Name", field: "name" },
    { title: "Department", field: "department" },
    { title: "Salary", field: "salary", formatter: "money" }
  ],
  groupBy: "department",
  groupStartOpen: true,
  groupHeader: function(value, count, data, group) {
    return `${value} <span style="color:#d00;">(${count} employees)</span>`;
  }
});

// Multi-level grouping
table.setGroupBy(["department", "level"]);
table.setGroupHeader([
  function(value, count) { return `Department: ${value} (${count})`; },
  function(value, count) { return `Level: ${value} (${count})`; }
]);

// Dynamic grouping
table.setGroupBy("status");
table.setGroupStartOpen(function(value, count, data, group) {
  // Open groups with more than 5 items
  return count > 5;
});

// Access group data
const groups = table.getGroups();
groups.forEach(group => {
  console.log(`Group: ${group.getKey()}, Rows: ${group.getRows().length}`);
});

// Get grouped data structure
const groupedData = table.getGroupedData();
console.log(groupedData);

GroupComponent Class

Component class representing a data group with methods for group manipulation and data access.

class GroupComponent {
  /**
   * Get the group key/value
   * @returns The value that defines this group
   */
  getKey(): any;
  
  /**
   * Get the field name this group is organized by
   * @returns Field name
   */
  getField(): string;
  
  /**
   * Get the DOM element for this group
   * @returns Group header element
   */
  getElement(): HTMLElement;
  
  /**
   * Get all rows in this group
   * @returns Array of RowComponent objects
   */
  getRows(): RowComponent[];
  
  /**
   * Get sub-groups (for multi-level grouping)
   * @returns Array of GroupComponent objects
   */
  getSubGroups(): GroupComponent[];
  
  /**
   * Get parent group (for multi-level grouping)
   * @returns Parent GroupComponent or false if top-level
   */
  getParentGroup(): GroupComponent | false;
  
  /**
   * Check if group is visible
   * @returns True if group is visible
   */
  isVisible(): boolean;
  
  /**
   * Show/expand the group
   */
  show(): void;
  
  /**
   * Hide/collapse the group
   */
  hide(): void;
  
  /**
   * Toggle group visibility
   */
  toggle(): void;
}

Advanced Usage Examples:

// Group header with calculations
const table = new Tabulator("#table", {
  groupBy: "department",
  groupHeader: function(value, count, data, group) {
    // Calculate average salary for group
    const avgSalary = data.reduce((sum, row) => sum + row.salary, 0) / count;
    return `${value} - ${count} employees (Avg: $${avgSalary.toFixed(0)})`;
  },
  groupToggleElement: "header", // Make entire header clickable
  groupClosedShowCalcs: true // Show calculations even when closed
});

// Conditional group values
table.setGroupValues(function(data) {
  // Only group active employees
  return data.filter(row => row.active).map(row => row.department);
});

// Access specific group
const groups = table.getGroups();
const engineeringGroup = groups.find(group => group.getKey() === "Engineering");
if (engineeringGroup) {
  console.log(`Engineering has ${engineeringGroup.getRows().length} employees`);
  
  // Access sub-groups in multi-level grouping
  const subGroups = engineeringGroup.getSubGroups();
  subGroups.forEach(subGroup => {
    console.log(`  ${subGroup.getField()}: ${subGroup.getKey()}`);
  });
}

// Update grouping dynamically
document.getElementById("group-by-dept").addEventListener("click", () => {
  table.setGroupBy("department");
});

document.getElementById("group-by-level").addEventListener("click", () => {
  table.setGroupBy(["department", "level"]);
});

Types

interface GroupHeaderFunction {
  (value: any, count: number, data: any[], group: GroupComponent): string;
}

interface GroupStartOpenFunction {
  (value: any, count: number, data: any[], group: GroupComponent): boolean;
}

interface GroupValuesFunction {
  (data: any[]): any[];
}

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