Grouped Columns
A grouped column puts a shared header above a set of related columns — users see a two-tier header where the group label spans its child columns (for example "Address" spanning Street, City and Zip). Grouping affects only the header; rows are not grouped or aggregated.
Note: Grouped columns ≠ grouped rows. To band rows under collapsible headings (orders grouped by customer), use the Group Table block variant. To nest child rows under a parent row, use Sub Rows — see Row Actions & Selection. Grouped columns only arrange headers.
Creating a Column Group
Open Inspector → Content → Columns and click the add button.
Pick Add Group (instead of Add Column). The group arrives with a starter child column and a placeholder name.
Drag existing columns into the group, or add new ones inside it. Each child is configured like any other column — see Column Types.
Group Configuration
| Property | Default | Description |
label | — | The spanning header text. Translatable |
visibility | shown | Hides the group and every column inside it |
appearance.align | center (new groups), left (schema default) | Alignment of the group label |
appearance.header | text-xs / medium / text-primary / light brand background | Font, color and background of the spanning header |
slots.Custom Header | — | Replace the group header text with a block of your own |
permissions | — | Restricts who sees the group and its columns |
Nesting Groups
A group's children can themselves be groups. Use Add Group inside an existing group to create a third (or deeper) header tier. Every rule applies through the whole subtree: hiding a group hides all columns at every depth inside it, a group disappears when nothing inside it is visible, and a group stretches when anything inside it stretches.
Column Group Behavior
Warning: A group with no visible children disappears entirely. Hide every child through visibility conditions, permissions or the column-visibility menu and the group header vanishes with them.
Warning: Hiding the group hides all of its columns. The group's own visibility condition gates the whole subtree.
Note: The group stretches when any child stretches. If any child column is set to grow into available space, the whole group grows with it.
Custom Filters (Filter Source)
Object-backed tables already know their fields, so their filter and sort menus fill themselves. A Mapped source, expression-fed source, or aggregation-style query knows nothing — until you hand it a field list through Filter Source. Once set, the toolbar's Filter and Sort menus and a quick filter's Data condition offer exactly the fields you supplied.
| Setting | Value |
| Where to set | Inspector → Content → Add-ons → Toolbar → Filter Source |
| Type | Data source reference, or a bound list of field descriptors |
| Appears when | The table's own source cannot supply a field list (typically a Mapped source) |
Setting Up Custom Filters
Create a data source that returns field metadata — an aggregation query, a report query, or any source whose response includes an
aggregationFieldsarray.Select that data source in Inspector → Content → Add-ons → Toolbar → Filter Source.
In the same Toolbar panel, add the Filter and Sort standard action. Its field pickers now list your custom fields.
Alternatively, bind Filter Source directly to a page variable or function that returns the field descriptor array.
Field Descriptor Structure
Every entry in the supplied list is one filterable/sortable field. Entries that break any rule are dropped silently without a warning.
| Property | Rule |
name | Required. The field's key in your rows and its id in filter/sort conditions |
displayName | Optional. The label users see in the menus. Falls back to name when missing |
fieldType | Required. One of: TEXT, NUMBER, LONG, DOUBLE, BOOLEAN, DATE, DATE_TIME, KEYWORD, TIME_DURATION. Missing = entry dropped |
filterable | Must be true. Any falsy value hides the field from the Data filter menu |
sortable | Set true to put the field in the Sort menu. Independent from filterable |
searchable | Set true to include the field in keyword search. Independent from the others |
lookup | Required when fieldType is KEYWORD. A reference that resolves the keyword's allowed values. Aggregation sources supply this automatically |
Warning: Filter Source fills the menu, not the query. On a Mapped source, supplying a field list makes fields appear in the menus but does not make filtering happen. The applied filter only reaches your rows when you bind {{ id.filters.filter }} into your data source's own inputs.
Note: When the list comes from a data source response, the platform reads the field array from a key named aggregationFields in the response. A custom endpoint that puts the array under a different key supplies nothing and the menus stay empty.
Filter Source Overrides Auto-Detection
When Filter Source is set, the menus use only your supplied list — fields the table's main data source could have auto-detected are no longer used. Remove Filter Source to go back to auto-detection.
How Filters Are Applied
Object-source tables
Filter, search and sort are applied to the query server-side automatically. The table sends the current filter, sort and search values to the server with every refetch. You do not need to wire anything.
Mapped-source tables
The table never filters its rows client-side. It only writes the current filter state to {{ id.filters }}. You must bind these values into your data source's inputs for filtering to have any effect:
| Binding | Description |
{{ id.filters.filter }} | The current data filter (null when no filter is applied) |
{{ id.filters.sort }} | The current sort configuration |
{{ id.filters.search }} | The current keyword search text |
{{ id.filters.timeFilter }} | The current date range filter |
Note: When the filter is cleared, {{ id.filters.filter }} becomes null — not an empty object. Handle the null case in your data source binding to return the full unfiltered set.
Frequently Asked Questions
My filter menu is empty even though I set a Filter Source. What should I check?
Check each field descriptor in order: Does it have a fieldType from the supported list? Is filterable explicitly set to true? If the type is KEYWORD, does it have a lookup? Fields that break any rule are silently dropped — there is no error message. Also confirm the response carries the field array under the key aggregationFields; a different key name is ignored.
I set a filter in my table, but the data source is not filtering. Why?
On a Mapped source, the table only writes the filter to {{ id.filters.filter }} — it does not apply the filter to the data itself. You must bind {{ id.filters.filter }} into your data source's inputs (as a query parameter or request body) and handle the null case (no filter active → return all data).
Can I group rows by a column's value (like a Kanban per status)?
Not in the standard Data Table block. Grouped columns create a two-tier header arrangement, not row groupings. To band rows under collapsible group headers per a field value (like a status), use the Group Table block variant. For a Kanban-style layout, use the Kanban block.
My column group header disappeared from the table. Where did it go?
Every child column inside it is hidden. A group header only exists while at least one child is visible — visibility conditions, permissions, or the user's column-visibility menu can all hide the last child and take the header with it. Check each child column's visibility and permissions settings.
Can I put a filter component outside the table and drive the table from it?
Yes — for a Mapped source, bind the external filter component's value into your data source's inputs. The data source re-runs whenever its inputs change, and the table renders the new results. Do not use the table's addFilterItem method for this — it only opens a filter row in the toolbar for the user to fill in; it cannot set a value programmatically.
Related Pages
| Page | Relationship |
| Toolbar & Views | Where Filter and Sort standard actions are added; Quick filters for one-click filtering |
| Column Types | Child columns inside a group use standard column configuration |
| Row Actions & Selection | Sub Rows nest rows, not headers — a common source of confusion with column groups |
| Table Overview | Data binding: Object vs Mapped source, and how filters integrate |