The public API of one table – everything you do with a table after it has been created: scrolling, sorting, filtering, selection, copy, Excel export, updating cells and rows, repainting.

Every table has exactly one TableApi. You never create it yourself – you get it:

Where How
Plain TypeScript new TableScope(host, model, new SimpleDomService(), options, listener).firstInit().getApi()
Web Component el.addEventListener("tableReady", e => e.detail)
React / Preact / Solid <GuiexpertTable tableReady={api => …} />
Vue 3 <GuiexpertTable @tableReady="api => …" />
Svelte 5 <GuiexpertTable onTableReady={api => …} />
Angular <guiexpert-table (tableReady)="onReady($event)" />

The most important methods

Task Methods
scroll scrollToIndex, ensureRowIsVisible, ensureColumnIsVisible, scrollToPixel, getFirstVisibleRowIndex
sort sortByColumn, sort, reSort
filter externalFilterChanged (with TableOptionsIf.externalFilterFunction)
export copyToClipboard, downloadExcel
change data updateCells, setRows, addRows, updateRows, removeRows, applyCellChanges
fill, batch edit fillRange, startBatchEdit, getPendingChanges, commitBatchEdit, cancelBatchEdit
redraw repaint (same row count), repaintHard (row count or heights changed)
columns autoResizeColumns, setColumnWidth, recalcColumnWidths, getColumnIndex
tree expandAll, collapseAll, setRowExpanded
state getState, applyState, resetState (with TableOptionsIf.autoRestoreOptions)
right-to-left getDirection (with TableOptionsIf.direction)
lifecycle destroy

Example

// plain TypeScript: create a table and talk to it
const tableModel = TableFactory.createTableModel({ rows: orders });
const tableApi = new TableScope(host, tableModel, new SimpleDomService(), new TableOptions(), new EventAdapter())
.firstInit()
.getApi();

tableApi.scrollToIndex(0, 50_000); // column 0, row 50,000
tableApi.sortByColumn("total", "desc"); // like a double-click on the header
await tableApi.copyToClipboard(); // the current selection, tab-separated
await tableApi.downloadExcel("orders.xlsx"); // the current view as .xlsx

Example

// live data: change single cells, only the visible ones are redrawn
tableApi.updateCells([
new TableCellUpdateEvent("body", 3, 2, 101.5, { "tick-up": true }),
new TableCellUpdateEvent("body", 3, 3, 0.42)
]);

Example

// replace the rows of an object-array table – the row count changes, so repaint hard
tableApi.setRows(newOrders);
tableApi.externalFilterChanged(); // only if a filter function is set
tableApi.repaintHard();

See

Training: Your first table, Sorting, Filtering, Excel export, Live data

Hierarchy

  • TableApi

Constructors

Properties

Methods

addRows addRowsAt announce applyCellChanges applyState autoResizeColumns batchUndoable canRedo canUndo cancelBatchEdit cancelCut cancelFill cancelRowDrag clearCells clearSelection clearUndoHistory collapseAll collapseAllDetails commitBatchEdit copySelection copyToClipboard cutSelection deleteColumns deleteRows destroy downloadExcel ensureColumnIsVisible ensureRowIsVisible evaluateFormula expandAll expandAllDetails externalFilterChanged fillRange findRowFromAllRowsByAllCriteria findRowFromFilteredRowsByAllCriteria findRows getActiveCell getBodyModel getCellAddress getCellByAddress getCellInput getCellValue getColumnIndex getDependents getDetailElement getDirection getDisplayedRowCount getEditingCell getExpandedDetailRows getFirstFullVisibleRowIndex getFirstVisibleRowIndex getHeaderFocus getLastFullVisibleRowIndex getLastVisibleRowIndex getOverlayState getPendingChanges getPivotConfig getPrecedents getRowGroupBy getRowValue getSelectionAggregates getSelectionAsText getSelectionModel getSheetData getSheetEngine getSheetValue getShortcutActionMapping getShowValuesAs getState getTableModel getTableScope getUndoState goToAddress hasCellFormulas hasPendingChanges hideOverlay insertColumns insertRows isBatchEditing isColumnVisible isDetailExpanded isEditing isFilling isFooterVisible isHeaderVisible isLoggingActive isRowDragging moveRows pasteText reSort recalcColumnWidths recalcWrappers recalculate redo refreshDetail removeRows repaint repaintHard resetState scrollToIndex scrollToPixel setCellInput setColumnFormula setColumnVisible setColumnWidth setCustomState setDetailExpanded setFooterVisible setHeaderGroupCollapsed setHeaderVisible setLoggingActive setPivotConfig setRowExpanded setRowGroupBy setRows setSelectionModel setShowValuesAs showLoadingOverlay showNoRowsOverlay sort sortByColumn startBatchEdit startEditing stopEditing subscribe toggleDetail triggerAction undo updateCells updateRows

Constructors

Properties

tableScope: TableScope

Methods

  • Adds new rows to the end of the table body.

    Only works with an AreaModelObjectArray body – logs a console warning otherwise. Does not repaint and resets filtering and sorting of the body: afterwards call externalFilterChanged (if a filter function is set) and repaintHard (the row count changed).

    Type Parameters

    • T

      The type of elements in the rows array

    Parameters

    • rows: T[]

      An array of data objects to append to the table's existing rows

    Returns void

    • This method doesn't return anything.

    Description

    This method appends the provided array of data objects to the end of the existing rows in the table body. It only works with tables that use AreaModelObjectArray as their body model.

    Example

    tableApi.addRows([{ id: 100_001, customer: "New GmbH" }]);
    tableApi.repaintHard();
    tableApi.ensureRowIsVisible(tableApi.getDisplayedRowCount() - 1);
  • Inserts new rows at a specific position in the table body.

    Only works with an AreaModelObjectArray body – logs a console warning otherwise. Does not repaint and resets filtering and sorting of the body: afterwards call externalFilterChanged (if a filter function is set) and repaintHard (the row count changed).

    Type Parameters

    • T

      The type of elements in the rows array

    Parameters

    • rows: T[]

      An array of data objects to insert into the table

    • rowIndex: number

      The index position where the new rows should be inserted

    Returns void

    • This method doesn't return anything.

    Description

    This method inserts the provided array of data objects at the specified index position in the table body. Existing rows at or after the specified index will be shifted down. It only works with tables that use AreaModelObjectArray as their body model.

  • Speaks a message to screen reader users through the live region of the table (role="status", polite – it does not interrupt). The table itself announces sorting, filter results, copying and "select all"; use this for your own events, e.g. after loading or saving data.

    Parameters

    • text: string

      plain text (not HTML)

    Returns void

    Example

    fetch("/api/orders").then(r => r.json()).then(orders => {
    tableApi.setRows(orders);
    tableApi.announce(`${orders.length} orders loaded`);
    });

    Since

    1.1.91

    See

    Training: Accessible tables: keyboard and screen readers

  • Writes values into body cells like the cell editor does – the one way the table changes cells (editor, fill handle and batch commit use it too): cells that are not editable are skipped (editable, calculated columns without valueSetter, group and pivot rows), values run through editInputPipe and ColumnDefIf.validate (invalid ones are not written), totals and calculated columns follow, and one onModelChanged reports all cells with old and new values. In a batch edit the values are marked as pending instead.

    Paste from the clipboard and undo/redo can be built on it: a CellChangeIf has the old and the new value.

    Parameters

    • changes: CellValueChangeIf[]

      display row index, column (index or property) and value per cell

    • Optional source: CellChangeSource = "api"
    • Optional opts: {
          undoable?: boolean;
      } = {}

      undoable: record the change for undo (TableOptionsIf.undo) – default: UndoOptionsIf.recordApiChanges for "api", recorded for the other sources (since 1.1.99)

      • Optional undoable?: boolean

    Returns CellChangeIf<any>[]

    the written (batch edit: newly pending) cells

    Example

    tableApi.applyCellChanges([
    { rowIndex: 0, column: "price", value: 9.9 },
    { rowIndex: 1, column: "price", value: 12 },
    ]);

    Example

    // undo the last change set (from onModelChanged)
    const undo = (changes: CellChangeIf[]) => tableApi.applyCellChanges(
    changes.map(c => ({ rowIndex: c.rowIndex, column: c.property, value: c.oldValue })));

    Since

    1.1.96

  • Applies a state from getState (or one written by hand) and repaints. Only the parts contained in the state are applied (optionally only the given ones); the others stay as they are – pass a part empty to reset it, e.g. sort: [] (clears the sort icons; the rows keep their current order). Unknown columns and rows are ignored. The change is stored (TableOptionsIf.autoRestoreOptions) and reported (EventListenerIf.onStateChanged).

    Parameters

    Returns void

    Example

    // two saved views of the same table
    const views: Record<string, TableStateIf> = {};
    views["compact"] = tableApi.getState(["columns"]);
    tableApi.applyState(views["compact"]);

    Example

    tableApi.applyState({ sort: [{ property: "total", sortState: "desc" }] });
    

    Since

    1.1.92

  • Automatically resizes all columns to fit their content.

    Parameters

    • recalcWrappers: boolean = true

      Determines whether to recalculate wrapper dimensions after resizing columns. Default value is true.

    Returns void

    • This method doesn't return anything.
  • Records all changes fn makes (several applyCellChanges calls, a fill and a paste …) as one undo step. Without the option fn just runs.

    Type Parameters

    • T

    Parameters

    • label: string

      the label of the step ("Undo Import")

    • fn: (() => T)

      the changes

        • (): T
        • Returns T

    Returns T

    what fn returns

    Example

    tableApi.batchUndoable("Import", () => {
    tableApi.applyCellChanges(firstChanges, "api", { undoable: true });
    tableApi.applyCellChanges(secondChanges, "api", { undoable: true });
    });

    Since

    1.1.99

  • True if there is an undone change to redo.

    Returns boolean

    true if redo would redo something

    Example

    redoButton.disabled = !tableApi.canRedo();
    

    Since

    1.1.99

  • True if there is a change to undo – for buttons (or listen to onUndoStackChanged).

    Returns boolean

    true if undo would undo something

    Example

    undoButton.disabled = !tableApi.canUndo();
    

    Since

    1.1.99

  • Discards the pending values of a batch edit (the cells show the data again) and ends a batch edit started with startBatchEdit.

    Returns void

    Example

    discardButton.onclick = () => tableApi.cancelBatchEdit();
    

    Since

    1.1.96

  • Removes the mark of cut cells (like Escape): the next paste copies instead of moving.

    Returns void

    Example

    tableApi.cancelCut();
    

    Since

    1.1.99

  • Cancels a running fill (like Escape): nothing is changed.

    Returns void

    Example

    tableApi.cancelFill();
    

    Since

    1.1.96

  • Cancels a running row drag (like Escape): nothing is moved, onRowDragEnd gets the type "cancel".

    Returns void

    Example

    tableApi.cancelRowDrag();   // e.g. new data arrived from the server
    

    Since

    1.1.95

  • Clears body cells like Delete in Excel-style editing: editable cells get their empty value (ColumnDefIf.emptyValue, default ""), one onModelChanged with the source "clear" (batch edit: marked). Works without TableOptionsIf.editing too.

    Parameters

    • Optional ranges: CellRange[]

      body ranges; default: the selected cells, or the focused cell

    Returns number

    the number of cleared cells, -1 if there were too many (EditingOptionsIf.maxClearCells)

    Example

    tableApi.clearCells([new CellRange(0, 2, 9, 2)]);   // rows 0–9 of column 2
    

    Since

    1.1.99

  • Clears the current selection in the table.

    This method removes any selected cells, rows, or columns in the table. It provides a convenient way to programmatically clear all selections in the table without having to access the underlying selection model directly.

    When called, this method delegates to the table scope's clearSelection method with a parameter value of true, which ensures the table is automatically repainted after the selection is cleared.

    Returns void

    Example

    // Clear all selections in the table (e.g. from a "reset" button)
    tableApi.clearSelection();
  • Empties the undo history (e.g. after saving or loading new data).

    Returns void

    Example

    await save(rows);
    tableApi.clearUndoHistory();

    Since

    1.1.99

  • Tree tables: collapses every row on every level and repaints. No effect for other tables.

    Returns void

    Example

    tableApi.collapseAll();
    
  • Collapses all detail rows (their contents are destroyed). No event per row.

    Returns number

    the number of rows that were collapsed

    Example

    tableApi.collapseAllDetails();
    

    Since

    1.1.97

  • Writes the pending values of a batch edit into the rows (through setValue, like the editor) and ends a batch edit started with startBatchEdit: one onModelChanged (source "commit") with all cells, then onBatchEditChanged with the type "commit". While a value is invalid (ColumnDefIf.validate) nothing is written and the result is false (unless BatchEditOptionsIf.blockCommitOnInvalid is false).

    Returns boolean

    true if written

    Example

    if (!tableApi.commitBatchEdit()) {
    alert("Please fix the marked cells first.");
    }

    Since

    1.1.96

  • Copies the selected cells (the last selected range, everything after Ctrl/⌘+A, otherwise the focused cell) with the asynchronous clipboard API – for an own button or menu. Tab-separated text with Excel's quoting plus an HTML table (ClipboardOptionsIf.html); pasting it into this table pastes the values. The browser may ask for permission; Ctrl/⌘+C needs none (TableOptionsIf.clipboard). Works without the option (defaults).

    Returns Promise<void>

    resolves when the clipboard was written

    Example

    copyButton.addEventListener("click", () => tableApi.copySelection());
    

    Since

    1.1.99

  • Copies the selected data from the table to the clipboard.

    This method leverages the copyService to extract and copy the currently selected data from the table. It works with the current selection state and focus position to determine what content should be copied.

    The copied data is formatted as tab-separated text that can be pasted into spreadsheet applications like Excel or text editors while maintaining the tabular structure. Screen readers hear "12 cells copied" (AriaTextsIf.copied).

    Returns Promise<string>

    A promise that resolves with the copied data as a string. The string contains the tab-separated representation of the selected table data.

    Example

    // Copy the currently selected data to clipboard
    tableApi.copyToClipboard().then(content => {
    console.log('Copied to clipboard:', content);
    });

    // Using with a button click handler
    function onCopyButtonClick() {
    if (tableApi) {
    tableApi.copyToClipboard()
    .then(content => {
    console.log('Successfully copied data to clipboard');
    // Optionally do something with the copied content
    })
    .catch(error => {
    console.error('Failed to copy to clipboard:', error);
    });
    }
    }
  • Like copySelection, and the cells are marked (dashed frame): the next paste of this content moves them – the cut cells are emptied in the same change (source: "cut"). Escape or another change removes the mark.

    Returns Promise<void>

    resolves when the clipboard was written

    Example

    cutButton.addEventListener("click", () => tableApi.cutSelection());
    

    Since

    1.1.99

  • Deletes columns of a spreadsheet (at = letter index, A = 0) and adjusts the cell formulas. One undo step.

    Parameters

    • at: number

      the first data column

    • Optional count: number = 1

      columns

    Returns boolean

    true if deleted (false for other models)

    Example

    tableApi.deleteColumns(2);   // column C
    

    Since

    1.1.99

  • Deletes rows of the sheet (at = row number − 1) and adjusts the cell formulas (a deleted reference becomes #REF!). One undo step.

    Parameters

    • at: number

      the first physical row

    • Optional count: number = 1

      rows

    Returns boolean

    true if deleted

    Example

    tableApi.deleteRows(2);   // row 3
    

    Since

    1.1.99

  • Releases the table: removes all DOM listeners (incl. the window resize listener), stops the resize observer, calls the cleanup functions of all cell renderers and clears the host element. The framework wrappers call it automatically when they are unmounted or receive a new table model.

    Returns void

    Example

    // Plain TS: replace the table with a new model
    tableApi.destroy();
    const scope = new TableScope(hostDiv, newModel, new SimpleDomService(), new TableOptions(), new EventAdapter());
    scope.firstInit();
  • Downloads the current table data as an Excel file.

    This method extracts all visible data from the table (including header, body, and footer areas), converts it into a matrix format, and triggers a download of an Excel file containing this data.

    The method works by:

    1. Creating an empty matrix to hold all table data
    2. Iterating through each area of the table (header, body, footer)
    3. For each area, iterating through all rows and columns to extract cell values
    4. Passing the complete data matrix to the Excel service for file generation and download

    Parameters

    • fileName: string = 'table.xlsx'

      The name of the Excel file to be downloaded (default: 'table.xlsx')

    • author: string = ''

      Optional metadata for the Excel file to specify the author (default: '')

    • exportOptions: Partial<ExcelExportOptionsIf> = {}

    Returns Promise<void>

    resolves when the (compressed) file has been handed to the browser

    Example

    // Download table data with default filename
    tableApi.downloadExcel();

    Example

    // Download table data with custom filename and author
    tableApi.downloadExcel('sales-report.xlsx', 'John Doe');

    Example

    // Download table data with custom filename only
    tableApi.downloadExcel('quarterly-data.xlsx');

    Example

    // cell formulas as Excel formulas (since 1.1.99, tableOptions.cellFormulas)
    tableApi.downloadExcel('budget.xlsx', '', { cellFormulas: true });
  • Ensures that a column is fully visible by scrolling horizontally if necessary – the counterpart of ensureRowIsVisible. A column left of the viewport becomes the first visible column, a column right of it the last one. The vertical position is kept. The arrow keys use it for the focused cell.

    Fixed columns (fixedLeftColumnCount / fixedRightColumnCount) are always visible, hidden columns (setColumnVisible) can't be scrolled to: both return false.

    Parameters

    • columnIndex: number

      The column index (model index over west + center + east)

    Returns boolean

    true if the table was scrolled, false if the column was already visible

    Example

    // show the column of a search hit (rowIndex/columnIndex from your own search)
    const rowIndex = 1200, columnIndex = 14;
    tableApi.ensureColumnIsVisible(columnIndex);
    tableApi.ensureRowIsVisible(rowIndex);

    See

    scrollToIndex - scrolls a column and row to the top left

  • Ensures that a specific row is visible in the viewport by scrolling if necessary. This method checks if the target row is within the currently visible range and adjusts the scroll position if it's not visible.

    The method performs the following:

    1. Checks if the row is above the current viewport (before first visible row)
    2. Checks if the row is below the current viewport (after last visible row)
    3. Scrolls to make the row visible if needed

    Parameters

    • rowIndex: number

      The index of the row to make visible

    Returns boolean

    Returns true if scrolling was needed and performed, false if the row was already visible

    Example

    // Ensure row 5 is visible in the viewport
    tableApi.ensureRowIsVisible(5);

    Throws

    Implicitly may throw if rowIndex is not a number or if required properties are undefined

    See

  • Calculates a formula once against the sheet (not stored), e.g. for a preview: "=SUM(D2:D4)". undefined without cell formulas.

    Parameters

    • source: string

      the formula (the = is optional)

    Returns unknown

    the result (a FormulaError for an error)

    Example

    tableApi.evaluateFormula("=SUM(D2:D4)");   // 3895
    

    Since

    1.1.99

  • Tree tables: expands every row on every level (like the "expand all" icon in the header) and repaints. No effect for other tables.

    Returns void

    Example

    document.querySelector("#expand")!.addEventListener("click", () => tableApi.expandAll());
    
  • Expands the detail rows of all shown master rows. The contents are created only when they scroll into view, so this is cheap also for many rows. No event per row.

    Returns number

    the number of rows that were expanded

    Example

    document.querySelector("#expand-all")!.addEventListener("click", () => tableApi.expandAllDetails());
    

    Since

    1.1.97

  • Notifies the table that an external filter has been changed and needs to be applied.

    This method is used when an external filter condition (defined by tableOptions.externalFilterFunction) has changed and the table needs to refresh its display to reflect the new filtering criteria.

    When called, this method:

    1. Applies the external filter function to all rows
    2. Clears the current selection (by default)
    3. Scrolls to the top of the table
    4. Recalculates table dimensions
    5. Repaints the table to display only the filtered rows

    Returns void

    Example

    // Define an external filter function in your table options
    const tableOptions = {
    externalFilterFunction: (row: MyRowType) => {
    // Return true to include the row, false to filter it out
    return row.status === 'active';
    }
    };

    // Initialize your table with these options
    const tableApi = new TableApi(tableScope);

    // Later, when filter criteria change (e.g., in a search input handler)
    function onFilterTextChanged() {
    // Update the filter function if needed
    tableOptions.externalFilterFunction = (row: MyRowType) => {
    return row.name.includes(searchText);
    };

    // Apply the updated filter
    tableApi.externalFilterChanged();
    }

    See

    TableScope.externalFilterChanged

  • Fills cells next to a range – what dragging the fill handle does (TableOptionsIf.fillHandle is not needed for this call): continues series (1, 2 → 3, 4; dates; Item 1 → Item 2) or copies, writes with applyCellChanges (one onModelChanged, source "fill") and selects source and filled cells.

    Parameters

    • source: CellRange

      the source range (body display indices)

    • direction: FillDirection

      "down", "up", "right" or "left"

    • count: number

      rows or columns to fill (clamped to the table)

    • Optional mode: FillMode = "auto"

      "auto", "alternate" (like ⌥/Alt while dragging) or "copy"

    Returns number

    the number of filled cells (batch edit: marked); -1 if more than maxCells

    Example

    // rows 0 and 1 of column 2 hold 1 and 2: rows 2…9 get 3…10
    tableApi.fillRange(new CellRange(0, 2, 1, 2), "down", 8);

    Since

    1.1.96

  • Searches through all rows in the table's body model to find a row that matches specified criteria. This method works only with AreaModelObjectArray body models.

    Type Parameters

    • T

      The type of objects/rows in the table

    Parameters

    • criteria: Partial<T>

      A partial object containing the search criteria. Only needs to include the properties you want to match against.

    • predicate: ((criteria, row) => boolean)

      A function that defines how to match rows against the criteria. Returns true if the row matches the criteria, false otherwise.

        • (criteria, row): boolean
        • Parameters

          • criteria: Partial<T>
          • row: T

          Returns boolean

    Returns undefined | T

    The first matching row, or undefined if no match is found or if the body model is not AreaModelObjectArray.

    Example

    // Find a user row by id and name
    const criteria = { id: 1, name: "John" };
    const user = tableApi.findRowFromAllRowsByAllCriteria(criteria,
    (criteria, row) => row.id === criteria.id && row.name === criteria.name
    );

    Example

    // Find a product row with partial match on name
    const criteria = { name: "Phone" };
    const product = tableApi.findRowFromAllRowsByAllCriteria(criteria,
    (criteria, row) => row.name.includes(criteria.name!)
    );

    Example

    // Find an order with complex matching logic
    const criteria = { total: 100, status: "paid" as const };
    const order = tableApi.findRowFromAllRowsByAllCriteria<Order>(criteria,
    (criteria, row) => {
    return row.total > criteria.total! &&
    row.status === criteria.status;
    }
    );

    Throws

    Logs a warning to console if the body model is not an instance of AreaModelObjectArray

  • Searches through the filtered rows of the table to find a row that matches specific criteria. This method only works with tables that use AreaModelObjectArray as their body model.

    Type Parameters

    • T

      The type of the row objects in the table

    Parameters

    • criteria: Partial<T>

      A partial object containing the search criteria. Only needs to include the properties you want to match against.

    • predicate: ((criteria, row) => boolean)

      A function that defines how to match rows against the criteria. Returns true if the row matches the criteria, false otherwise.

        • (criteria, row): boolean
        • Parameters

          • criteria: Partial<T>
          • row: T

          Returns boolean

    Returns undefined | T

    The first matching row from the filtered rows, or undefined if no match is found or if the body model is not an instance of AreaModelObjectArray.

    Example

    interface Person {
    id: number;
    name: string;
    age: number;
    }

    // Find a person by exact match
    const criteria = { name: "John", age: 30 };
    const person = tableApi.findRowFromFilteredRowsByAllCriteria<Person>(
    criteria,
    (criteria, row) => row.name === criteria.name && row.age === criteria.age
    );

    // Find a person by partial name match
    const searchCriteria = { name: "Jo" };
    const person2 = tableApi.findRowFromFilteredRowsByAllCriteria<Person>(
    searchCriteria,
    (criteria, row) => row.name.toLowerCase().includes(criteria.name!.toLowerCase())
    );

    Throws

    Logs a warning to console if the body model is not an instance of AreaModelObjectArray

    Remarks

    • This method only searches through filtered rows (rows that are currently visible in the table)
    • If you need to search through all rows (including filtered out ones), use findRowFromAllRowsByAllCriteria instead
    • The predicate function gives you full control over how to match rows against your criteria
    • Returns undefined if either no match is found or if the table's body model is not compatible
  • Searches for and returns rows from the table body that match the given criteria.

    Only works with an AreaModelObjectArray body – logs a console warning otherwise.

    Type Parameters

    • T

      The type of elements in the rows array

    Parameters

    • rows: T[]

      An array of rows to search for in the table body

    • predicate: ((a, b) => boolean) = ...

      A comparison function that determines if two rows match

      • Default predicate uses strict equality (===)
      • The function should return true if the rows are considered a match
      • Parameters:
        • a: The row from the table body being checked
        • b: The row from the input array being searched for
        • (a, b): boolean
        • Parameters

          • a: T
          • b: T

          Returns boolean

    Returns T[]

    An array containing all matching rows found in the table body

    • Returns an empty array if:
      • The body model is not an instance of AreaModelObjectArray
      • No matches are found

    Description

    This method searches through the table body model for rows that match the provided criteria. It only works with tables that use AreaModelObjectArray as their body model. The method uses a predicate function to determine matches between rows.

    Example

    // Find rows with simple equality comparison
    const matchingRows = tableApi.findRows([orders[0], orders[1]]);

    Example

    // Find rows with custom comparison logic
    const matchingRows = tableApi.findRows<Order>([{ ...orders[0] }], (a, b) => a.id === b.id);
  • The active body cell (the focused cell), undefined if there is none or the header has the focus.

    Returns undefined | [number, number]

    display row and model column

    Example

    const cell = tableApi.getActiveCell();
    if (cell) console.log(tableApi.getCellAddress(cell[0], cell[1])); // "B3"

    Since

    1.1.99

  • The address of a body cell in cell formulas: "B3" = second data column, third row of getAllRows() (the physical row – sorting and filtering don't change it). undefined without cell formulas or for a row number or checkbox column.

    Parameters

    • rowIndex: number

      display row

    • column: string | number

      model column index or property

    Returns undefined | string

    the address

    Example

    tableApi.getCellAddress(1, "total");   // "D2" – the second row of getAllRows()
    

    Since

    1.1.99

  • The body cell of an address ("B3", "$B$3"): display row (-1 if a filter hides it) and model column; undefined without cell formulas or for an address outside the data.

    Parameters

    • address: string

      the address

    Returns undefined | [number, number]

    display row and model column

    Example

    const cell = tableApi.getCellByAddress("D5");
    if (cell && cell[0] >= 0) tableApi.scrollToIndex(cell[1], cell[0]);

    Since

    1.1.99

  • The input of a body cell – what was typed: the formula text of a cell formula ("=B2*C2"), otherwise the value.

    Parameters

    • rowIndex: number

      display row

    • column: string | number

      model column index or property

    Returns unknown

    the input

    Example

    tableApi.getCellInput(1, "total");   // "=B2*C2"
    

    Since

    1.1.99

  • The value of a body cell – the result of a cell formula (2598), otherwise the value (= getValueAt).

    Parameters

    • rowIndex: number

      display row

    • column: string | number

      model column index or property

    Returns unknown

    the value

    Example

    tableApi.getCellValue(1, "total");   // 2598
    

    Since

    1.1.99

  • The index of the column that shows a property – -1 if there is none.

    Column indices count all columns, also a RowNumberColumnDef or CheckboxColumnDef in front: with row numbers (rowNumbersVisible: true) every data column has an index one higher. Get the index by the property instead of writing numbers into your code.

    Parameters

    • property: string

      the property of the column definition, e.g. "total"

    Returns number

    the column index (fixed columns included) or -1

    Example

    const totalColumn = tableApi.getColumnIndex("total");
    tableApi.scrollToIndex(totalColumn, 0);

    Since

    1.1.93

  • The cells whose formulas read a cell directly (display row, model column; rows a filter hides are left out).

    Parameters

    • rowIndex: number

      display row

    • column: string | number

      model column index or property

    Returns [number, number][]

    the dependent cells

    Example

    tableApi.getDependents(1, "price");   // [[1, 3]] – D2 reads B2
    

    Since

    1.1.99

  • The container of a detail row (the element your detailRenderer renders into) – only while its content exists (it is created when the detail row becomes visible).

    Parameters

    • rowOrIndex: number | object

      display index or row object

    Returns undefined | HTMLDivElement

    the container

    Example

    const notes = tableApi.getDetailElement(order)?.querySelector("textarea");
    

    Since

    1.1.97

  • Retrieves the number of rows currently displayed in the table.

    Returns number

    The number of rows currently displayed in the table.

    Description

    This method returns the count of rows that are currently visible in the table after applying any filtering, pagination, or other visibility constraints.

  • The cell whose editor is open.

    Returns undefined | [number, number]

    display row and model column, undefined without editor

    Example

    const cell = tableApi.getEditingCell();
    if (cell) console.log(`editing row ${cell[0]}, column ${cell[1]}`);

    Since

    1.1.99

  • The master rows whose detail rows are expanded, in the order they were expanded (also rows that are filtered out).

    Type Parameters

    • T = any

    Returns T[]

    the row objects

    Example

    const openOrders = tableApi.getExpandedDetailRows<Order>().map(order => order.id);
    

    Since

    1.1.97

  • Retrieves the index of the first fully visible row in the table's viewport.

    A row is considered "fully visible" when it's completely within the visible area of the table. This differs from the regular "visible" row, which might be partially visible at the edges of the viewport.

    This method is useful for:

    • Determining which rows are completely in view for operations that require full visibility
    • Implementing pagination or virtualization logic that needs to know complete row visibility
    • Supporting keyboard navigation that should skip partially visible rows

    Returns number

    The index of the first fully visible row, or -1 if no rows are fully visible

    Example

    // Get the first fully visible row index
    const firstFullVisibleRow = tableApi.getFirstFullVisibleRowIndex();

    // Check if a specific row is fully visible
    const isRowFullyVisible = (rowIndex: number) => {
    const firstFullVisible = tableApi.getFirstFullVisibleRowIndex();
    const lastFullVisible = tableApi.getLastFullVisibleRowIndex();
    return rowIndex >= firstFullVisible && rowIndex <= lastFullVisible;
    };
  • Returns the index of the first visible row in the table's viewport.

    This method retrieves the first visible row index from the table's scope, which is useful for virtual scrolling and viewport-related calculations. The index represents the topmost visible row in the current scroll position of the table.

    This value is maintained internally by the table and updated during scrolling operations. It's particularly important for:

    • Virtual scrolling optimization
    • Calculating visible range of rows
    • Viewport-related operations
    • Scroll position restoration

    Returns number

    The index of the first visible row in the table's viewport. Returns -1 if no rows are visible or if the table is not yet rendered.

    Example

    // Get the first visible row index
    const tableApi = new TableApi(tableScope);
    const firstVisibleIndex = tableApi.getFirstVisibleRowIndex();

    // Use the index for scroll position calculations
    if (firstVisibleIndex >= 0) {
    // Perform operations with the first visible row
    console.log(`First visible row index: ${firstVisibleIndex}`);
    }
  • The header cell that has the keyboard focus. Arrow up in the first body row moves the focus into the header (Enter sorts or opens/closes a header group there); arrow down leaves it. The FocusModelIf holds the body focus only and is not changed by this.

    Returns undefined | [number, number]

    header row index and column index, undefined if the focus is in the body

    Example

    const headerFocus = tableApi.getHeaderFocus();
    if (headerFocus) {
    const [headerRow, column] = headerFocus;
    console.log(`header cell ${headerRow}/${column} has the focus`);
    }

    Since

    1.1.91

  • Returns the index of the last fully visible row in the table's viewport.

    This method retrieves the last row that is completely visible within the current viewport of the table. A row is considered "fully visible" when its entire height is visible without any portion being cut off by the viewport boundaries.

    The distinction between "visible" and "fully visible" is important when scrolling:

    • A row can be partially visible (some portion is in view)
    • A row can be fully visible (the entire row is in view)

    Returns number

    The index of the last fully visible row in the table. If no row is fully visible or the table is empty, the method might return -1.

    Example

    // Get the index of the last fully visible row
    const lastVisibleRowIndex = tableApi.getLastFullVisibleRowIndex();

    // Use this information to determine if a specific row is fully visible
    const isRowFullyVisible = rowIndex <= lastVisibleRowIndex && rowIndex >= tableApi.getFirstFullVisibleRowIndex();

    // Can be used with scrolling operations to ensure certain rows are visible
    if (rowIndex > lastVisibleRowIndex) {
    tableApi.ensureRowIsVisible(rowIndex);
    }
  • Returns the index of the last row that is visible in the table's viewport.

    This method retrieves the last visible row index from the table scope, which keeps track of which rows are currently visible as the user scrolls through the table.

    This can be useful for:

    • Implementing virtualized scrolling optimizations
    • Determining if specific rows are currently in view
    • Implementing features that need to know the visible range of rows

    Returns number

    The index of the last visible row in the table viewport

    Example

    // Check if a specific row is currently visible in the viewport
    const lastVisibleIndex = tableApi.getLastVisibleRowIndex();
    const firstVisibleIndex = tableApi.getFirstVisibleRowIndex();
    const isRowVisible = rowIndex >= firstVisibleIndex && rowIndex <= lastVisibleIndex;

    Example

    // Get the range of visible rows
    const visibleRowsRange = {
    first: tableApi.getFirstVisibleRowIndex(),
    last: tableApi.getLastVisibleRowIndex()
    };
    console.log(`Visible rows: ${visibleRowsRange.first} to ${visibleRowsRange.last}`);
  • The overlay shown now: "none", "loading", "noRows" or "noMatches". During OverlayOptionsIf.loadingDelayInMs the loading overlay is requested but not shown yet – the automatic overlay stays meanwhile (e.g. "noRows" of an empty table), so a fast answer causes no flicker.

    Returns GeOverlayKind

    the shown overlay

    Example

    if (tableApi.getOverlayState() === "noMatches") {
    resetFilterButton.hidden = false;
    }

    Since

    1.1.92

  • The values of a batch edit that are not written yet: row object, property, old and new value, the current display index (-1 while a filter hides the row) and the message of an invalid value. The changes belong to the rows, not to their positions – sorting and filtering don't mix them up.

    Returns CellChangeIf<any>[]

    the pending cells

    Example

    saveButton.onclick = async () => {
    const changes = tableApi.getPendingChanges()
    .map(c => ({ id: (c.row as { id: number }).id, field: c.property, value: c.newValue }));
    const response = await fetch("/api/prices", { method: "PATCH", body: JSON.stringify(changes) });
    if (response.ok) tableApi.commitBatchEdit();
    };

    Since

    1.1.96

  • Pivot table: the current configuration.

    Returns undefined | PivotConfigIf<any>

    a copy, undefined if the table model is no pivot table

    Example

    const columnFields = tableApi.getPivotConfig()?.columnFields;   // ["monat"]
    

    Since

    1.1.94

  • The cells and ranges a cell formula reads, as addresses.

    Parameters

    • rowIndex: number

      display row

    • column: string | number

      model column index or property

    Returns string[]

    e.g. ["B2", "C2"] (empty for a value cell or without cell formulas)

    Example

    tableApi.getPrecedents(1, "total");   // ["B2", "C2"]
    

    Since

    1.1.99

  • Row grouping: the current levels.

    Returns undefined | RowGroupField[]

    the levels, undefined if the body is no row grouping

    Example

    const levels = tableApi.getRowGroupBy();   // ["region", "produkt"]
    

    Since

    1.1.94

  • The value of a column for a row object – computed for a calculated column (valueGetter, formula), otherwise the property (path). Use it in the external filter to filter by calculated values; a TreeRow is unwrapped.

    Parameters

    • row: any

      a row object (or the TreeRow a tree filter gets)

    • property: string

      the property of the column

    Returns unknown

    the value (a FormulaError for a formula error)

    Example

    tableOptions.externalFilterFunction = (row: Item) => Number(tableApi.getRowValue(row, "total")) > 500;
    tableApi.externalFilterChanged();

    Since

    1.1.95

  • Count, sum, average, minimum and maximum of the selected body cells – for a status bar like in a spreadsheet. Counted are the selected cells of the visible data columns; the numbers are the cell values of type number. Above SelectionAggregator.maxCells cells (default 1,000,000) nothing is computed (capped: true). Without a selection all values are 0 / undefined.

    Returns SelectionAggregatesIf

    { count, numericCount, sum, avg, min, max, capped }

    Example

    // a status bar in plain HTML under the table
    const statusBar = document.querySelector<HTMLDivElement>("#status")!;
    const listener = new EventAdapter();
    listener.onSelectionChanged = () => {
    const a = tableApi.getSelectionAggregates();
    statusBar.textContent = a.capped ? "Selection too large"
    : a.numericCount ? `Count ${a.count} · Sum ${formatAggregateValue(a.sum)} · Average ${formatAggregateValue(a.avg)}`
    : "";
    };

    Since

    1.1.94

  • The selected cells as tab-separated text, exactly as Ctrl/⌘+C copies them (Excel's quoting, copyHeaders, copyValue). "" without cells or with more than CopyService.maxCopyCells.

    Returns string

    the text

    Example

    console.log(tableApi.getSelectionAsText());   // "a\tb\n1\t2"
    

    Since

    1.1.99

  • Returns the current selection model for the table.

    The selection model manages cell selection state, including single cells, ranges, rows, and columns. This method provides access to the selection model instance, allowing operations like:

    • Checking if cells are selected
    • Getting selection ranges
    • Modifying selections
    • Adding/removing selection event listeners

    Returns undefined | SelectionModelIf

    The current selection model if available, otherwise undefined.

    Example

    // Get the selection model
    const selectionModel = tableApi.getSelectionModel();

    // Check if a specific cell is selected
    if (selectionModel?.isSelected(3, 2)) {
    console.log('Cell at row 3, column 2 is selected');
    }

    // Get all selected ranges
    const ranges = selectionModel?.getRanges();
    console.log('Selected ranges:', ranges);

    // Clear all selections
    selectionModel?.clear();

    // Toggle selection of a cell
    selectionModel?.togglePoint(5, 1);

    // Add a selection change listener
    selectionModel?.addEventSelectionChangedListener({
    onSelectionChanged: () => {
    console.log('Selection has changed');
    }
    });
  • The inputs of a spreadsheet (SpreadsheetFactory) as rows × columns – formulas as text, up to the last filled row and column (empty cells ""). Save them; SpreadsheetFactory.create({ data }) loads them again. undefined for other models (their data are the app's rows).

    Returns undefined | unknown[][]

    the data

    Example

    localStorage.setItem("sheet", JSON.stringify(tableApi.getSheetData()));
    

    Since

    1.1.99

  • The formula engine of the cell formulas (undefined without them) – physical rows, data columns.

    Returns undefined | SheetEngine

    the engine

    Example

    tableApi.getSheetEngine()?.getFormulaCount();   // 4
    

    Since

    1.1.99

  • The value of a cell by its address – also of a row a filter hides. undefined without cell formulas.

    Parameters

    • address: string

      e.g. "D5"

    Returns unknown

    the value

    Example

    tableApi.getSheetValue("D5");   // 3895
    

    Since

    1.1.99

  • Retrieves the shortcut action mapping from the table's shortcut service.

    This method provides access to the keyboard shortcut configuration that defines which keys trigger specific actions in the table. The mapping contains key-value pairs where:

    • Keys are string representations of keyboard shortcuts (e.g., "ctrl+c", "shift+arrow_down")
    • Values are ActionId values representing the corresponding table actions

    This mapping can be useful for:

    • Displaying available shortcuts to users
    • Creating custom shortcut documentation
    • Dynamically checking which actions are available via keyboard
    • Extending or integrating with the table's shortcut system

    Returns ShortcutActionIdMapping

    An object mapping shortcut key combinations to their corresponding action IDs. For example: { "ctrl+c": "COPY_2_CLIPBOARD", "arrow_down": "NAVIGATE_DOWN" }

    Example

    // Get all available shortcuts in the table
    const shortcuts = tableApi.getShortcutActionMapping();

    // Check if a specific shortcut exists
    if (shortcuts["ctrl+c"]) {
    console.log("Copy shortcut is available with action:", shortcuts["ctrl+c"]);
    }

    // Display available shortcuts in the UI
    Object.entries(shortcuts).forEach(([key, actionId]) => {
    console.log(`${key}: ${actionId}`);
    });
  • „Show values as“ of a column.

    Parameters

    • property: string

      the property of the column

    Returns undefined | ShowValuesAsConfig

    the configuration, undefined for none

    Example

    const mode = tableApi.getShowValuesAs("total");   // "percentOfColumnTotal"
    

    Since

    1.1.95

  • The state of the table as plain JSON: column layout (order, widths, visibility), sorting, scroll position, expanded tree nodes, checked and selected rows, header groups and your own data (setCustomState). Columns are identified by property and rows by id (AutoRestoreOptionsIf.getRowId), never by index. Parts that do not apply to this table are left out (e.g. tree for a flat table).

    Store it wherever you like and give it back with applyState or TableOptionsIf.initialState; TableOptionsIf.autoRestoreOptions does this for you in localStorage.

    Parameters

    Returns TableStateIf

    the state

    Example

    const state = tableApi.getState();                       // { version: 1, columns: [...], sort: [...], ... }
    await fetch("/api/prefs/orders", { method: "PUT", body: JSON.stringify(state) });

    Example

    const layout = tableApi.getState(["columns", "sort"]);   // only the layout, no scroll position or selection
    

    See

    Training: Remember the state

    Since

    1.1.92

  • Retrieves the table model that contains all data and structure information for the table.

    Returns TableModelIf

    The table model interface that provides access to the table's data structure, including header, body, and footer area models.

  • Returns the TableScope instance associated with this TableApi.

    The TableScope provides access to the core functionality and internal state of the table component, including rendering, event handling, selection, and other low-level operations.

    This method is useful for advanced customization scenarios where you need direct access to the table's internal structure and behaviors.

    Returns TableScope

    The TableScope instance that controls this table component

    Example

    // Access the TableScope to perform a custom operation
    const tableApi = new TableApi(myTableScope);
    const tableScope = tableApi.getTableScope();

    // Example: Manually trigger a context menu at a specific location
    const mouseEvent = new MouseEvent('contextmenu');
    const geMouseEvent = tableScope.createGeMouseEvent(mouseEvent);
    tableScope.contextmenu(geMouseEvent);
  • The state of the undo history (what onUndoStackChanged reports).

    Returns undefined | GeUndoEvent

    can undo/redo, labels, size; undefined without the option

    Example

    const state = tableApi.getUndoState();
    undoButton.title = state?.undoLabel ? `Undo ${state.undoLabel}` : "Undo";

    Since

    1.1.99

  • Goes to a cell or range of the sheet by its address (cell formulas): "D10" makes it the active cell, "B2:C5" selects the range (its first cell becomes active); the view scrolls to it. false for an invalid address, one outside the data or a row a filter hides.

    Parameters

    • address: string

      e.g. "D10", "$B$2:C5"

    Returns boolean

    true if it went there

    Example

    tableApi.goToAddress("B2:C5");
    

    Since

    1.1.99

  • True if a batch edit has values that are not written yet.

    Returns boolean

    whether there are pending changes

    Example

    window.addEventListener("beforeunload", evt => {
    if (tableApi.hasPendingChanges()) evt.preventDefault(); // "Leave site? Changes may not be saved."
    });

    Since

    1.1.96

  • Ends the overlay shown by showLoadingOverlay or showNoRowsOverlay. "No rows to show" / "No matching rows" are not ended: they show the state of the body and stay as long as it is empty (switch them off with overlayOptions: { autoNoRows: false }).

    Returns void

    Example

    tableApi.showLoadingOverlay("Saving…");
    save(order).finally(() => tableApi.hideOverlay());

    Since

    1.1.92

  • Inserts empty columns before a column of a spreadsheet (SpreadsheetFactory; at = letter index, A = 0) and adjusts the cell formulas. One undo step.

    Parameters

    • at: number

      the data column the new columns come before

    • Optional count: number = 1

      columns

    Returns boolean

    true if inserted (false for other models)

    Example

    tableApi.insertColumns(1);   // a new column B
    

    Since

    1.1.99

  • Inserts empty rows before a row of the sheet (at = row number − 1, the physical row: also when sorted or filtered) and adjusts the cell formulas (=SUM(D2:D4) grows when rows are inserted inside). One undo step, one onModelChanged (source "structure"). Works for a spreadsheet (SpreadsheetFactory), object rows (new objects from clipboard.createRow, otherwise {} – the app's array changes in place) and arrays.

    Parameters

    • at: number

      the physical row the new rows come before (row count = append)

    • Optional count: number = 1

      rows

    Returns boolean

    true if inserted

    Example

    tableApi.insertRows(4, 2);   // two empty rows before row 5
    

    Since

    1.1.99

  • Returns whether a column is visible (ColumnDefIf.isVisible, see setColumnVisible). Columns without a column definition are always visible.

    Parameters

    • column: string | number | ColumnDefIf

      column index, property or column definition

    Returns boolean

    • True if the column is visible, false if it is hidden or does not exist.

    Example

    if (!tableApi.isColumnVisible("category")) {
    tableApi.setColumnVisible("category", true);
    }
  • True if the detail row of a master row is expanded (master/detail).

    Parameters

    • rowOrIndex: number | object

      display index or row object

    Returns boolean

    whether it is expanded

    Example

    const open = tableApi.isDetailExpanded(3);
    

    Since

    1.1.97

  • True while a cell editor is open.

    Returns boolean

    true while editing

    Example

    if (!tableApi.isEditing()) {
    tableApi.updateCells([], true); // live data: don't repaint under the user's input
    }

    Since

    1.1.99

  • True while the fill handle is dragged.

    Returns boolean

    true during a fill

    Example

    if (!tableApi.isFilling()) {
    tableApi.updateCells([], true); // e.g. live data: wait until the fill is done
    }

    Since

    1.1.96

  • Determines if the footer is visible: it has at least one row and is not hidden with setFooterVisible.

    Returns boolean

    True if the footer is visible, false otherwise.

    Example

    const footerShown = tableApi.isFooterVisible();
    
  • Checks if the header is visible: it has at least one row and is not hidden with setHeaderVisible.

    Returns boolean

    • Returns true if the header is visible, otherwise returns false.

    Example

    const headerShown = tableApi.isHeaderVisible();
    
  • Checks whether logging is currently active for the table component.

    This method returns the current state of logging for the table. When logging is active, the table outputs detailed information about its operations to the console, including:

    • Rendering processes and lifecycle events
    • Data modifications and updates
    • Event handling and user interactions
    • Performance metrics and state changes

    Logging can be toggled using the setLoggingActive(boolean) method.

    Returns boolean

    True if logging is currently enabled, false otherwise.

    Example

    // Check if logging is enabled
    if (tableApi.isLoggingActive()) {
    console.log("Table logging is currently active");
    }

    // Conditionally enable logging only if it's not already active
    if (!tableApi.isLoggingActive()) {
    tableApi.setLoggingActive(true);

    // Perform operations that need debugging
    tableApi.updateCells([
    {
    area: "body",
    rowIndex: 2,
    columnIndex: 3,
    value: "New Value",
    cssClasses: { "highlight": true }
    }
    ]);

    // Run some additional operations...

    // Disable logging when finished
    tableApi.setLoggingActive(false);
    }
  • True while rows are dragged with the pointer (mouse, touch, pen).

    Returns boolean

    true during a row drag

    Example

    if (!tableApi.isRowDragging()) {
    tableApi.updateCells([], true); // e.g. live data: wait until the drag is done
    }

    Since

    1.1.95

  • Moves body rows – the code way to do what row drag does (e.g. "up"/"down" buttons, the pointer alternative of WCAG 2.5.7, or after the server confirmed an unmanaged drag). The body model must support it (AreaModelIf.moveRows: object arrays, arrays of arrays, trees); no filter may hide rows and no column may be sorted (asc/desc – a sorted view has no order of its own). Focus and a multi-row selection follow the rows; screen readers hear "Row moved to position 7 of 20". No row drag events. false if nothing moved (also for a target where the rows already are).

    Parameters

    • rowIndices: number | number[]

      display index or indices of the rows to move

    • target: number | RowDropTargetIf

      drop target; a number = in front of that display index (getDisplayedRowCount() = behind the last row)

    Returns boolean

    true if the rows were moved

    Example

    tableApi.moveRows(2, { rowIndex: 6, position: "after" });   // row 3 becomes row 7
    tableApi.moveRows([0, 1], tableApi.getDisplayedRowCount()); // the first two rows to the end

    Example

    // unmanaged drag: the server decides, then the table moves the rows
    const listener = new EventAdapter();
    listener.onRowDragEnd = async (evt: GeRowDragEvent) => {
    if (evt.type === "end" && evt.target && (await fetch("/api/move", { method: "POST" })).ok) {
    tableApi.moveRows(evt.rowIndices, evt.target);
    }
    };

    Since

    1.1.95

  • Pastes tab-separated text like Ctrl/⌘+V – without clipboard permissions: from target (once), otherwise from the selection (tiled over a selected range that is an integer multiple, one value into every selected cell) or the focused cell. Hidden columns are skipped, read-only cells left out, the rest is cut off at the last column; one onModelChanged with source: "paste" (batch edit: marked). Works without TableOptionsIf.clipboard.

    Parameters

    • text: string

      rows separated by line breaks, cells by tabs (quoted cells like Excel)

    • Optional target: [number, number]

      display row and model column of the first cell

    Returns CellChangeIf<any>[]

    the written (batch edit: newly pending) cells

    Example

    tableApi.pasteText("a\tb\n1\t2", [0, 1]);   // A 2×2 block from row 0, column 1
    

    Since

    1.1.99

  • Re-applies the current sorting configuration to the table data and repaints.

    Returns void

    • This method doesn't return anything.

    Description

    The current sorting is the last sort function, otherwise the columns with a sort state (the header icons, also restored by autoRestoreOptions). Useful when the underlying data has changed and needs to be re-sorted without changing the sort columns or direction. (Before 1.1.91 only the sort items stored by autoRestoreOptions were used – without them reSort() did nothing.)

    Example

    orders[0].total = 999_999;
    tableApi.reSort();
  • Recalculates the column widths of the table.

    Parameters

    • Optional clientWidth: number

      The width of the client area.

    Returns void

  • Recalculates the dimensions of all wrapper elements in the table.

    This method is typically called after changes to the table structure or content that might affect the layout, such as resizing columns or changing row heights. It ensures that all wrapper elements are properly sized to match their content.

    Returns void

    • This method doesn't return anything.
  • Calculates all cell formulas again – after the app changed the data without the table (updateCells, applyCellChanges and the editor recalculate by themselves; repaint does not). Also renews TODAY(), NOW() and RAND().

    Returns void

    Example

    rows[3].price = 30;          // changed outside the table
    tableApi.recalculate();

    Since

    1.1.99

  • Redoes the last undone change like Ctrl+Y / Ctrl/⌘+Shift+Z (source "redo").

    Returns boolean

    true if a step was redone

    Example

    redoButton.addEventListener("click", () => tableApi.redo());
    

    Since

    1.1.99

  • Destroys the content of an expanded detail row and creates it again (context.recreated is true) – e.g. after the data it shows changed.

    Parameters

    • rowOrIndex: number | object

      display index or row object

    Returns boolean

    false if the row is not expanded

    Example

    order.items.push(newItem);
    tableApi.refreshDetail(order);

    Since

    1.1.97

  • Removes specified rows from the table body.

    Only works with an AreaModelObjectArray body – logs a console warning otherwise. Does not repaint and resets filtering and sorting of the body: afterwards call externalFilterChanged (if a filter function is set) and repaintHard (the row count changed).

    Type Parameters

    • T

      The type of elements in the rows array

    Parameters

    • rows: T[]

      An array of data objects to remove from the table

    • predicate: ((a, b) => boolean) = ...

      A comparison function that determines if two rows match

      • Default predicate uses strict equality (===)
      • The function should return true if the rows are considered a match
        • (a, b): boolean
        • Parameters

          • a: T
          • b: T

          Returns boolean

    Returns void

    • This method doesn't return anything.

    Description

    This method removes rows from the table body that match any of the provided rows based on the predicate function. It only works with tables that use AreaModelObjectArray as their body model.

  • Repaints the table.

    This method refreshes the visual representation of the table by delegating to the tableScope's repaint functionality. Use this method whenever the table's visual state needs to be updated after data changes, selection changes, or any modifications that affect the rendered output.

    Repainting the table ensures that all visible cells, rows, and styling reflect the current state of the underlying data model and configuration settings.

    Since 1.1.94 it also drops cached totals (AreaModelIf.invalidateDerivedValues, e.g. of a footer from footerAggregates), so they are computed again from the changed rows. Scrolling never does that.

    Returns void

    Example

    // Update data and repaint the table
    const tableApi = new TableApi(tableScope);
    tableApi.setRows(newData);
    tableApi.repaint();

    Example

    // Update selection and repaint to show the visual change
    tableApi.getSelectionModel()?.togglePoint(2, 3);
    tableApi.repaint();

    Example

    // After changing values in the row objects yourself, repaint to show them
    orders[0].status = "paid";
    tableApi.repaint();
  • Performs a complete repaint of the table by triggering a hard repaint on the underlying table scope.

    A hard repaint is more thorough than a regular repaint and performs the following operations:

    • Recalculates the height and padding of the table model
    • Resets the size of the wrapper div elements
    • Adjusts containers and rows positioning
    • Makes additional adjustments after scrolling

    Use this method when regular repaint isn't sufficient, such as when:

    • Table dimensions have significantly changed
    • The structure of data has been modified (rows/columns added or removed)
    • The table layout needs complete recalculation
    • After major DOM changes affecting the table's container

    Returns void

    This method doesn't return a value

    Example

    // Example 1: Basic usage
    tableApi.repaintHard();

    Example

    // Example 2: Using after major data changes
    tableApi.setRows(newDataSet);
    tableApi.repaintHard();

    Example

    // Example 3: Using after resizing a container
    window.addEventListener('resize', () => {
    tableApi.repaintHard();
    });

    Example

    // Example 4: Using after changing ColumnDefIf.isVisible yourself
    // (setColumnVisible() does this on its own)
    column.isVisible = FalseFn;
    tableApi.repaintHard();
  • Back to the state of the code: column layout, sort icons and header groups as they were right after the table was built (before a stored state was applied) – tree, checked and selected rows too when they are remembered (TableOptionsIf.autoRestoreOptions) or given as TableOptionsIf.initialState –, scrolled to the top, custom data removed. Deletes the stored state. The rows keep their current order (a table has no "unsorted" order to go back to); only the sort icons of the code come back.

    Returns void

    Example

    document.querySelector("#reset-layout")!.addEventListener("click", () => tableApi.resetState());
    

    Since

    1.1.92

  • Scrolls the table to display the specified row and column indices at the top-left corner of the viewport.

    The row becomes the first row of the body, the column the first column of the scrollable (center) part – as far as the scroll range allows: the last columns and rows cannot move further than to the right/bottom edge.

    Fixed columns (fixedLeftColumnCount / fixedRightColumnCount) are always visible: a fixed west column scrolls back to the start (x = 0), a fixed east column – and -1 or any other index outside the columns – keeps the current horizontal position.

    Parameters

    • indexX: number = 0

      The column index (model index, fixed columns included) to scroll to. Defaults to 0 (first column). -1 keeps the horizontal position.

    • indexY: number = 0

      The vertical index (row) to scroll to. Defaults to 0 (topmost row).

    Returns void

    Example

    // Scroll to the 5th row, keeping the current horizontal scroll position
    tableApi.scrollToIndex(-1, 5);

    Example

    // Scroll to column 3, row 10
    tableApi.scrollToIndex(3, 10);

    Example

    // Scroll to column 3, keeping the rows that are currently shown
    tableApi.scrollToIndex(3, tableApi.getFirstVisibleRowIndex());

    See

  • Scrolls the table content to the specified pixel coordinates.

    This method allows programmatic scrolling of the table viewport to exact pixel positions. It delegates the scrolling operation to the underlying TableScope instance.

    Parameters

    • px: number = 0

      The horizontal pixel coordinate to scroll to: px from the start of the row – 0 = the first column (leftmost position; right-to-left the rightmost, see TableOptionsIf.direction). Defaults to 0.

    • py: number = 0

      The vertical pixel coordinate to scroll to. Defaults to 0 (topmost position).

    Returns void

    Example

    // Scroll to the top-left corner of the table
    tableApi.scrollToPixel(0, 0);

    Example

    // Scroll 200 pixels horizontally and 150 pixels vertically
    tableApi.scrollToPixel(200, 150);

    Example

    // Scroll only vertically, keeping the current horizontal position
    // (an omitted or undefined px means 0; for rows use scrollToIndex(-1, rowIndex))
    tableApi.scrollToPixel(tableApi.getTableScope().getViewportScrollLeft(), 300);

    Example

    // Example in a component that needs precise scrolling control
    class TableScroller {
    private tableApi: TableApi;

    constructor(tableApi: TableApi) {
    this.tableApi = tableApi;
    }

    scrollToPosition(x: number, y: number) {
    // Scroll to exact pixel coordinates
    this.tableApi.scrollToPixel(x, y);
    }

    scrollHalfway() {
    const tableModel = this.tableApi.getTableModel();
    const totalWidth = tableModel.getContentWidthInPixel();
    const totalHeight = tableModel.getContentHeightInPixel();

    // Scroll to the middle of the table content
    this.tableApi.scrollToPixel(totalWidth / 2, totalHeight / 2);
    }
    }

    See

  • Writes the input of a body cell (a value or a formula "=B2*C2") like the editor: one applyCellChanges.

    Parameters

    • rowIndex: number

      display row

    • column: string | number

      model column index or property

    • input: unknown

      the input

    Returns boolean

    true if written (or marked in a batch edit)

    Example

    tableApi.setCellInput(4, "total", "=SUM(D2:D4)");
    

    Since

    1.1.99

  • Sets (or replaces) the formula of a column – e.g. from an input field of your app. The formula is compiled once; an invalid formula is set anyway (the cells show #ERROR! / #NAME?) and its error is returned, so you can show the message next to the input. No code is ever executed (no eval). The table repaints; totals, sorting and filter see the new values after repaint, reSort() resp. externalFilterChanged().

    Parameters

    • property: string

      the property of the column (it becomes a calculated column)

    • formula: string

      the formula, e.g. "[price] * [quantity] * 1.19"

    • Optional options: FormulaOptionsIf

      own functions

    Returns undefined | FormulaError

    the error of the formula itself, undefined if it is valid (#NAME? also if there is no such column)

    Example

    input.addEventListener("change", () => {
    const error = tableApi.setColumnFormula("custom", input.value);
    hint.textContent = error ? `${error.code} ${error.message}` : "";
    });

    Since

    1.1.95

  • Shows or hides a column and repaints the table.

    The column keeps its definition, its position (also when other columns are dragged) and its width: a hidden column is just not rendered (width 0), not copied (copyToClipboard) and not exported (downloadExcel). Showing it again restores the previous width. Works for fixed columns, too.

    The same as ColumnDefIf.isVisible – this method sets it to TrueFn / FalseFn (an own isVisible function of the column is replaced). Columns without a column definition (e.g. bodyData + columnSizes without columnDefs) can't be hidden.

    Parameters

    • column: string | number | ColumnDefIf

      column index (fixed columns included), property (e.g. "category") or the column definition

    • Optional visible: boolean = true

      false hides the column

    Returns boolean

    false if the column (definition) does not exist

    Example

    // hide a column by property, show it again later
    tableApi.setColumnVisible("category", false);
    tableApi.setColumnVisible("category", true);

    Example

    // a checkbox list "visible columns"
    tableApi.getTableModel().getColumnDefs()?.forEach((columnDef, index) => {
    const checkbox = document.createElement("input");
    checkbox.type = "checkbox";
    checkbox.checked = tableApi.isColumnVisible(index);
    checkbox.addEventListener("change", () => tableApi.setColumnVisible(columnDef, checkbox.checked));
    document.body.append(checkbox, columnDef.headerLabel);
    });
  • Sets the width of a specific column in the table.

    Parameters

    • columnIndex: number

      The index of the column to resize.

    • width: number

      The new width to set for the column, in pixels.

    Returns void

    • This method doesn't return anything.
  • Stores data of your application with the table state (part custom), e.g. the text of a filter field. It is reported with EventListenerIf.onStateChanged, stored with autoRestoreCustomState and returned by getState – also after a reload, so you can restore your filter in tableReady. Must be JSON.

    Parameters

    • custom: unknown

      your data (JSON)

    Returns void

    Example

    filterInput.addEventListener("input", () => {
    tableApi.setCustomState({ filter: filterInput.value });
    tableApi.externalFilterChanged();
    });
    // after a reload (tableReady):
    const custom = tableApi.getState(["custom"]).custom as { filter?: string } | undefined;
    filterInput.value = custom?.filter ?? "";

    Since

    1.1.92

  • Expands or collapses the detail row of a master row (master/detail, TableOptionsIf.masterDetail). The content is created when the detail row becomes visible; collapsing destroys it. Reports EventListenerIf.onDetailExpandedChanged (source "api").

    Parameters

    • rowOrIndex: number | object

      display index or row object

    • expanded: boolean

      true = expand, false = collapse

    Returns boolean

    false if nothing changed (no master row, already in that state, no master/detail)

    Example

    tableApi.setDetailExpanded(0, true);                  // the first shown row
    tableApi.setDetailExpanded(orders[42], true); // a row object (also if it is filtered out)

    Since

    1.1.97

  • Shows or hides the footer and repaints the table.

    A hidden footer takes no space – the body gets taller. Its rows stay in the model, so setFooterVisible(true) brings them back (an own footer model, e.g. totals, is asked for its values again). Requires a TableModel (what all factories create).

    Parameters

    • Optional visible: boolean = true

      false hides the footer

    Returns void

    Example

    // show the totals footer only while a filter is active
    tableApi.setFooterVisible(!!tableOptions.externalFilterFunction);
  • Collapses or expands a header group (CellGroupIf with toggle: true) – like a click on its toggle.

    Parameters

    • id: string

      CellGroupIf.id, otherwise the path of the labels, e.g. "Customer" or "2026/Q1"

    • collapsed: boolean = true

      true = collapse

    Returns boolean

    false if the header has no such group

    Example

    tableApi.setHeaderGroupCollapsed("Customer", true);
    

    Since

    1.1.92

  • Shows or hides the header and repaints the table.

    A hidden header takes no space – the body moves up and shows more rows. The header rows stay in the model (labels, sort icons, header groups), so setHeaderVisible(true) brings them back unchanged. Requires a TableModel (what all factories create).

    Parameters

    • Optional visible: boolean = true

      false hides the header

    Returns void

    Example

    // a compact view without column headers
    tableApi.setHeaderVisible(false);

    Example

    // toggle from a button
    document.querySelector("#toggle-header")!.addEventListener("click", () =>
    tableApi.setHeaderVisible(!tableApi.isHeaderVisible()));
  • Checks whether logging is currently active for the table component.

    This method returns the current state of logging for the table. When logging is active, the table outputs detailed information about its operations to the console, including:

    • Rendering processes and lifecycle events
    • Data modifications and updates
    • Event handling and user interactions
    • Performance metrics and state changes

    Logging can be toggled using the setLoggingActive(boolean) method.

    Parameters

    • active: boolean

    Returns void

    True if logging is currently enabled, false otherwise.

    Example

    // Check if logging is enabled
    if (tableApi.isLoggingActive()) {
    console.log("Table logging is currently active");
    }

    // Conditionally enable logging only if it's not already active
    if (!tableApi.isLoggingActive()) {
    tableApi.setLoggingActive(true);

    // Perform operations that need debugging
    tableApi.updateCells([
    {
    area: "body",
    rowIndex: 2,
    columnIndex: 3,
    value: "New Value",
    cssClasses: { "highlight": true }
    }
    ]);

    // Run some additional operations...

    // Disable logging when finished
    tableApi.setLoggingActive(false);
    }
  • Pivot table (PivotFactory): pivots again – other row fields, column fields or values, or new rows – without a new table model (a new model would rebuild the table in every framework wrapper). The model gets new columns, header and totals; rows whose path stays keep their expanded state, the filter stays, column widths of columns that stay are kept, so are columns hidden with setColumnVisible. Sorting, selection and focus are reset (the columns are different). An invalid configuration throws and changes nothing.

    Parameters

    • changes: Partial<PivotConfigIf<any>>

      the changed parts, e.g. { columnFields: ["jahr"] }; {} = pivot the current rows again (e.g. after new keys)

    • Optional rows: any[]

      new source rows (default: the current ones)

    Returns boolean

    false if the table model is no pivot table

    Example

    // a select with the column field
    select.addEventListener("change", () => tableApi.setPivotConfig({ columnFields: [select.value] }));

    Example

    tableApi.setPivotConfig({ values: [{ value: "umsatz", aggregator: "avg" }] });   // averages instead of sums
    tableApi.setPivotConfig({}, await loadSales()); // new data

    Since

    1.1.94

  • Tree tables: expands or collapses the displayed body row rowIndex (like a click on its arrow), repaints and remembers the state with autoRestoreOptions.

    Parameters

    • rowIndex: number

      index of the displayed body row

    • expanded: boolean

      the new state

    Returns boolean

    false if the table is no tree, the row does not exist or already has this state

    Example

    tableApi.setRowExpanded(0, true);   // expand the first row
    
  • Row grouping (RowGroupFactory): groups the rows by other levels – without a new table model (a new model would rebuild the table in every framework wrapper). Groups whose path stays keep their expanded state; filter, sorting and checked rows stay; the columns of the grouped properties are hidden (the previously grouped ones come back) and the header of the group column follows. An empty list shows the rows without groups.

    Parameters

    Returns boolean

    false if the body is no row grouping

    Example

    // a select with "region", "produkt", "region,produkt"
    select.addEventListener("change", () => tableApi.setRowGroupBy(select.value.split(",")));

    Example

    tableApi.setRowGroupBy([]);   // flat again (with the total row)
    

    Since

    1.1.94

  • Sets the rows data for the table body, replacing any existing rows.

    Only works with an AreaModelObjectArray body – logs a console warning otherwise. Does not repaint and resets filtering and sorting of the body: afterwards call externalFilterChanged (if a filter function is set) and repaintHard (the row count changed).

    Type Parameters

    • T

      The type of elements in the rows array

    Parameters

    • rows: T[]

      An array of data objects to set as the table's rows

    Returns void

    • This method doesn't return anything.

    Description

    This method replaces all existing rows in the table body with the provided array of data objects. It only works with tables that use AreaModelObjectArray as their body model.

  • Sets the selection model for the table.

    This method allows you to replace the current selection model with a new one, which controls how cells, rows, or columns can be selected in the table.

    Parameters

    • sm: SelectionModel

      The new selection model to be set. This model defines the selection behavior including selection type (none, cell, row, column), selection mode (single, multi), and manages the selected ranges.

    • Optional repaint: boolean = true

      Whether to repaint the table after changing the selection model. Default is true, which immediately reflects the change visually. Set to false if you want to avoid immediate repainting.

    Returns void

    Example

    // Create a new selection model with row selection and multi-select mode
    const selectionModel = new SelectionModel("row", "multi");

    // Set the new selection model and repaint the table
    tableApi.setSelectionModel(selectionModel);

    // Set a selection model without repainting (if you plan to make more changes)
    tableApi.setSelectionModel(selectionModel, false);
    // ... make other changes ...
    tableApi.repaint(); // Now repaint once
  • „Show values as“: shows the numbers of a column differently – share of the column total, running total, rank … (see ShowValuesAs) – or normal again (undefined). No new model: the table repaints.

    Parameters

    • property: string

      the property of the column

    • showValuesAs: undefined | ShowValuesAsConfig

      the mode (with options) or undefined for the values

    Returns boolean

    false if there is no such column or the mode is unknown

    Example

    select.addEventListener("change", () =>
    tableApi.setShowValuesAs("total", select.value ? select.value as ShowValuesAs : undefined));

    Since

    1.1.95

  • Shows "Loading…" with a CSS spinner over the body – e.g. while a server answers. The header and footer stay readable; rows already shown stay visible under a semi-transparent layer. By default mouse and editing on the body are blocked until hideOverlay (OverlayOptionsIf.blockInteractionWhileLoading). Screen readers: the host gets aria-busy="true", the text is announced.

    Texts, delay and own content: TableOptionsIf.overlayOptions. Framework wrappers have a loading prop that calls this method (no re-creation of the table).

    Parameters

    Returns void

    Example

    tableApi.showLoadingOverlay();
    fetch("/api/orders")
    .then(response => response.json())
    .then((orders: object[]) => {
    tableApi.setRows(orders);
    tableApi.repaintHard();
    })
    .finally(() => tableApi.hideOverlay()); // 0 rows? "No rows to show" appears by itself

    Since

    1.1.92

    See

    Training: Live data

  • Shows the "no rows" overlay, also over rows – e.g. when the server says "no permission". An empty body shows "No rows to show" anyway (OverlayOptionsIf.autoNoRows); this method is for other cases. Ends with hideOverlay.

    Parameters

    Returns void

    Example

    tableApi.showNoRowsOverlay("You may not see these orders");
    

    Since

    1.1.92

  • Sorts the table data using a custom comparison function.

    This method allows sorting of table rows by providing a custom comparison function. The comparison function should follow the standard JavaScript array sort comparator pattern, returning:

    • A negative number if the first element should be sorted before the second
    • A positive number if the first element should be sorted after the second
    • Zero if the elements are equal

    Parameters

    • compareFn: ((a, b) => number)

      A function that defines the sort order. The function should accept two arguments and return a number indicating their relative order: - Negative number: first argument should come before second - Positive number: second argument should come before first - Zero: elements are equal

        • (a, b): number
        • Parameters

          • a: any
          • b: any

          Returns number

    Returns void

    Example

    // Sort table rows by a specific property in ascending order
    tableApi.sort((a: Person, b: Person) => {
    if (a.name < b.name) return -1;
    if (a.name > b.name) return 1;
    return 0;
    });

    Example

    // Sort numbers in descending order
    tableApi.sort((a: { value: number }, b: { value: number }) => b.value - a.value);

    Example

    // Sort with multiple criteria
    tableApi.sort((a: Order, b: Order) => {
    // First sort by status
    const statusCompare = a.status.localeCompare(b.status);
    if (statusCompare !== 0) return statusCompare;

    // Then sort by name if status is equal
    return a.customer.localeCompare(b.customer);
    });

    Example

    // Case-insensitive string sorting
    tableApi.sort((a: Person, b: Person) =>
    a.name.toLowerCase().localeCompare(b.name.toLowerCase())
    );

    Example

    // Tree tables: the function compares the tree rows of siblings (your objects: a.data / b.data),
    // children stay below their parent
    tableApi.sort((a: TreeRowIf<OrderNode>, b: TreeRowIf<OrderNode>) => b.data.total - a.data.total);
  • Sorts by one column from code – e.g. from your own button – exactly like a double click on the column header: rows, header icon, filter (sort order survives filtering) and auto-restore.

    Parameters

    • column: string | number

      column index or property, e.g. "total"

    • Optional sortState: SortState

      "asc" or "desc"; omitted: toggles like the header (asc → desc → …)

    Returns boolean

    false if the column does not exist

    Example

    document.querySelector("#by-total")!.addEventListener("click", () => tableApi.sortByColumn("total", "desc"));
    
  • Starts a batch edit: from now on edited and filled values are collected – shown in the cells (class ge-table-cell-pending), but not written into your rows – until commitBatchEdit or cancelBatchEdit. Sorting, filtering, totals, copy and Excel use the written data. For a batch edit that is always on use TableOptionsIf.batchEdit.

    Returns boolean

    false if a batch edit is already running

    Example

    editButton.onclick = () => tableApi.startBatchEdit();
    saveButton.onclick = () => tableApi.commitBatchEdit();
    discardButton.onclick = () => tableApi.cancelBatchEdit();

    Since

    1.1.96

  • Opens the cell editor of a body cell – like F2 (caret at the end) or, with typedText, like typing that text. With Excel-style editing (TableOptionsIf.editing) the editor sits above the cell; otherwise (or for columns with an own getEditRenderer) it is rendered into the cell.

    Parameters

    • rowIndex: number

      display row index of the body

    • column: string | number

      model column index or property

    • Optional typedText: string

      starts in "enter" mode with this text (it replaces the content)

    Returns boolean

    true if an editor is open (false for a cell that cannot be edited)

    Example

    tableApi.startEditing(0, "price");          // edit the price of the first row
    tableApi.startEditing(4, "name", "Ad"); // as if "Ad" had been typed

    Since

    1.1.99

  • Closes an open cell editor: commits its input (like Enter without moving) or, with cancel, discards it (like Escape).

    Parameters

    • Optional cancel: boolean = false

      discard the input

    Returns boolean

    true if no editor is open afterwards (an invalid input keeps the editor open)

    Example

    saveButton.addEventListener("click", () => {
    tableApi.stopEditing(); // the value being typed belongs to the data that is saved
    });

    Since

    1.1.99

  • Adds an event listener next to the one the table was created with – e.g. for a toolbar or an own formula bar that lives outside the component that created the table. Every on… method you give is called after the main listener's; a listener that throws is logged and does not stop the others.

    Parameters

    Returns (() => void)

    call it to remove the listener (the table also removes all on destroy())

      • (): void
      • Adds an event listener next to the one the table was created with – e.g. for a toolbar or an own formula bar that lives outside the component that created the table. Every on… method you give is called after the main listener's; a listener that throws is logged and does not stop the others.

        Returns void

        call it to remove the listener (the table also removes all on destroy())

        Example

        const unsubscribe = tableApi.subscribe({
        onEditingChanged: (evt: GeEditEvent) => { hint.textContent = evt.type === "input" ? evt.input ?? "" : ""; },
        onModelChanged: (evt: GeModelChangeEvent) => console.log(`${evt.changes?.length ?? 0} cells changed`),
        });
        // later
        unsubscribe();

        Since

        1.1.99

    Example

    const unsubscribe = tableApi.subscribe({
    onEditingChanged: (evt: GeEditEvent) => { hint.textContent = evt.type === "input" ? evt.input ?? "" : ""; },
    onModelChanged: (evt: GeModelChangeEvent) => console.log(`${evt.changes?.length ?? 0} cells changed`),
    });
    // later
    unsubscribe();

    Since

    1.1.99

  • Expands a collapsed or collapses an expanded detail row (master/detail).

    Parameters

    • rowOrIndex: number | object

      display index or row object

    Returns boolean

    false if it is no master row (or no master/detail)

    Example

    tableApi.toggleDetail(3);   // e.g. from a button outside the table
    

    Since

    1.1.97

  • Triggers the action with the given action ID. This function can be invoked programmatically.

    Parameters

    • actionId: "COPY_2_CLIPBOARD" | "START_EDITING" | "TOGGLE_SELECTION" | "SELECT_ALL" | "DESELECT_ALL" | "NAVIGATE_LEFT" | "NAVIGATE_RIGHT" | "NAVIGATE_UP" | "NAVIGATE_DOWN" | "NAVIGATE_ROW_START" | "NAVIGATE_ROW_END" | "NAVIGATE_FIRST_CELL" | "NAVIGATE_LAST_CELL" | "NAVIGATE_PAGE_UP" | "NAVIGATE_PAGE_DOWN" | "ACTIVATE_CELL" | "MOVE_ROW_UP" | "MOVE_ROW_DOWN" | "FILL_DOWN" | "FILL_RIGHT" | "NAVIGATE_NEXT_CELL" | "NAVIGATE_PREVIOUS_CELL" | "EXTEND_SELECTION_UP" | "EXTEND_SELECTION_DOWN" | "EXTEND_SELECTION_LEFT" | "EXTEND_SELECTION_RIGHT" | "EXTEND_SELECTION_ROW_START" | "EXTEND_SELECTION_ROW_END" | "EXTEND_SELECTION_PAGE_UP" | "EXTEND_SELECTION_PAGE_DOWN" | "NAVIGATE_DATA_EDGE_UP" | "NAVIGATE_DATA_EDGE_DOWN" | "NAVIGATE_DATA_EDGE_LEFT" | "NAVIGATE_DATA_EDGE_RIGHT" | "EXTEND_TO_DATA_EDGE_UP" | "EXTEND_TO_DATA_EDGE_DOWN" | "EXTEND_TO_DATA_EDGE_LEFT" | "EXTEND_TO_DATA_EDGE_RIGHT" | "SELECT_ROW" | "SELECT_COLUMN" | "CLEAR_CELLS" | "CLEAR_AND_EDIT" | "CUT_2_CLIPBOARD" | "PASTE_FROM_CLIPBOARD" | "UNDO" | "REDO"

      The ID of the action to trigger.

    Returns boolean

  • Undoes the last change like Ctrl/⌘+Z (TableOptionsIf.undo): the old values are written back (onModelChanged with source "undo"), the cells are selected and scrolled into view. Not while the cell editor is open (it has its own text undo).

    Returns boolean

    true if a step was undone; false without the option or with nothing to undo

    Example

    undoButton.addEventListener("click", () => tableApi.undo());
    

    Since

    1.1.99

  • Updates the cells in the table with the provided cell update events.

    This method allows you to update specific cells in the table without requiring a full table repaint, which can significantly improve performance when updating large tables frequently.

    Parameters

    • events: TableCellUpdateEventIf[]

      An array of cell update events, each defining a single cell update operation. Each event must specify: - area: The table area to update ('header', 'body', or 'footer') - rowIndex: The row index of the cell to update - columnIndex: The column index of the cell to update - value: The new value to set for the cell - cssClasses: Optional object mapping CSS class names to boolean values (true to add the class, false to remove it)

    • Optional repaintAll: boolean = false

      Whether to repaint the entire table after updating cells. - If true: All cells will be repainted after updating (slower but ensures visual consistency) - If false: Only the modified cells will be repainted (faster, recommended for frequent updates)

    Returns void

    Example

    // Update a single cell with a new value and CSS classes
    tableApi.updateCells([{
    area: 'body',
    rowIndex: 3,
    columnIndex: 2,
    value: 42,
    cssClasses: {
    'highlight': true, // Add 'highlight' class
    'error': false // Remove 'error' class if present
    }
    }]);

    Example

    // Update multiple cells at once
    tableApi.updateCells([
    {
    area: 'body',
    rowIndex: 1,
    columnIndex: 1,
    value: 'New Value 1',
    cssClasses: { 'updated': true }
    },
    {
    area: 'body',
    rowIndex: 2,
    columnIndex: 3,
    value: 'New Value 2',
    cssClasses: { 'updated': true }
    }
    ]);

    Example

    // Update cells and repaint the entire table
    tableApi.updateCells([
    { area: 'body', rowIndex: 0, columnIndex: 0, value: 'Hello', cssClasses: { 'bg-green-0': true } },
    { area: 'body', rowIndex: 1, columnIndex: 1, value: 'World', cssClasses: { 'bg-red-0': true } }
    ], true);

    Example

    // High-performance animation example (update without full repaint)
    function animateCell() {
    const value = Math.sin(Date.now() / 1000) * 50;
    const cssClasses = {
    'positive': value > 0,
    'negative': value < 0
    };

    tableApi.updateCells([{
    area: 'body',
    rowIndex: 0,
    columnIndex: 0,
    value: Math.round(value),
    cssClasses
    }]);

    requestAnimationFrame(animateCell);
    }
    animateCell();
  • Updates existing rows in the table body with new data.

    Only works with an AreaModelObjectArray body – logs a console warning otherwise. The properties are copied into the existing objects; nothing is repainted – call repaint afterwards.

    Type Parameters

    • T

      The type of elements in the rows array

    Parameters

    • rows: T[]

      An array of data objects containing the updated values

    • predicate: ((a, b) => boolean) = ...

      A comparison function that determines which rows to update

      • Default predicate uses strict equality (===)
      • The function should return true if the row should be updated
        • (a, b): boolean
        • Parameters

          • a: T
          • b: T

          Returns boolean

    Returns void

    • This method doesn't return anything.

    Description

    This method updates existing rows in the table body with new values from the provided rows array. For each row in the table, if the predicate returns true when compared with any row in the provided array, all properties from the provided row will be copied to the existing row. It only works with tables that use AreaModelObjectArray as their body model.