Optional ariaThe id of an element that describes the table, e.g. a hint below it (aria-describedby of the grid).
// <p id="orders-hint">Double click a header to sort.</p>
const tableOptions: TableOptionsIf = { ...new TableOptions(), ariaDescribedBy: "orders-hint" };
1.1.91
Optional ariaThe accessible name of the table for screen readers (aria-label of the grid), e.g. "Orders".
Prefer ariaLabelledBy if the page shows a title.
const tableOptions: TableOptionsIf = { ...new TableOptions(), ariaLabel: "Orders" };
1.1.91
Live demo: accessible order table · Training: Accessible tables: keyboard and screen readers
Optional ariaThe id of the element that names the table, e.g. a heading above it (aria-labelledby of the grid).
Takes precedence over ariaLabel.
// <h2 id="orders-title">Orders 2026</h2> <div class="table-div"></div>
const tableOptions: TableOptionsIf = { ...new TableOptions(), ariaLabelledBy: "orders-title" };
1.1.91
Optional ariaOwn texts for screen readers – announcements (sorting, filter, copy, select all) and the names of the row checkboxes and header group toggles. Functions you leave out keep their English default (AriaTexts).
const tableOptions: TableOptionsIf = {
...new TableOptions(),
ariaTexts: {
filtered: (rowCount: number) => `${rowCount} Zeilen`,
copied: (cellCount: number) => `${cellCount} Zellen kopiert`,
selectRow: (rowNumber: number) => `Zeile ${rowNumber} auswählen`,
},
};
1.1.91
Optional autoRemember sorting, scroll position and expanded tree nodes in localStorage. Off by default.
Optional batchBatch edit always on: edited and filled values are collected (marked ge-table-cell-pending) and written with
TableApi.commitBatchEdit or discarded with TableApi.cancelBatchEdit. Without it, start a batch
edit with TableApi.startBatchEdit (it ends with commit or cancel).
const tableOptions: TableOptionsIf = { ...new TableOptions(), batchEdit: true };
1.1.96
Live demo: fill handle & batch edit · Training: Fill handle and batch edit
Optional cellCell formulas like in Excel: a text with a leading = in the data (row.total = "=B2*C2") is calculated –
references A1, $B$3, B2:D10, A:A, ≈ 70 functions, dependencies are recalculated after every write.
Row 1 is the first row of getAllRows() (sorting and filtering keep the references), column A the first data
column (row numbers and checkboxes don't count). The data keep the formula text; sorting, filters, totals, copy
and the Excel export use the results. '=… is the text =…. true = every data column with the defaults of
CellFormulaOptions; { columns: ["total"] } = only these properties. Flat bodies only (objects or
arrays; a tree, row grouping, pivot table or master/detail: a warning, no formulas). Not set: "=1+1" is text.
const tableOptions: TableOptionsIf = {
...new TableOptions(),
editing: { defaultEditable: true },
cellFormulas: true,
};
1.1.99
Optional clipboardCopy, cut and paste like Excel and Google Sheets: Ctrl/⌘+C puts tab-separated text (with Excel's quoting) and an
HTML table into the clipboard, Ctrl/⌘+X marks the range (dashed frame) and moves it on paste, Ctrl/⌘+V pastes
from the anchor – tiled over a selected range, cut off at the last column, skipping read-only cells; one
onModelChanged with source: "paste" (or "cut"). true = defaults (ClipboardOptions); without the
option Ctrl/⌘+C copies as before and Ctrl/⌘+X/V do nothing.
const tableOptions: TableOptionsIf = {
...new TableOptions(),
getSelectionModel: () => new SelectionModel("range", "multi"),
editing: true,
clipboard: true,
};
1.1.99
The width of the column resize handle in pixels.
Flag indicating whether the columns are draggable.
Represents whether the columns are resizable.
Row heights of header, body and footer in px (default 34 / 34 / 34). Read by TableFactory.createTableModel
when it creates the area models – pass the options there as tableOptions, too.
Optional directionWriting direction: "ltr" (default), "rtl" for Arabic, Hebrew, Persian, Urdu … (first column on the right,
horizontal scrolling, fixed columns, tree indent, resize handles and arrow keys mirrored) or "auto" (the
direction of the page: dir="rtl" on <html> or a parent element). Read once when the table is built – a new
options object rebuilds the table in the wrappers.
In right-to-left, the "left" and "right" in names of the API mean start and end:
fixedLeftColumnCount fixes columns at the start (right), fixedRightColumnCount at the end (left),
ge-table-text-align-left aligns to the start. The table sets dir on its host element (also dir="ltr").
const tableOptions: TableOptionsIf = { ...new TableOptions(), direction: "rtl" };
1.1.98
Live demo: right-to-left · Training: Right-to-left
Optional editingExcel-style editing: typing on a focused cell opens the editor (the text is replaced), Enter edits, Enter/Tab
commit and move on, Shift+arrows extend the selection, Ctrl/⌘+arrows jump to the edge of the data, Delete
clears the selected cells, Ctrl/⌘+Enter writes into all selected cells. The editor lives above the cell and
survives scrolling. true = defaults (EditingOptions); without the option the table behaves as before
(F2/double click edit, Enter activates, Tab leaves the table).
const selectionModel = new SelectionModel("range", "multi");
const tableOptions: TableOptionsIf = {
...new TableOptions(),
getSelectionModel: () => selectionModel,
editing: { defaultEditable: true }, // every data column can be edited
};
1.1.99
Your filter: called for every row, return true to show it. After changing the filter criteria call
TableApi.externalFilterChanged – the table filters again and keeps the sort order.
const filter = { text: "" };
const tableOptions: TableOptionsIf = {
...new TableOptions(),
externalFilterFunction: (order: Order) => order.customer.toLowerCase().includes(filter.text)
};
searchInput.addEventListener("input", () => {
filter.text = searchInput.value.toLowerCase();
tableApi.externalFilterChanged();
});
Training: Filtering with a live search
Optional fillThe fill handle: a small square at the bottom right corner of the selected range. Dragging it fills the
neighbouring cells (copy, or a series: 1, 2, 3 …, dates, Item 1 → Item 2); ⌥/Alt switches between series and
copy. Keyboard: Ctrl/⌘+D fills down, Ctrl/⌘+R fills right. Needs a selection model of the type "range";
only editable cells are filled. true = defaults (FillHandleOptions).
const selectionModel = new SelectionModel("range", "multi"); // one model – not a new one per call
const tableOptions: TableOptionsIf = {
...new TableOptions(),
getSelectionModel: () => selectionModel,
fillHandle: true,
};
1.1.96
Live demo: fill handle & batch edit · Training: Fill handle and batch edit
Determines whether the fixed east separator border is visible.
Indicates whether the fixed west separator border should be visible.
Indicates whether the footer separator border is visible or not.
Indicates whether a vertical separator should be displayed in the footer.
Optional getThe editor for a cell, if the column has no own ColumnDefIf.getEditRenderer. Default: a text input (InputCellRenderer).
Training: Inline editing
Optional getReturns the focus model of the table. Default: every table creates its own FocusModel.
Optional getReturns the selection model of the table. Without it every table creates its own new SelectionModel()
of type "none" – nothing can be selected.
const selectionModel = new SelectionModel("row", "single");
const tableOptions: TableOptionsIf = { ...new TableOptions(), getSelectionModel: () => selectionModel };
Training: Select cells, rows and ranges
Icons of collapsible header groups (AreaModelCellGroups).
Indicates whether the header separator border is visible.
Reserved – currently not evaluated (tree tables always show the expand-all / collapse-all icon in the top left header cell).
Represents whether a vertical separator should be displayed in a header.
1.0.0
Represents the visibility of the horizontal border.
Flag indicating whether the hover color of a column is visible or not in general. If true, the column get the hover background color while the mouse is over the column.
Flag indicating whether the hover color of a row is visible or not in general. If true, the row get the hover background color while the mouse is over the row.
Optional initialThe state the table starts with: column layout, sorting, tree, checked and selected rows … – e.g. loaded from your server (TableApi.getState, EventListenerIf.onStateChanged). A state stored by autoRestoreOptions wins over it, part by part.
const saved = (await (await fetch("/api/prefs/orders")).json()) as TableStateIf | null;
const tableOptions: TableOptionsIf = { ...new TableOptions(), initialState: saved ?? undefined };
1.1.92
Live demo: persisted layout · Training: Remember the state
Optional masterMaster/detail: master rows get an expand icon; below an expanded row a detail row over the full width shows any
content (a nested table, a form, a framework component – see MasterDetailOptionsIf). Only for flat body
models. Fields you leave out keep their default (MasterDetailOptions); detailRenderer is required.
const tableOptions: TableOptionsIf = {
...new TableOptions(),
masterDetail: {
detailHeight: "auto",
detailRenderer: (container, row) => { container.textContent = `Notes: ${row.notes}`; }
}
};
1.1.97
Live demo: master/detail · Training: Master/detail
The value of the css overflowX determines the behavior of horizontal overflow for the table body (scroll port).
The value of the css overflowX determines the behavior of vertical overflow for the table body (scroll port).
Optional overlayTexts and behaviour of the overlays over the body: "Loading…" (TableApi.showLoadingOverlay), "No rows to show" (empty body, automatic) and "No matching rows" (the filter hides all rows). Fields you leave out keep their default (OverlayOptions).
const tableOptions: TableOptionsIf = {
...new TableOptions(),
overlayOptions: { noRowsText: "No orders yet", blockInteractionWhileLoading: false },
};
1.1.92
Live demo: loading & empty states · Training: Loading and empty tables
The delay in milliseconds used for debouncing the resize event.
Optional rowRow drag: managed or events only, multi-row drag, tree drop, auto-scroll (see RowDragOptionsIf). The drag handles come from ColumnDefIf.rowDrag. Fields you leave out keep their default (RowDragOptions).
const tableOptions: TableOptionsIf = {
...new TableOptions(),
rowDragOptions: { managed: false }, // only events – e.g. the server decides
};
1.1.95
Live demo: row drag · Training: Dragging rows into order
Optional shortcutOwn keyboard shortcuts: maps a shortcut (e.g. "ctrl+c", "f2") to an ActionId.
Default: WindowsShortcutActionIdMapping resp. OsxShortcutActionIdMapping.
Switch off all keyboard shortcuts of the table (copy, select all, navigation, F2 …).
Indicates whether to show checkbox without an extra column. If true and the row is checkable, a checkbox is rendered in the first column. If false and the row is checkable, a checkbox is rendered in an extra column left to the first column.
Training: Tree table with checkboxes
The order of the sort states on repeated double-clicks on a header, default ["asc", "desc"].
Add "" to get "unsorted" as third state. Per column: ColumnDefIf.sortStatesOrder.
The sort icons shown in sortable header cells.
Optional spreadsheetPreset „like a spreadsheet“ for existing models: switches on editing (with defaultEditable), clipboard,
undo, cellFormulas and fillHandle – unless the options set them themselves – and a range selection.
An object switches single parts off (false) or configures them (SpreadsheetOptionsIf). For a new, empty
sheet use SpreadsheetFactory; column letters above existing headers: TableFactory.createTableModel({ …, columnLetters: true }).
const tableOptions: TableOptionsIf = { ...new TableOptions(), spreadsheet: true };
1.1.99
Optional stateDelay in ms between the last change of the state (resize, sort, scroll …) and EventListenerIf.onStateChanged / the save of autoRestoreOptions. Default 300.
1.1.92
Specifies whether the bottom border of a table is visible.
Indicates whether the top border of a table is visible or hidden.
Icons and behaviour of tree tables (arrows, indentation). See TreeOptionsIf.
Optional undoUndo and redo: Ctrl/⌘+Z undoes the last change – an edit, a fill, a paste, a cut, Delete – as one step,
Ctrl+Y or Ctrl/⌘+Shift+Z redoes it (source "undo"/"redo" in onModelChanged). Cells are found by their row
object (sorting and filtering in between don't matter). true = defaults (UndoOptions); without the option
Ctrl/⌘+Z does nothing (as before). In a batch edit the marked values are undone; commit and cancel empty the
history.
const tableOptions: TableOptionsIf = {
...new TableOptions(),
editing: true,
clipboard: true,
undo: true,
};
1.1.99
Indicates whether the vertical border is visible.
Represents the options for configuring a table.
Start from the defaults in TableOptions and change only what you need.
Example
See
Training: TableOptions: behaviour and look