Core Features

Advanced Features

Vue Data GridCalculated Columns - Dialog & Customisation

Version 36.3.0
Enterprise

Configure the dialog users create and edit calculated columns in, and customise the columns they create.

The Calculated Column dialog has three fields: Title, Type and Expression. Configure the dialog with the calculatedColumns grid option. Set it to true to enable the feature with the default dialog, or to an options object to enable the feature and customise the dialog.

Opening the Dialog Copy Link

Users open the dialog from the grid's menus; see Letting Users Add Columns. To open it from your own interface, call one of these grid API methods:

  • openCalculatedColumnDialog(column) to edit or view an existing calculated column, bringing its dialog forward if already open.
  • openAddCalculatedColumnDialog(sourceColumn?) to add one after a source column, or at the end when omitted.

Both methods focus the dialog and use the configured apply mode. Adding is unavailable in pivot mode.

// Call from an application button.
function onAddCalculatedColumn() {
    gridApi.openAddCalculatedColumnDialog();
}

Closing the dialog returns focus to the calculated column's header, scrolling it into view if needed. If a deferred Add was not applied, focus returns to the source column when supplied. Focus is not moved if you have already focused another element.

openCalculatedColumnDialogCopy Link
Function
Opens and focuses the dialog for an existing calculated column. Read-only calculated columns open in view mode. Reuses and brings forward an already-open dialog. On close, returns focus to the column's header, scrolling it into view if needed. Does nothing if Calculated Columns are disabled or the key does not resolve to a calculated column.
openAddCalculatedColumnDialogCopy Link
Function
Opens the Add Calculated Column dialog, optionally after a source column as with the column menu. Without a source column, the new column is appended. Unknown or non-primary source columns are ignored. Uses the configured apply mode: live creates the column immediately, deferred creates it on Apply. Moves focus into the dialog. Does not open in pivot mode. On close, returns focus to the new column's header, or the source column if no column was created.

Referencing Columns Copy Link

The dialog shows references by header name, for example [Revenue]. It translates these display references back to colId references before updating the column definition. Some headers need more than the header name:

  • Duplicate headers under column groups use the shortest unique group path, such as [2025 Q4] and [2026 Q4].
  • When two columns have the same header and the same group hierarchy, the dialog appends the colId, for example [2025 Q4 (revenue-q4)]. This keeps the reference stable when columns are reordered. Give your columns distinct headers or group hierarchies to avoid this.
  • A literal ] in a header name is escaped as ]]. For example, the header Revenue [USD] appears as [Revenue [USD]]]. The Columns picker inserts the escaped reference automatically; stored colId references are unchanged.

The following example has duplicate Q1, Q2, Q3 and Q4 headers under 2025 and 2026 column groups. The year groups start collapsed and show a calculated Total column; expanding a group reveals the quarter columns. The dialog shows grouped references such as [2025 Q4] and [2026 Q4], while the source code stores stable colId references such as [q4_2025] and [q4_2026].

Expression Editor Copy Link

The expression editor highlights references, functions and operators. Built-in errors mark the field invalid and have underlines, tooltips and accessible descriptions. Reference checks validate columns, not row availability. When validation runs, and what happens to invalid expressions, depends on the apply mode.

Expression Pickers Copy Link

Buttons beside the expression open the Columns, Functions and Operators pickers. Use expressionPickers to control which pickers appear. By default all three do:

<ag-grid-vue
    :calculatedColumns="calculatedColumns"
    /* other grid options ... */>
</ag-grid-vue>

this.calculatedColumns = {
    expressionPickers: ['columns'],
};

type CalculatedColumnExpressionPicker = 
      'columns' 
    | 'functions' 
    | 'operators'

This only controls the expression picker buttons. Use an empty array or null to hide all picker buttons. Inline autocomplete while typing in the expression editor remains available. The example in Column Highlighting shows only the Columns picker.

Column Highlighting Copy Link

While a column's dialog is open, the grid highlights the column's header and cells. Customise the highlight colour with the --ag-calculated-column-highlight-color CSS variable.

Use suppressColumnHighlighting to turn the highlight off. The default is false:

<ag-grid-vue
    :calculatedColumns="calculatedColumns"
    /* other grid options ... */>
</ag-grid-vue>

this.calculatedColumns = {
    suppressColumnHighlighting: true,
};

The following example sets both expressionPickers: ['columns'] and suppressColumnHighlighting: true:

In the example, edit Profit. The dialog shows only the Columns picker, and the Profit column is not highlighted while the dialog is open. In the other examples on this page, the column being edited is highlighted.

Data Types Copy Link

Use dataTypes to control which cell data types appear in the dialog's Type dropdown. The default is ['text', 'number', 'date', 'boolean']. The list can include built-in cell data types and custom types registered with dataTypeDefinitions:

<ag-grid-vue
    :dataTypeDefinitions="dataTypeDefinitions"
    :calculatedColumns="calculatedColumns"
    :columnDefs="columnDefs"
    /* other grid options ... */>
</ag-grid-vue>

this.dataTypeDefinitions = {
    currency: {
        extendsDataType: 'number',
        baseDataType: 'number',
        valueFormatter: params =>
            params.value == null ? '' : `$${params.value.toLocaleString()}`,
    },
};
this.calculatedColumns = {
    dataTypes: ['currency', 'number', 'boolean'],
};
this.columnDefs = [
    { field: 'revenue', cellDataType: 'currency' },
    { field: 'cost', cellDataType: 'currency' },
    {
        colId: 'profit',
        headerName: 'Profit',
        calculatedExpression: '[revenue] - [cost]',
        cellDataType: 'currency',
    },
];
  • Give your own columns the same types, as the snippet does for revenue and cost, so a user who picks Currency in the dialog gets the same formatting.
  • A valueFormatter on a column definition cannot be selected in the dialog, so it is not available to users.
  • Built-in types use the grid's locale text, while custom type names are converted to readable labels in the dialog.
  • If a selected value does not match a registered Cell Data Type, the grid's normal cellDataType validation applies when the calculated column is created.

In the example, edit Profit and open the Type dropdown. It lists Currency, Number and Boolean.

Applying Changes Copy Link

The applyMode option sets when dialog edits reach the column. The default is 'live':

Live (default)Deferred (applyMode: 'deferred')
Title, type and expressionUpdate the column as you typeHeld until the user clicks Apply; the dialog shows Apply and Cancel buttons
Add Calculated ColumnCreates the column and opens the dialog over itCreates the column when the user clicks Apply
Invalid expressionsStill apply, and render formula errors in cells until fixedValidated as you edit and on Apply, and not applied while invalid

In live mode:

  • Empty expressions remain valid.
  • Custom validation and reference restrictions still apply.
  • Closing the dialog keeps the latest state; remove the column with Remove Calculated Column.
  • Expression edits containing references excluded by isColumnReferenceable are saved but blocked from evaluation, preserving the full text for correction.

Deferred Mode Copy Link

Set applyMode: 'deferred' to hold changes until the user clicks Apply:

<ag-grid-vue
    :calculatedColumns="calculatedColumns"
    /* other grid options ... */>
</ag-grid-vue>

this.calculatedColumns = {
    applyMode: 'deferred',
};

type CalculatedColumnApplyMode = 'live' | 'deferred'

In deferred edit dialogs, validation runs as you edit and on Apply, not when the dialog opens.

In the example, edit Profit and change its expression. The cells change only when you click Apply.

Debouncing Live Edits Copy Link

Set applyDebounce to wait for a quiet period before applying live dialog edits. This delays both the cell repaint and calculated-column change events:

<ag-grid-vue
    :calculatedColumns="calculatedColumns"
    /* other grid options ... */>
</ag-grid-vue>

this.calculatedColumns = {
    applyDebounce: 400,
};
  • The default is 0, which applies on the next animation frame.
  • Closing the dialog applies any pending edit immediately; removing the column cancels it.
  • State and column-definition APIs report the last applied values while an edit is pending.
  • This option has no effect in deferred mode.

Customising User-Created Columns Copy Link

Use processColDef to customise calculated columns that users create in the dialog, for example to add a filter or allow aggregation. It receives the column's own definition, as set in the dialog, and returns the definition to use. The returned definition takes precedence over defaultColDef and column types:

<ag-grid-vue
    :calculatedColumns="calculatedColumns"
    /* other grid options ... */>
</ag-grid-vue>

this.calculatedColumns = {
    processColDef: (params) => ({
        ...params.colDef,
        filter: true,
        enableValue: params.colDef.cellDataType === 'number',
    }),
};

Spread params.colDef to preserve the user's settings. Omitted properties use normal column defaults, except calculatedExpression, which retains the user's expression.

In the example, the Profit column is restored from Grid State as if a user had created it, so it has a filter button and can be aggregated from the column menu.

Properties available on the CalculatedColumnProcessColDefParams<TData = any, TContext = any> interface.

The column's own definition: the properties set in the Calculated Column dialog, before defaultColDef and column types are merged in. A fresh copy is passed on every call.
The column the calculated column was added from, i.e. the one its menu was opened on. null when it was added from no column, or when that column is gone. A column restored from Grid State is not tied to the column it was added from: it gets the last column of its group, or null if it is not in a group.
expressionValidationCopy Link
CalculatedColumnExpressionValidation
Validation of colDef.calculatedExpression, including syntax, direct column references and saved dialog rejections from getValidationErrors or isColumnReferenceable. Does not rerun application callbacks or check row-specific evaluation errors. In 'live' apply mode, the expression may be incomplete.
The grid api.
Application context as set on gridOptions.context.

params.expressionValidation includes syntax and reference errors plus saved dialog rejections from getValidationErrors and isColumnReferenceable, matching expressionValidation on the calculatedColumnChanged event. It does not rerun these callbacks or check row-specific evaluation errors.

When the Callback Runs Copy Link

  • The callback runs each time the column is built, including when dialog edits are applied and on restore from Grid State.
  • It does not run for calculated columns declared in columnDefs.
  • The dialog and Grid State keep the user's values, not the callback's.
  • colId, editable, suppressPaste, field, valueGetter, valueSetter, cellEditor and cellEditorSelector are always overridden.
  • Prefer initial* properties, such as initialWidth, to stateful ones.
  • The definitions from api.getColumnDefs() include the callback's output; see Managing Columns with Column Definitions.

Making Created Columns Read-Only Copy Link

processColDef can return calculatedColumnReadOnly: true to make user-created columns read-only. In live mode, calculatedColumnReadOnly: true locks the column when the initial Add dialog closes, even if the expression is empty or invalid.

To leave blank columns editable, return the full definition with the flag true only when there is an expression: { ...params.colDef, calculatedColumnReadOnly: !!params.colDef.calculatedExpression?.trim() }.

A non-empty expression may still be unfinished; use applyMode: 'deferred' to require Apply before creating and locking the column.

See Read-Only Calculated Columns for what a read-only column allows.