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

event-system.mddocs/

Event System

Comprehensive event handling for user interactions, data changes, and table lifecycle events with support for custom event dispatch.

Capabilities

Event Subscription and Management

Core methods for subscribing to and managing table events.

/**
 * Subscribe to table event
 * @param event - Event name to listen for
 * @param callback - Function to execute when event fires
 */
on(event: string, callback: Function): void;

/**
 * Unsubscribe from table event
 * @param event - Event name to stop listening to
 * @param callback - Specific callback to remove (optional, removes all if not provided)
 */
off(event: string, callback?: Function): void;

/**
 * Dispatch custom event
 * @param event - Event name to dispatch
 * @param args - Arguments to pass to event handlers
 */
dispatchEvent(event: string, ...args: any[]): void;

Usage Examples:

// Basic event subscription
table.on("rowClick", function(e, row) {
  console.log("Row clicked:", row.getData());
});

// Multiple event handlers
table.on("cellEdited", handleCellEdit);
table.on("cellEdited", logCellChanges);
table.on("cellEdited", validateCellData);

// Remove specific handler
table.off("cellEdited", logCellChanges);

// Remove all handlers for event
table.off("rowClick");

// Dispatch custom event
table.dispatchEvent("customDataUpdate", { source: "api", count: 50 });

Table Lifecycle Events

Events related to table construction, destruction, and state changes.

interface LifecycleEvents {
  /** Fired before table construction begins */
  "tableBuilding": () => void;
  /** Fired after table construction completes */
  "tableBuilt": () => void;
  /** Fired after table is completely destroyed */
  "tableDestroyed": () => void;
  /** Fired when table is redrawn */
  "tableRedraw": (force: boolean) => void;
}

Usage Examples:

table.on("tableBuilding", function() {
  console.log("Starting table construction...");
  showLoadingIndicator();
});

table.on("tableBuilt", function() {
  console.log("Table ready!");
  hideLoadingIndicator();
  initializeCustomFeatures();
});

table.on("tableDestroyed", function() {
  console.log("Table cleanup complete");
  clearCustomEventListeners();
});

Data Events

Events triggered by data loading, changes, and manipulation operations.

interface DataEvents {
  /** Fired before data loading begins */
  "dataLoading": (data: any) => void;
  /** Fired after data is loaded and processed */
  "dataLoaded": (data: any[]) => void;
  /** Fired when data changes occur */
  "dataChanged": (data: any[]) => void;
  /** Fired after data processing completes */
  "dataProcessed": () => void;
  /** Fired before data sorting */
  "dataSorting": (sorters: any[]) => void;
  /** Fired after data is sorted */
  "dataSorted": (sorters: any[], rows: RowComponent[]) => void;
  /** Fired before data filtering */
  "dataFiltering": (filters: any[]) => void;
  /** Fired after data is filtered */
  "dataFiltered": (filters: any[], rows: RowComponent[]) => void;
}

Usage Examples:

// Data loading events
table.on("dataLoading", function(data) {
  console.log("Loading data...", data);
  showProgressBar();
});

table.on("dataLoaded", function(data) {
  console.log(`Loaded ${data.length} records`);
  hideProgressBar();
  updateRecordCount(data.length);
});

// Data change tracking
table.on("dataChanged", function(data) {
  console.log("Data modified, auto-saving...");
  autoSaveData(data);
});

// Filter and sort events
table.on("dataFiltered", function(filters, rows) {
  updateStatusBar(`${rows.length} rows visible`);
});

table.on("dataSorted", function(sorters, rows) {
  console.log("Data sorted by:", sorters);
});

Row Events

Events related to row operations, selection, and user interactions.

interface RowEvents {
  /** Fired when row is added to table */
  "rowAdded": (row: RowComponent) => void;
  /** Fired when row is deleted from table */
  "rowDeleted": (row: RowComponent) => void;
  /** Fired when row data is updated */
  "rowUpdated": (row: RowComponent) => void;
  /** Fired when row is moved */
  "rowMoved": (row: RowComponent) => void;
  /** Fired when row is clicked */
  "rowClick": (e: Event, row: RowComponent) => void;
  /** Fired when row is double-clicked */
  "rowDblClick": (e: Event, row: RowComponent) => void;
  /** Fired when row context menu is triggered */
  "rowContext": (e: Event, row: RowComponent) => void;
  /** Fired when row is selected */
  "rowSelected": (row: RowComponent) => void;
  /** Fired when row is deselected */
  "rowDeselected": (row: RowComponent) => void;
  /** Fired when row selection changes */
  "rowSelectionChanged": (data: any[], rows: RowComponent[]) => void;
  /** Fired when mouse enters row */
  "rowMouseEnter": (e: Event, row: RowComponent) => void;
  /** Fired when mouse leaves row */
  "rowMouseLeave": (e: Event, row: RowComponent) => void;
}

Usage Examples:

// Row interaction events
table.on("rowClick", function(e, row) {
  const data = row.getData();
  if (data.id) {
    window.location.href = `/users/${data.id}`;
  }
});

table.on("rowDblClick", function(e, row) {
  row.getCell("name").edit(); // Start editing name field
});

// Row data change events
table.on("rowAdded", function(row) {
  console.log("New row added:", row.getData());
  row.getElement().style.backgroundColor = "lightgreen";
  setTimeout(() => {
    row.getElement().style.backgroundColor = "";
  }, 2000);
});

table.on("rowUpdated", function(row) {
  console.log("Row updated:", row.getData());
  markRowAsModified(row);
});

// Row selection events
table.on("rowSelectionChanged", function(data, rows) {
  const count = rows.length;
  document.getElementById("selected-count").textContent = `${count} selected`;
  
  // Enable/disable bulk action buttons
  toggleBulkActions(count > 0);
});

Cell Events

Events for cell-level interactions, editing, and formatting.

interface CellEvents {
  /** Fired when cell is clicked */
  "cellClick": (e: Event, cell: CellComponent) => void;
  /** Fired when cell is double-clicked */
  "cellDblClick": (e: Event, cell: CellComponent) => void;
  /** Fired when cell context menu is triggered */
  "cellContext": (e: Event, cell: CellComponent) => void;
  /** Fired when cell editing begins */
  "cellEditing": (cell: CellComponent) => void;
  /** Fired when cell editing is cancelled */
  "cellEditCancelled": (cell: CellComponent) => void;
  /** Fired when cell edit is completed */
  "cellEdited": (cell: CellComponent) => void;
  /** Fired when mouse enters cell */
  "cellMouseEnter": (e: Event, cell: CellComponent) => void;
  /** Fired when mouse leaves cell */
  "cellMouseLeave": (e: Event, cell: CellComponent) => void;
}

Usage Examples:

// Cell editing events
table.on("cellEditing", function(cell) {
  console.log("Editing cell:", cell.getField());
  cell.getElement().style.backgroundColor = "lightyellow";
});

table.on("cellEdited", function(cell) {
  const field = cell.getField();
  const newValue = cell.getValue();
  const oldValue = cell.getOldValue();
  
  console.log(`${field} changed from "${oldValue}" to "${newValue}"`);
  
  // Validate and save
  if (validateCellValue(field, newValue)) {
    saveCellChange(cell.getRow().getData().id, field, newValue);
  } else {
    cell.restoreOldValue();
  }
});

// Cell interaction events
table.on("cellClick", function(e, cell) {
  if (cell.getField() === "email") {
    window.open(`mailto:${cell.getValue()}`);
  }
});

Column Events

Events related to column operations and interactions.

interface ColumnEvents {
  /** Fired when column header is clicked */
  "columnClick": (e: Event, column: ColumnComponent) => void;
  /** Fired when column header is double-clicked */
  "columnDblClick": (e: Event, column: ColumnComponent) => void;
  /** Fired when column context menu is triggered */
  "columnContext": (e: Event, column: ColumnComponent) => void;
  /** Fired when column is moved */
  "columnMoved": (column: ColumnComponent, columns: ColumnComponent[]) => void;
  /** Fired when column is resized */
  "columnResized": (column: ColumnComponent) => void;
  /** Fired when column visibility changes */
  "columnVisibilityChanged": (column: ColumnComponent, visible: boolean) => void;
  /** Fired when column title is changed */
  "columnTitleChanged": (column: ColumnComponent) => void;
}

Page Events

Events for pagination operations and navigation.

interface PageEvents {
  /** Fired when page is loaded */
  "pageLoaded": (pageno: number) => void;
  /** Fired when page changes */
  "pageChanged": (pageno: number) => void;
}

Advanced Event Patterns

Event Chaining and Validation

// Prevent default behavior with validation
table.on("cellEditing", function(cell) {
  const field = cell.getField();
  const rowData = cell.getRow().getData();
  
  if (field === "salary" && rowData.role !== "manager") {
    cell.cancelEdit();
    alert("Only managers can edit salaries");
    return false; // Prevent editing
  }
});

// Chain events for complex workflows
table.on("rowAdded", function(row) {
  // Auto-assign ID for new rows
  if (!row.getData().id) {
    row.update({ id: generateUniqueId() });
  }
});

table.on("rowUpdated", function(row) {
  // Auto-update modified timestamp
  row.update({ lastModified: new Date().toISOString() });
});

Custom Event Creation

// Define custom events for application logic
class TableManager {
  constructor(table) {
    this.table = table;
    this.setupCustomEvents();
  }
  
  setupCustomEvents() {
    // Custom validation event
    this.table.on("customValidation", (data, callback) => {
      fetch("/api/validate", {
        method: "POST",
        body: JSON.stringify(data)
      })
      .then(response => response.json())
      .then(result => callback(result.isValid, result.errors));
    });
    
    // Custom save event
    this.table.on("customSave", (data) => {
      this.saveToServer(data);
    });
  }
  
  triggerValidation(data) {
    this.table.dispatchEvent("customValidation", data, (isValid, errors) => {
      if (isValid) {
        this.table.dispatchEvent("customSave", data);
      } else {
        this.displayErrors(errors);
      }
    });
  }
}

Event Performance Optimization

// Debounce rapid events
let saveTimeout;
table.on("cellEdited", function(cell) {
  clearTimeout(saveTimeout);
  saveTimeout = setTimeout(() => {
    saveAllData();
  }, 1000); // Save 1 second after last edit
});

// Batch event processing
const batchProcessor = {
  events: [],
  timeout: null,
  
  add(event, data) {
    this.events.push({ event, data, timestamp: Date.now() });
    
    if (!this.timeout) {
      this.timeout = setTimeout(() => {
        this.processBatch();
      }, 100);
    }
  },
  
  processBatch() {
    console.log(`Processing ${this.events.length} events`);
    // Process all events together
    this.events = [];
    this.timeout = null;
  }
};

table.on("cellEdited", (cell) => batchProcessor.add("cellEdited", cell));
table.on("rowUpdated", (row) => batchProcessor.add("rowUpdated", row));

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