Unify Logo Footer.svg
Unify Applications
Logo
Grouping & Filters

Grouping & Filters

Logo

7 mins READ

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

  1. Open Inspector → Content → Columns and click the add button.

  2. Pick Add Group (instead of Add Column). The group arrives with a starter child column and a placeholder name.

  3. 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

PropertyDefaultDescription
labelThe spanning header text. Translatable
visibilityshownHides the group and every column inside it
appearance.aligncenter (new groups), left (schema default)Alignment of the group label
appearance.headertext-xs / medium / text-primary / light brand backgroundFont, color and background of the spanning header
slots.Custom HeaderReplace the group header text with a block of your own
permissionsRestricts 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.

SettingValue
Where to setInspector → Content → Add-ons → Toolbar → Filter Source
TypeData source reference, or a bound list of field descriptors
Appears whenThe table's own source cannot supply a field list (typically a Mapped source)

Setting Up Custom Filters

  1. Create a data source that returns field metadata — an aggregation query, a report query, or any source whose response includes an aggregationFields array.

  2. Select that data source in Inspector → Content → Add-ons → Toolbar → Filter Source.

  3. 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.

PropertyRule
nameRequired. The field's key in your rows and its id in filter/sort conditions
displayNameOptional. The label users see in the menus. Falls back to name when missing
fieldTypeRequired. One of: TEXT, NUMBER, LONG, DOUBLE, BOOLEAN, DATE, DATE_TIME, KEYWORD, TIME_DURATION. Missing = entry dropped
filterableMust be true. Any falsy value hides the field from the Data filter menu
sortableSet true to put the field in the Sort menu. Independent from filterable
searchableSet true to include the field in keyword search. Independent from the others
lookupRequired 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:

BindingDescription
{{ 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.

PageRelationship
Toolbar & ViewsWhere Filter and Sort standard actions are added; Quick filters for one-click filtering
Column TypesChild columns inside a group use standard column configuration
Row Actions & SelectionSub Rows nest rows, not headers — a common source of confusion with column groups
Table OverviewData binding: Object vs Mapped source, and how filters integrate