@guiexpert/table
v1.1.113
Published
This is the base component of the GuiExpert Table Project. One can use this in a plain JS project.
Readme
GuiExpert Table with plain JS
This is the base component of the GuiExpert Table Project. One can use this in a plain JS project.
Become a master at creating web applications with large tables
This is the UI-agnostic table component for your next web app. 😊
Features
- Handle large datasets easily
- Excellent performance for large tables by vertical and horizontal virtual scrolling
- Fully-featured (advanced sorting and filtering)
- Highly customizable orderData grid
- Outstanding performance
- No third-party dependencies
- UI-agnostic
- Column Interactions (resize, reorder)
- Sorting Rows
- Row, Column, and Range Selection
- Single and Multi Selection
- UI-agnostic
- Row and Column Spanning
- Fixed Columns (Left and Right)
- Tree table (Hierarchical View)
- Accessibility: screen readers (WAI-ARIA grid/treegrid, row/column counts with virtual scrolling, announcements of sorting, filter and copy) and full keyboard navigation (arrows, Home/End, Page Up/Down, header focus, Enter) – since 1.1.91
- Overlays "Loading…" (CSS spinner,
tableApi.showLoadingOverlay(),loadingprop in the wrappers) and "No rows to show" / "No matching rows" (automatic) – plain HTML/CSS, since 1.1.92 - Row numbers like in a spreadsheet (
rowNumbersVisible: trueorRowNumberColumnDef): fixed on the left, width fits the largest number, click selects the row, view or original order – since 1.1.93 - Aggregation: total rows in the footer that follow filter and sorting (
footerAggregates: { quantity: "sum", total: "avg" },AreaModelAggregateFooter), helpersaggregate()/aggregateColumns()with mergeable aggregators (sum, count, avg, min, max, countDistinct, first, last or your own), and count/sum/average of the selected cells for a status bar (tableApi.getSelectionAggregates()) – since 1.1.94 - Row grouping with aggregation: flat rows grouped by one or more properties or functions, group rows with arrow,
label (
"Berlin (12)") and sum/average/… per column, total row, filter and sorting by aggregate, regroup at runtime (RowGroupFactory.createTableModel({ rows, groupBy, aggregations }),tableApi.setRowGroupBy()) – since 1.1.94 - Pivot tables: row fields (a hierarchy with subtotals) × column fields (their values become columns, several fields
= a multi-row header with collapsible groups) × aggregated values, total column and total row, filter before the
aggregation, pivot again at runtime (
PivotFactory.createTableModel({ rows, rowFields, columnFields, values }),tableApi.setPivotConfig(), enginepivotRows()) – since 1.1.94 - Calculated columns (
ColumnDef.valueGetter– sorting, filter viatableApi.getRowValue(), copy, Excel, totals and row grouping use the computed value), „Show values as“ (showValuesAs: share of the column / row / grand / parent total, running total, difference, rank – also per pivot value) and formulas (formula: "[price] * [quantity] * 1.19", own parser and interpreter withouteval, functions likeROUND,IF,SUM([x]), error values#DIV/0!,tableApi.setColumnFormula()) – since 1.1.95 - Row drag: drag handle per row (
ColumnDef.rowDragorrowDrag: truein the factory), mouse, touch and pen, ghost, drop marker, auto-scroll, Escape, keyboard alternative Ctrl+Alt+↑/↓, several selected rows, trees; the table moves the rows (managed) or only reports the drop (rowDragOptions: { managed: false },onRowDragEnd) – since 1.1.95 - Fill handle and batch edit: a square at the corner of the selected range copies values or continues series (numbers,
dates,
Item 1→Item 2; ⌥/Alt switches, Ctrl/⌘+D, Ctrl/⌘+R), batch edit collects changes (ge-table-cell-pending) untiltableApi.commitBatchEdit()/cancelBatchEdit(),ColumnDef.validate, oneonModelChangedper change with old and new values (tableOptions.fillHandle,tableOptions.batchEdit) – since 1.1.96 - Master/detail: expandable rows with a detail row over the full width (nested table, form, framework component),
created lazily and kept while scrolling, fixed or measured height, keyboard (Enter, Tab) and screen readers
(
aria-expanded),tableApi.setDetailExpanded()/expandAllDetails(), stored with the table state (tableOptions.masterDetail) – since 1.1.97. Variable row heights use prefix sums (O(log n) per scroll frame) - Right-to-left (Arabic, Hebrew, Persian, Urdu):
tableOptions.direction: "rtl"(or"auto"from the page) mirrors the whole table – first column on the right, horizontal scrolling, fixed columns, tree indent, resize handles, fill handle, row drag, master/detail, arrow keys; right-to-left Excel sheet – since 1.1.98 - Excel-style editing (
tableOptions.editing): type to overwrite, F2, Enter/Tab, Delete, Ctrl+Enter, Ctrl+arrow to the data edge, IME; copy, cut and paste with Excel and Google Sheets (clipboard); undo and redo of every change (undo,tableApi.undo()) – since 1.1.99 - Spreadsheet cell formulas (
tableOptions.cellFormulas):=B2*C2,$A$1, ranges, 70 Excel functions, a dependency graph that recalculates only dependent cells, colored references and pointing while typing, Excel export with real formulas – own parser, noeval.SheetEngineworks without a table – since 1.1.99 - Spreadsheet mode:
SpreadsheetFactory.create({ data })builds column letters, row numbers, a sparse body (a million empty rows cost nothing) and all of the above;FormulaBar, insert/delete rows and columns with adjusted references;spreadsheet: truefor an existing table – since 1.1.99 - Live data that keeps coming (a log tail, an event stream):
tableApi.appendRows(rows, { follow: "auto", maxRows })– in place, O(k) per update, filter and sort order only for the new rows, selection and focus stay at their rows, follow the end or freeze the view, ring buffer; own area models:rowsAppended(count)– since 1.1.108 - Custom Filtering
- In-place Cell Editing
- Userdefined Key and Mouse Events
- Customizable Look & Feel (via CSS variables)
- Row sorting
- Column Reordering (Drag and Drop)
- Column drag events and locks:
onColumnResizeEnd/onColumnMoveEndonce per drag (after the change – save the layout there),ColumnDef.resizable: false/movable: falseper column, a column stays in its fixed area, a double click on the resize handle fits the width (columnAutoWidth,tableApi.autoResizeColumn(), flat with millions of rows) – since 1.1.110 - State persistence: column layout (width, order, visibility), sorting, scroll position, tree, checked and selected
rows, header groups – in
localStorage(autoRestoreOptions) or on your server (tableApi.getState()/applyState(),initialState,onStateChanged); stored by property and row id, never by index – since 1.1.92 - Customizable Cell Contents via Renderer for Header, Body and Footer
- Full control over the HTML structure and style
Quick answers
- Hide the scroll bars:
.my-table .ge-table-scroll-viewport { scrollbar-width: none; }– the table uses the full width and height; wheel, touch, keyboard and the API still scroll. - Rows are appended all the time (live log, ticker):
tableApi.repaintHard({ py })counts the rows and shows the position in one render pass (py: Number.MAX_SAFE_INTEGERfollows the end) – since 1.1.107. - Rows arrive all the time (log, stream)?
tableApi.appendRows(rows, { follow: "auto", maxRows })– in place, one render, selection stays (since 1.1.108); notaddRows()(copies everything, resets filter and sort). - Clicks lost while the table updates? Fixed in 1.1.108: a render between
mousedownandmouseupno longer swallowsmouseClicked– the table reports the click for the pressed cell itself. - Own area model with other row heights: return them from
getRowHeight(i)and, if all are equal,getConstantRowHeight()– the scroll height follows them (since 1.1.107;defaultRowHeightsis only the default). repaint()orrepaintHard()?repaint()for changed values,repaintHard()when rows were added or removed.- Own keys (Delete, Enter):
keydownon the host +tableApi.getActiveCell()– there is no keyboard event. - Selected rows:
selectionModel.getMergedRowIndices(n)→tableApi.getBodyModel().getRowByIndex(i)(pass your ownSelectionModel– the default type is"none"). - Save the column layout when the user drags a column:
onColumnResizeEnd/onColumnMoveEnd(wrapperscolumnResizeEnd,columnMoveEnd) – once per drag, after the change, only for the user (since 1.1.110). Lock one column:ColumnDef.resizable: false,movable: false. - AI assistants:
llms.txtin this package – recipes and pitfalls, every snippet compiled against the API. - Nothing visible? The host div needs a fixed height and the stylesheet
@guiexpert/table/css/main.css.
More: FAQ in the developer guide.
Links
Get Started
Add the following NPM package to your existing plain JS project (run this in your project root directory):
npm install --save @guiexpert/tableAdd an empty element to your html code:
<div
class="container-div"
style="width:100%;height:100%;background:transparent;margin:0;padding:0;"
></div>If you are working with plain JS, you don't need to do this. If you are using TypeScript as a language, please import the following classes:
import {
EventAdapter,
SimpleDomService,
TableModelIf,
TableOptions,
TableScope } from "@guiexpert/table";Create a table model. Select ('querySelector') the element and create a table scope. Finally, call firstInit() at least once. In this example, you will see the plain TS version. For plain JS, remove ': TableModelIf'.
const tableModel: TableModelIf = TableFactory.createTableModel({
headerData: [
['Header 1', 'Header 2']
],
bodyData: [
['Text 1a', 'Text 2a'],
['Text 1b', 'Text 2b'],
]
});
const ele = document.querySelector(".container-div") as HTMLDivElement;
const tableScope = new TableScope(
ele, tableModel, new SimpleDomService(), new TableOptions(), new EventAdapter()
);
tableScope.firstInit();There are numerous possibilities to create table models. Please refer to the Documentation for further information or the Demo section for examples.
License
Current releases: MIT License. All currently published versions are free to use, modify and distribute – also in commercial and proprietary applications. See LICENSE.
Future releases: possible dual licensing. Dr. Marc Kronberg (gui.expert) reserves the right to publish future versions under different terms (e.g. open source for individuals and non-commercial use, commercial license for businesses). Versions already released under MIT remain MIT. Details: gui.expert/license.
