Skip to content

Tables & lists

Three elements show record collections. Pick by task:

ElementData directionUse for
TableDisplays server dataBrowsing, searching, and acting on records
Dynamic tableCollects user dataEditable rows the user adds/removes (part of the form result)
List gridDisplays dataCard-style record lists with a custom template

Table (table)

The full-featured data table. It reads rows from a data source and everything below is configurable from the properties sidebar.

Start simple

A working table needs only: a data source, Items path, and 2–3 columns. Add search, actions, and pagination once the data shows up.

Row context in expressions and actions: {row.fieldName} — e.g. a row action with condition {row.status} == "draft". Selected rows: {__table.<tableName>.selectedRows}.

Primary source & request

PropertyWhat it does
Data source namePrimary source from the DataSources tab. Example: loadUsers.
Items path (optional)Path to the array in the response, e.g. data.items. Empty = auto-detection.
Request paramsAdditional TABLE-POST params (up to 5 rows): Param name + Value / {path}.
Lazy loadLoad per page/sort from the server instead of everything upfront.
Total path (lazy)Path to the total record count, e.g. meta.total or totalCount. Optional — total, totalCount, totalRecords, count, cnt (and the same names nested under paging.*) are auto-detected without setting this.
Order clauseSort expression the backend expects.
Order directionasc / desc, used with the order clause or column sorting.

With Lazy load on, set the data source's Method to TABLE-POST — this sends a real POST but automatically merges the current page/sort/search state into the request body for you. For the exact request/response JSON your backend must implement, see Table: server-side paging & filtering in the developer docs — hand that section to whoever builds the endpoint.

PropertyWhat it does
Show quick searchOne short field for quick filtering.
Quick search placeholderSay what can be searched here.
Quick search param nameRequest parameter for the value, e.g. q or searchTerm.
Quick search conditionMatch mode: contains %-%, not contains !%-%, starts with %-, ends with -%, equals =, not equals !=.
Quick search case modeCase-insensitive latin, case sensitive, uppercase, or lowercase comparison.
Quick search debounce (ms)Time between the last keystroke and the request.
Show detailed searchThe expanded block with per-column filters, operators, and values.
Detailed search case modeCase handling for detailed search.

Per-column filter settings live on each column — see Columns below.

Columns

Columns holds the column schema. Each column has:

Column fieldWhat it does
KeyData key in the row object; nested paths allowed (user.name, status).
Label / Mobile labelHeader text; the mobile variant falls back to Label when empty.
AlignColumn text alignment.
SortableWhether sorting is allowed by this column.
Show in table / Show in detailsWhere the column appears (main table and/or the details view).
Detail labelOptional different name in the details view.
Show header labelHide header text for action/checkbox/technical columns.
Header groupGroup header above the column — adjacent columns with the same name merge.
TemplateCustom cell HTML, e.g. {{value}} {{row.status}}.
Template refReference to a Templates-tab template (takes priority over inline HTML).
Filter control typeDetailed-search control for this column: auto, select, toggle
Filter options / JSON / data source (+ items path, label key, value key)Where the filter's choices come from: manual list, JSON, or a data source.
Filter toggle true/false valueWhat a detailed-search toggle sends when on/off (yes/no, T/N).
Filter multi-value delimiterJoins multiple filter values into one request param (, or ;).
Status rulesCondition + tone (+ label, icon, rounded) rules that render the cell as a status badge. Conditions support {row.*}, {value}. Example: [{ "condition": "{row.submitted} == \"Y\"", "label": "Submitted", "tone": "success", "icon": "check_circle", "rounded": true }].
Show status iconStatus badges show an icon (tone default when the rule has none).
Checked if / Enabled ifFor interactive toggle/checkbox columns: what controls the checked state ({row.disabled} == true) and whether clicking is allowed ({row.canEdit} == true).
Cell actions (+ enabled, display mode, placeholder)Actions on the cell: dropdown/buttons for regular columns; fired on click for toggle/checkbox columns. Context: row, parentRow, column, checked.
Use totals (+ fraction digits, locale, grouping, mask, template)Show this column's sum in the footer row, with formatting controls and a {total} text template.
Editable / Editor type / Editor options (+ label key, value key, placeholder)Inline-edit settings for this column: which control edits it (text, number, select, date) and where its choices come from.

Actions

PropertyWhat it does
Row actionsActions for each row — dropdown or buttons. Quick presets: View, Edit, Copy, Delete.
Row actions displaydropdown, iconButtons, or buttons (icon + text).
Row actions menu button styleDefault or borderless three-dot button.
Row action visibility pathRow field that decides whether actions show for that record.
Row click actionsActions fired by clicking the whole row (navigate, open details, select).
Row expand actionsActions for the expanded-row scenario.
Selection actions + labelBulk actions applied to selected rows (export, delete, status change).
Actions label / Show actions header labelThe actions column header text, and whether to show it.

Every action uses the standard action editor — a row button can navigate to /clients/{row.id} or call an endpoint with id = row.id.

Selection

PropertyWhat it does
Enable multi selectCheckbox selection. Selected records: {__table.<name>.selectedRows} (and .selectedItems with a template).
Selection key pathUnique field identifying rows, e.g. id or classifier.id.
Auto select ifAuto-select rows after refresh. Example: {row.status} == "Y".
Selected item templateHow each selected row becomes an entry in selectedItems: empty = whole row; row.oraId = an ID array; JSON like {"oraId":"{row.oraId}"} = custom objects.

Expanded rows & details

PropertyWhat it does
Expandable rowsMaster switch — without it neither inline nested tables nor the side panel work.
Expanded display modeinline (below the row) or sidePanel (side details panel).
Show expand chevron in first columnChevron appears only on rows that can actually expand.
Open details on row clickRow click opens details — no separate button needed.
Expanded rows pathPath in the row object to the nested array (orgList, details.items).
Expanded datasource (+ items path)Alternative: call a data source on expand instead of reading a nested array. Example: organizationsByUser.
Expanded columnsNested-table columns (same schema as Columns).
Expanded row actionsActions on nested records; context adds parentRow / tableRow. Example: [{ "label": "Open", "type": "navigate", "navigateTo": "/org/{parentRow.id}/{row.id}" }].
Expanded content template (HTML)Free-form details markup: {{value}}, {{row.xxx}}, {{item.xxx}}.
Expanded empty messageText when a row has no nested records.
Details panel titleTitle of the side details panel.

Pagination

PropertyWhat it does
PaginatorShows pagination controls.
Page sizeRecords per page.
Page size options + Show page size selectorLet users pick from e.g. 10,25,50,100 — only values the backend supports.
Paginator variantfull, pager, numbers, simple.
Paginator alignStart / center / end.
Paginator max buttonsHow many page buttons show at once.
Show record countTotal results summary near the paginator.
Flat footer surfaceFooter without extra border/shadow accents.

Header controls

PropertyWhat it does
Show header controlsMaster switch for the header bar (search, export, menu…).
Show export buttonsCSV / Excel / PDF export — generated entirely in the browser from the rows the table already has (or re-fetches with a larger page size for "export all"). There is no separate server-side export endpoint to build.
Export column picker dialogChoose which columns to export — useful for wide tables.
Export file nameDefault download name.
Export all page sizeBatch size when exporting all pages of a lazy table.
Column settings (Show column settings)End users change visible columns, order, and widths.
Column settings modeWhere preferences live: local UI, localStorage, or host/server.
Column settings storage keylocalStorage key when persisting between sessions.
Column settings datasource / path / save datasource / dialog titleServer-backed column settings: load source + response path, save source, and dialog title.
Header template (HTML) / Header template refCustom content in the header center — inline HTML or a Templates-tab reference.
Header added elements positionWhere drag-and-dropped header elements align: left / center / right.
Header dropdown (+ placeholder, items path, datasource, datasource items path, static options, label key, value key)An extra dropdown in the header — its options come from a path, data source, or manual list.
Header dropdown actionsActions fired by menu items (navigate, data source…).
Flat header surfaceHeader without extra surface accents.

Inline edit

PropertyWhat it does
Enable inline editEdit cells in place, without a dialog.
Inline edit start modeSingle click, double click, or an action button.
Inline edit save datasourceWhere changed rows are sent.
Cancel inline edit on reloadDrop unsaved edits when the table reloads.

Appearance & performance

PropertyWhat it does
Table styledefault, grid, striped.
Row hoverHover state for rows.
Sticky headerHeader (with search/filters/export) sticks while scrolling.
Responsive modeauto or stack on mobile.
Empty state textText when the table has no data.
Virtual scroll (+ buffer, row height, viewport height)Renders only visible rows for huge datasets. Set an accurate row height; the buffer trades smoothness for DOM size.

Texts

PropertyWhat it does
Prev / Next labelPagination button texts.
Loading labelText during load.
Select all / Select / Select row labelSelection checkbox labels (also used for accessibility).
Expand / Collapse labelExpand-button texts.

Dynamic table (dynamicTable)

An input element: spreadsheet-like rows the user fills in. The value is an array of objects, exactly like a Dynamic panel but in table form.

PropertyWhat it does
ColumnsEach column is itself an element (text, number, select, multi-select, radio, checkbox, datepicker, textarea…) with its own validation.
Add row button text / Remove row button textButton captions.
Disallow adding rows / Disallow deleting rowsLock the row count.
Max rowsUpper limit — the add button disables when reached.
Confirm row deletionAsk before removing, with Delete confirm title / message / confirm & cancel button texts.
Hide row ifExpression that hides matching rows: {row.status} != "A".
Status rulesCondition + tone rules that color the whole cell background.
Total templateFooter text with {total}, e.g. Total: {total}.

Row context inside cells: row.otherColumn, row.index. Aggregates outside: sumInArray({orderLines}, "amount").

Example — order lines:

  • Columns: product (select with data source), quantity (number), price (number, read-only, filled by expression from the product), total (number, Expression: toNumber(row.quantity) * toNumber(row.price)).
  • Below the table, a read-only Number named orderTotal with Expression: sumInArray({orderLines}, "total").

List grid (listGrid)

Renders each record of a data source as a card using an HTML template — product cards, employee directory, dashboards.

PropertyWhat it does
Data source / Items pathWhere records come from.
Card templateHTML with {{item.xxx}} placeholders and @if(...) blocks — inline or from the template library via Card template ref (ref wins).
LayoutList or grid display.
Grid column count / Grid minimum column width / Min card width / GapGrid geometry.
Quick search (Run search / Clear search / placeholder)Built-in search bar over the records.
Sort control (Show sort control + Sort field)A sort button; requires the field to sort by (name, createdAt, user.lastName).
Infinity scrollLoads the next page as the user nears the bottom — a paginator alternative for card lists.
Total pathTotal record count in the response for lazy loading (total, data.totalCount, paging.total).
Empty messageText when there are no records.

Template example:

html
<div class="card">
  <strong>{{ item.name }}</strong>
  <span>{{ item.city }}</span>
  @if (item.status == "Active") {<span class="ok">{{ item.status }}</span>}
</div>