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-trees.mddocs/

Data Trees

Hierarchical data tree functionality for displaying nested data structures with expandable/collapsible parent-child relationships and custom tree controls.

Capabilities

Tree Configuration

Configure hierarchical data display with parent-child relationships and tree controls.

interface DataTreeOptions {
  dataTree?: boolean;
  dataTreeFilter?: boolean;
  dataTreeSort?: boolean;
  dataTreeElementColumn?: string | false;
  dataTreeBranchElement?: boolean | string | HTMLElement;
  dataTreeChildIndent?: number;
  dataTreeChildField?: string;
  dataTreeCollapseElement?: string | HTMLElement | false;
  dataTreeExpandElement?: string | HTMLElement | false;
  dataTreeStartExpanded?: boolean | Function | boolean[];
  dataTreeChildColumnCalcs?: boolean;
  dataTreeSelectPropagate?: boolean;
}

Row Tree Methods

Tree-specific methods added to RowComponent for managing hierarchical relationships.

// Added to RowComponent by DataTree module
/**
 * Collapse this tree row and hide its children
 */
treeCollapse(): void;

/**
 * Expand this tree row and show its children
 */
treeExpand(): void;

/**
 * Toggle expansion state of this tree row
 */
treeToggle(): void;

/**
 * Get the parent row in the tree hierarchy
 * @returns Parent RowComponent or false if top-level
 */
getTreeParent(): RowComponent | false;

/**
 * Get all direct child rows in the tree
 * @returns Array of child RowComponent objects
 */
getTreeChildren(): RowComponent[];

/**
 * Add a new child row to this tree row
 * @param data - Data for the new child row
 * @param pos - Position to insert (true for top, false for bottom)
 * @param index - Index to insert before
 * @returns Promise resolving to new RowComponent
 */
addTreeChild(data: any, pos?: boolean, index?: any): Promise<RowComponent>;

/**
 * Check if this tree row is currently expanded
 * @returns True if expanded, false if collapsed
 */
isTreeExpanded(): boolean;

Usage Examples:

import { Tabulator } from "tabulator-tables";

// Basic tree structure
const treeData = [
  {
    name: "Engineering",
    employees: 15,
    _children: [
      {
        name: "Frontend Team",
        employees: 8,
        _children: [
          { name: "Alice Johnson", role: "Senior Developer", employees: 1 },
          { name: "Bob Smith", role: "Developer", employees: 1 },
          { name: "Carol White", role: "UI/UX Designer", employees: 1 }
        ]
      },
      {
        name: "Backend Team", 
        employees: 7,
        _children: [
          { name: "David Brown", role: "Tech Lead", employees: 1 },
          { name: "Eve Davis", role: "Senior Developer", employees: 1 },
          { name: "Frank Wilson", role: "DevOps Engineer", employees: 1 }
        ]
      }
    ]
  },
  {
    name: "Sales",
    employees: 12,
    _children: [
      { name: "Grace Miller", role: "Sales Manager", employees: 1 },
      { name: "Henry Taylor", role: "Account Executive", employees: 1 },
      { name: "Ivy Anderson", role: "Sales Rep", employees: 1 }
    ]
  }
];

// Table with tree functionality
const table = new Tabulator("#tree-table", {
  data: treeData,
  columns: [
    {
      title: "Name",
      field: "name",
      width: 300,
      formatter: "plaintext"
    },
    {
      title: "Role/Department", 
      field: "role",
      formatter: function(cell, formatterParams) {
        return cell.getValue() || cell.getRow().getData().name;
      }
    },
    {
      title: "Employees",
      field: "employees",
      width: 100,
      align: "right"
    }
  ],
  dataTree: true,
  dataTreeStartExpanded: true,
  dataTreeChildField: "_children",
  dataTreeChildIndent: 15,
  dataTreeElementColumn: "name"
});

// Programmatic tree operations
const firstRow = table.getRows()[0];

// Collapse a tree row
firstRow.treeCollapse();

// Expand a tree row
firstRow.treeExpand();

// Toggle expansion state
firstRow.treeToggle();

// Check expansion state
if (firstRow.isTreeExpanded()) {
  console.log("Row is expanded");
}

// Get tree relationships
const children = firstRow.getTreeChildren();
console.log(`This row has ${children.length} children`);

children.forEach(child => {
  const parent = child.getTreeParent();
  console.log(`Child row parent: ${parent ? parent.getData().name : 'none'}`);
});

// Add new child
firstRow.addTreeChild({
  name: "Quality Assurance Team",
  employees: 5,
  _children: [
    { name: "Jack Lee", role: "QA Lead", employees: 1 },
    { name: "Kate Green", role: "QA Engineer", employees: 1 }
  ]
});

Tree Configuration Options

Child Field Configuration

Specify which field contains child data in your data structure.

const table = new Tabulator("#table", {
  dataTree: true,
  dataTreeChildField: "_children", // Default field name
  // ... other options
});

// Alternative field names
dataTreeChildField: "children"     // Use "children" field
dataTreeChildField: "subItems"     // Use "subItems" field  
dataTreeChildField: "nested"       // Use "nested" field

Visual Customization

Customize tree appearance with custom elements and indentation.

const table = new Tabulator("#table", {
  dataTree: true,
  dataTreeChildIndent: 20, // Indent child rows by 20px
  dataTreeBranchElement: true, // Show default branch lines
  dataTreeElementColumn: "name", // Column to show tree controls in
  
  // Custom collapse/expand buttons
  dataTreeCollapseElement: "<span>▼</span>",
  dataTreeExpandElement: "<span>▶</span>",
  
  // Custom branch element
  dataTreeBranchElement: "<div class='custom-branch'></div>"
});

Expansion State Management

Control which tree rows start expanded or collapsed.

// All rows start expanded
const table = new Tabulator("#table", {
  dataTree: true,
  dataTreeStartExpanded: true
});

// All rows start collapsed
const table2 = new Tabulator("#table2", {
  dataTree: true,
  dataTreeStartExpanded: false
});

// Conditional expansion using function
const table3 = new Tabulator("#table3", {
  dataTree: true,
  dataTreeStartExpanded: function(row, level) {
    // Expand top-level rows, collapse deeper levels
    return level < 2;
  }
});

// Specific expansion levels using array
const table4 = new Tabulator("#table4", {
  dataTree: true,
  dataTreeStartExpanded: [true, true, false] // Expand levels 0,1 but not 2+
});

Advanced Tree Features

Tree Filtering and Sorting

Configure how child rows are handled in filtering and sorting operations.

const table = new Tabulator("#table", {
  dataTree: true,
  dataTreeFilter: true, // Include child rows in filtering
  dataTreeSort: true,   // Include child rows in sorting
  
  // Child row calculations
  dataTreeChildColumnCalcs: true, // Include visible children in calculations
  
  // Selection propagation  
  dataTreeSelectPropagate: true, // Selecting parent selects children
});

Dynamic Tree Operations

Dynamically modify tree structure after table creation.

// Add children to existing rows
const parentRow = table.getRow(1);
await parentRow.addTreeChild({
  name: "New Team Member",
  role: "Junior Developer",
  employees: 1
});

// Traverse tree programmatically
function traverseTree(row, level = 0) {
  const indent = "  ".repeat(level);
  console.log(`${indent}${row.getData().name}`);
  
  const children = row.getTreeChildren();
  children.forEach(child => {
    traverseTree(child, level + 1);
  });
}

// Traverse all top-level rows
table.getRows().forEach(row => {
  if (!row.getTreeParent()) {
    traverseTree(row);
  }
});

// Batch tree operations
const engineeringTeam = table.getRows().find(row => 
  row.getData().name === "Engineering"
);

if (engineeringTeam) {
  // Collapse all children
  engineeringTeam.getTreeChildren().forEach(child => {
    child.treeCollapse();
  });
  
  // Then expand the parent
  engineeringTeam.treeExpand();
}

Tree Events

Handle tree-specific events for user interactions.

// Tree expansion/collapse events
table.on("dataTreeRowExpanded", function(row, level) {
  console.log(`Row expanded: ${row.getData().name} at level ${level}`);
});

table.on("dataTreeRowCollapsed", function(row, level) {
  console.log(`Row collapsed: ${row.getData().name} at level ${level}`);
});

// Custom tree button handling
table.on("rowClick", function(e, row) {
  // Check if click was on tree control
  if (e.target.closest('.tabulator-data-tree-control')) {
    row.treeToggle();
  }
});

Tree Data Structures

Nested Object Structure

Standard hierarchical data with child arrays.

const nestedData = [
  {
    id: 1,
    name: "Parent 1",
    _children: [
      {
        id: 2,
        name: "Child 1.1",
        _children: [
          { id: 3, name: "Grandchild 1.1.1" },
          { id: 4, name: "Grandchild 1.1.2" }
        ]
      },
      { id: 5, name: "Child 1.2" }
    ]
  }
];

Flat Data with Parent References

Transform flat data with parent references into tree structure.

const flatData = [
  { id: 1, name: "Parent 1", parentId: null },
  { id: 2, name: "Child 1.1", parentId: 1 },
  { id: 3, name: "Child 1.2", parentId: 1 },
  { id: 4, name: "Grandchild 1.1.1", parentId: 2 }
];

// Transform to nested structure
function buildTree(flatData) {
  const tree = [];
  const lookup = {};
  
  // Create lookup map
  flatData.forEach(item => {
    lookup[item.id] = { ...item, _children: [] };
  });
  
  // Build tree structure
  flatData.forEach(item => {
    if (item.parentId === null) {
      tree.push(lookup[item.id]);
    } else {
      lookup[item.parentId]._children.push(lookup[item.id]);
    }
  });
  
  return tree;
}

const treeData = buildTree(flatData);

Types

interface TreeRowData {
  [key: string]: any;
  _children?: TreeRowData[];
}

interface DataTreeOptions {
  dataTree?: boolean;
  dataTreeFilter?: boolean;
  dataTreeSort?: boolean;
  dataTreeElementColumn?: string | false;
  dataTreeBranchElement?: boolean | string | HTMLElement;
  dataTreeChildIndent?: number;
  dataTreeChildField?: string;
  dataTreeCollapseElement?: string | HTMLElement | false;
  dataTreeExpandElement?: string | HTMLElement | false;
  dataTreeStartExpanded?: boolean | Function | boolean[];
  dataTreeChildColumnCalcs?: boolean;
  dataTreeSelectPropagate?: boolean;
}

interface TreeStartExpandedFunction {
  (row: RowComponent, level: number): boolean;
}

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