---
title: "Formula Editor Component"
enterprise: true
framework: vue
version: "36.1.0"
---

# Formula Editor Component

The Formula Cell Editor is the default editor for columns with `allowFormula: true`. It tokenises cell references, highlights ranges, and provides function autocomplete while you type.

## Default Formula Editor

If a column enables formulas and does not specify a `cellEditor`, the grid automatically uses the Formula Cell Editor.

#### Formula Editor

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import {
  CellSelectionOptions,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GetRowIdFunc,
  GetRowIdParams,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  NumberEditorModule,
  TextEditorModule,
  ValueFormatterParams,
  enableDevValidations,
} from "ag-grid-community";
import { CellSelectionModule, FormulaModule } from "ag-grid-enterprise";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  CellSelectionModule,
  ClientSideRowModelModule,
  FormulaModule,
  NumberEditorModule,
  TextEditorModule,
]);

const currencyFormatter = ({ value }: ValueFormatterParams) =>
  `$ ${Number(value).toFixed(2)}`;

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <ag-grid-vue
      style="width: 100%; height: 100%;"
      @grid-ready="onGridReady"
      :columnDefs="columnDefs"
      :getRowId="getRowId"
      :cellSelection="cellSelection"
      :defaultColDef="defaultColDef"
      :rowData="rowData"></ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi | null>(null);
    const columnDefs = ref<ColDef[]>([
      { field: "item" },
      { field: "price", valueFormatter: currencyFormatter },
      { field: "qty" },
      { field: "total", allowFormula: true, valueFormatter: currencyFormatter },
    ]);
    const getRowId = ref<GetRowIdFunc>((params: GetRowIdParams) =>
      String(params.data.id),
    );
    const cellSelection = ref<boolean | CellSelectionOptions>({
      handle: {
        mode: "fill",
      },
    });
    const defaultColDef = ref<ColDef>({
      editable: true,
      flex: 1,
    });
    const rowData = ref<any[] | null>([
      {
        id: 1,
        item: "Apples",
        price: 1.2,
        qty: 4,
        total: '=REF(COLUMN("price"),ROW(1))*REF(COLUMN("qty"),ROW(1))',
      },
      {
        id: 2,
        item: "Bananas",
        price: 0.5,
        qty: 6,
        total: '=REF(COLUMN("price"),ROW(2))*REF(COLUMN("qty"),ROW(2))',
      },
      {
        id: 3,
        item: "Oranges",
        price: 0.8,
        qty: 3,
        total: '=REF(COLUMN("price"),ROW(3))*REF(COLUMN("qty"),ROW(3))',
      },
      {
        id: 4,
        item: "Pears",
        price: 1.4,
        qty: 2,
        total: '=REF(COLUMN("price"),ROW(4))*REF(COLUMN("qty"),ROW(4))',
      },
      {
        id: 5,
        item: "Grapes",
        price: 2.1,
        qty: 3,
        total: '=REF(COLUMN("price"),ROW(5))*REF(COLUMN("qty"),ROW(5))',
      },
      {
        id: 6,
        item: "Strawberries",
        price: 1.8,
        qty: 4,
        total: '=REF(COLUMN("price"),ROW(6))*REF(COLUMN("qty"),ROW(6))',
      },
    ]);

    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;
    };

    return {
      gridApi,
      columnDefs,
      getRowId,
      cellSelection,
      defaultColDef,
      rowData,
      onGridReady,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

[Live example: Formula Editor](https://www.ag-grid.com/examples/formula-editor-component/formula-editor-component/vue3/)

> **Note**
>
> Range highlights and range handle editing require `cellSelection` to be enabled. Without it, the editor still works but range highlights and handles are not shown.

## Disabling the Formula Cell Editor

Providing a `cellEditor` opts the column out of the Formula Cell Editor. Formulas still evaluate, but range highlighting, handles, and function autocomplete are disabled because a different editor is in use.

#### Formula Editor Disabled

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GetRowIdFunc,
  GetRowIdParams,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  NumberEditorModule,
  TextEditorModule,
  ValueFormatterParams,
  enableDevValidations,
} from "ag-grid-community";
import { FormulaModule } from "ag-grid-enterprise";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  ClientSideRowModelModule,
  FormulaModule,
  NumberEditorModule,
  TextEditorModule,
]);

const valueFormatter = ({ value }: ValueFormatterParams) =>
  `$ ${Number(value).toFixed(2)}`;

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <ag-grid-vue
      style="width: 100%; height: 100%;"
      @grid-ready="onGridReady"
      :columnDefs="columnDefs"
      :getRowId="getRowId"
      :defaultColDef="defaultColDef"
      :rowData="rowData"></ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi | null>(null);
    const columnDefs = ref<ColDef[]>([
      { field: "item" },
      { field: "price", valueFormatter },
      { field: "qty" },
      {
        field: "total",
        allowFormula: true,
        cellEditor: "agTextCellEditor",
        valueFormatter,
      },
    ]);
    const getRowId = ref<GetRowIdFunc>((params: GetRowIdParams) =>
      String(params.data.id),
    );
    const defaultColDef = ref<ColDef>({
      editable: true,
      flex: 1,
    });
    const rowData = ref<any[] | null>([
      {
        id: 1,
        item: "Apples",
        price: 1.2,
        qty: 4,
        total: '=REF(COLUMN("price"),ROW(1))*REF(COLUMN("qty"),ROW(1))',
      },
      {
        id: 2,
        item: "Bananas",
        price: 0.5,
        qty: 6,
        total: '=REF(COLUMN("price"),ROW(2))*REF(COLUMN("qty"),ROW(2))',
      },
      {
        id: 3,
        item: "Oranges",
        price: 0.8,
        qty: 3,
        total: '=REF(COLUMN("price"),ROW(3))*REF(COLUMN("qty"),ROW(3))',
      },
      {
        id: 4,
        item: "Pears",
        price: 1.4,
        qty: 2,
        total: '=REF(COLUMN("price"),ROW(4))*REF(COLUMN("qty"),ROW(4))',
      },
      {
        id: 5,
        item: "Grapes",
        price: 2.1,
        qty: 3,
        total: '=REF(COLUMN("price"),ROW(5))*REF(COLUMN("qty"),ROW(5))',
      },
      {
        id: 6,
        item: "Strawberries",
        price: 1.8,
        qty: 4,
        total: '=REF(COLUMN("price"),ROW(6))*REF(COLUMN("qty"),ROW(6))',
      },
    ]);

    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;
    };

    return {
      gridApi,
      columnDefs,
      getRowId,
      defaultColDef,
      rowData,
      onGridReady,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

[Live example: Formula Editor Disabled](https://www.ag-grid.com/examples/formula-editor-component/formula-editor-component-disabled/vue3/)

## Validation

Invalid formulas already surface via the formula engine: the cell displays the error and shows a tooltip based on the grid's formula error state. Because of this, the Formula Cell Editor does not validate on every change by default.

To opt into validation while editing, set `validateFormulas: true` on the editor params. Validation will also run if you provide a custom [getValidationErrors](https://www.ag-grid.com/vue-data-grid/cell-editing-validation/#overriding-validation) callback. For more details on validation behaviour and presentation, see [Cell Editing Validation](https://www.ag-grid.com/vue-data-grid/cell-editing-validation/).

```js
const columnDefs = [
    {
        field: 'total',
        allowFormula: true,
        cellEditorParams: {
            validateFormulas: true,
        },
    },
];
```

#### Formula Editor Validation

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import {
  CellSelectionOptions,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GetRowIdFunc,
  GetRowIdParams,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  NumberEditorModule,
  TextEditorModule,
  ValueFormatterParams,
  enableDevValidations,
} from "ag-grid-community";
import { CellSelectionModule, FormulaModule } from "ag-grid-enterprise";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  CellSelectionModule,
  ClientSideRowModelModule,
  FormulaModule,
  NumberEditorModule,
  TextEditorModule,
]);

const valueFormatter = ({ value }: ValueFormatterParams) => {
  if (typeof value === "string" && value.startsWith("#")) {
    return value;
  }
  const numericValue = Number(value);
  return Number.isFinite(numericValue)
    ? `$ ${numericValue.toFixed(2)}`
    : String(value ?? "");
};

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <ag-grid-vue
      style="width: 100%; height: 100%;"
      @grid-ready="onGridReady"
      :getRowId="getRowId"
      :columnDefs="columnDefs"
      :cellSelection="cellSelection"
      :defaultColDef="defaultColDef"
      :rowData="rowData"></ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi | null>(null);
    const getRowId = ref<GetRowIdFunc>((params: GetRowIdParams) =>
      String(params.data.id),
    );
    const columnDefs = ref<ColDef[]>([
      { field: "item" },
      { field: "price", valueFormatter: valueFormatter },
      { field: "qty" },
      {
        field: "total",
        allowFormula: true,
        valueFormatter: valueFormatter,
        cellEditorParams: {
          validateFormulas: true,
        },
      },
    ]);
    const cellSelection = ref<boolean | CellSelectionOptions>({
      handle: {
        mode: "fill",
      },
    });
    const defaultColDef = ref<ColDef>({
      editable: true,
      flex: 1,
    });
    const rowData = ref<any[] | null>([
      {
        id: 1,
        item: "Apples",
        price: 1.2,
        qty: 4,
        total: '=REF(COLUMN("price"),ROW(1))*REF(COLUMN("qty"),ROW(1))',
      },
      {
        id: 2,
        item: "Bananas",
        price: 0.5,
        qty: 6,
        total: "=B2*",
      },
      {
        id: 3,
        item: "Oranges",
        price: 0.8,
        qty: 3,
        total: '=REF(COLUMN("price"),ROW(3))*REF(COLUMN("qty"),ROW(3))',
      },
      {
        id: 4,
        item: "Pears",
        price: 1.4,
        qty: 2,
        total: '=REF(COLUMN("price"),ROW(4))*REF(COLUMN("qty"),ROW(4))',
      },
      {
        id: 5,
        item: "Grapes",
        price: 2.1,
        qty: 3,
        total: "=BADFUNC(1)",
      },
      {
        id: 6,
        item: "Plums",
        price: 1.5,
        qty: 2,
        total: '=REF(COLUMN("price"),ROW(6))*REF(COLUMN("qty"),ROW(6))',
      },
      {
        id: 7,
        item: "Strawberries",
        price: 1.8,
        qty: 4,
        total: '=REF(COLUMN("price"),ROW(7))*REF(COLUMN("qty"),ROW(7))',
      },
    ]);

    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;
    };

    return {
      gridApi,
      getRowId,
      columnDefs,
      cellSelection,
      defaultColDef,
      rowData,
      onGridReady,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

[Live example: Formula Editor Validation](https://www.ag-grid.com/examples/formula-editor-component/formula-editor-component-validation/vue3/)
