Columns overview
Columns define how Grid renders headers, cells, layout, and per-column
interactions. Use columnDefaults to define shared behavior and columns[]
to override individual columns when needed.
Defaults
{columnDefaults: {cells: {format: "<span>{value}</span>"},sorting: {enabled: false}},columns: [{id: "product",sorting: {enabled: true}}]}
The columnDefaults object defines shared options for all columns in the
Grid. The columns[] array is used to override those defaults or add
column-specific behavior where needed.
Most options in columnDefaults are mirrored 1:1 in columns[].
Working with data (autogenerateColumns)
data.autogenerateColumns controls how Grid combines provider columns with
columns[] configuration.
true(default): provider columns are rendered automatically. Ifheaderis not set, they keep provider order. Columns configured incolumns[]that are not present in provider data (for example unbound/computed columns) are appended at the end incolumns[]order.false: provider columns are not rendered automatically. Grid renders only columns explicitly defined incolumns[](or referenced byheader).
Example: append custom column in auto-generation mode
Grid.grid('container', {data: {columns: {product: ['Apple', 'Pear', 'Plum', 'Banana'],weight: [100, 40, 0.5, 200],price: [1.5, 2.53, 5, 4.5]}},columns: [{id: 'weight',enabled: false}, {id: 'lineValue',dataId: null,dataType: 'number',cells: {valueGetter: cell => cell.row.data.weight * cell.row.data.price,format: '${value:,.2f}'}}]});// Rendered order (no header): product, price, lineValue
Example: manual column set only
Grid.grid('container', {data: {autogenerateColumns: false,columns: {product: ['Apple', 'Pear', 'Plum', 'Banana'],price: [3.24, 2.62, 5.99, 4.74],revenue: [120, 85, 200, 150],ignoredByConfig: ['A', 'B', 'C', 'D']}},columns: [{id: 'sum',dataId: null,cells: {valueGetter: cell => cell.row.data.revenue * cell.row.data.price}}, {id: 'sales',dataId: 'revenue'}, {id: 'price'}, {id: 'product'}]});// Rendered columns: sum, sales, price, product
Summary columns (columnAggregator)
A summary column derives its value from the other columns of the same row, for
example a Total column summing quarterly columns. It is the per-row mirror of
a summary row. Set columnAggregator to an aggregation function name (SUM,
AVERAGE, MIN, MAX, COUNT, MEDIAN, PRODUCT, ...) and list the source
columns in aggregatedColumns:
Grid.grid('container', {data: {columns: {region: ['North', 'South'],q1: [120, 80],q2: [140, 85]}},columns: [{// No source column provides `total`, so the column is unbound.id: 'total',columnAggregator: 'SUM',aggregatedColumns: ['q1', 'q2']}]});
aggregatedColumnsis optional. When omitted, every other numeric column of the table is aggregated, skipping columns that are derived themselves. List the columns explicitly when the table holds numeric columns that must stay out of the result, such as an id or a year.- Without an explicit
dataType, a summary column is assumed numeric. - The header and body cells always carry the
hcg-summary-columnclass, so styling them needs noclassNameof your own. - The cells are derived, so they are never editable.
- The value is re-resolved whenever a cell of its row is edited.
- By default only the rendered cells are resolved, which keeps the column out of
sorting, filtering, and exports. Set
materializeto change that.
Sorting, filtering and exporting (materialize)
Sorting and filtering are stages of the data pipeline, not of rendering: they run on the data table before anything aggregates. A summary column resolved per cell has no column in that table, so there is nothing to sort by.
materialize: true writes the aggregate into the queried table ahead of the
sorting and filtering modifiers, which makes the column behave like a regular
data column — while the cells stay read-only:
columns: [{id: 'total',columnAggregator: 'SUM',aggregatedColumns: ['q1', 'q2'],materialize: true}]
What it costs, and when not to use it:
- One pass over every row on each query, instead of resolving only the cells on screen. With virtualized data that is the difference between all rows and a screenful.
- A cell edit becomes a requery rather than a cheap refresh of the row.
- It needs a local data provider. Sorting and filtering of a remote provider run
on the server, which knows nothing about the column, so
materializeis ignored there and reported in the console. - The aggregator callback runs before sorting and filtering, so its
rowIndexaddresses the source table, androwIdis only resolved whendata.idColumnis set. - Under TreeView or row grouping the column behaves like any other data column:
give it a
rowAggregatorfor parent rows to aggregate it.
Pass a callback to decide per row, returning a function name or a falsy value to skip aggregation and leave the column's own data in place:
columns: [{id: 'total',aggregatedColumns: ['q1', 'q2'],columnAggregator: context => context.rowIndex === 0 ? false : 'SUM'}]
For logic no Formula function covers, use cells.valueGetter instead. It
receives the cell, derives the value from cell.row.data, takes precedence over
columnAggregator, and follows edits the same way:
columns: [{id: 'margin',dataId: null,dataType: 'number',cells: {valueGetter: cell => cell.row.data.revenue - cell.row.data.cost}}]
See the summary columns demo.
Aggregating down a column instead — one value per column over many rows — is
what rowAggregator and
summary rows do.
Styling and Theming
Use column-level classes, inline styles, and theme variables to control how headers and body cells look. See Styling and Theming.
Header
Headers can be configured per column with columns[].header or structurally
with the root header[] option for order, inclusion, and grouped headers.
See Column headers.
Grouping
Use grouped headers when several columns belong under a shared label.
Grouping is defined in the root header[] option and can be nested. See
Column grouping.
Width and resizing
Columns can use fixed widths, percentages, or automatic distribution, and end users can optionally resize them from the header. See Column width and resizing.
Sorting
Sorting can be enabled per column or globally, with support for initial ordering, custom compare logic, and multicolumn sorting. See Column sorting.
Filtering
Filtering adds popup or inline filter controls to individual columns, with conditions based on each column's data type. See Column filtering.
Virtualization
Wide grids render only the columns visible in the viewport, which keeps the DOM small and the initial render fast. See Column virtualization.
Cell formatting
Cell output is configured through columns[].cells, including template
formatting, formatter callbacks, and edit-mode behavior. See
Cell formatting.