---
title: "Cell Editing"
framework: react
version: "36.1.0"
---

# Cell Editing

## Enable Editing

To enable Cell Editing for a Column use the `editable` property on the Column Definition.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `editable` | `boolean \| EditableCallback` |  | `false` | Set to `true` if this column is editable, otherwise `false`. Can also be a function to have different rows editable. When grouping, see `groupRowEditable` instead for group rows. |

```jsx
const [columnDefs, setColumnDefs] = useState([
    {
        field: 'athlete',
        // enables editing
        editable: true
    }
]);

<AgGridReact columnDefs={columnDefs} />
```

By default, the grid uses [Cell Data Types](https://www.ag-grid.com/react-data-grid/cell-data-types/) to provide different editors based on the type of each column. For example, string columns will use a text input, number columns will use a numeric input.

The example below shows editing enabled on all columns by setting `editable=true` on the `defaultColDef`.

#### Simple Cell Editing

```tsx
"use client";

import React, {
  useCallback,
  useMemo,
  useRef,
  useState,
  StrictMode,
} from "react";
import { createRoot } from "react-dom/client";
import { AgGridReact, AgGridProvider } from "ag-grid-react";
import {
  ClientSideRowModelApiModule,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  ModuleRegistry,
  NumberEditorModule,
  TextEditorModule,
  enableDevValidations,
} from "ag-grid-community";
import { IOlympicData } from "./interfaces";
import { useFetchJson } from "./useFetchJson";

if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

const modules = [
  NumberEditorModule,
  TextEditorModule,
  ClientSideRowModelApiModule,
  ClientSideRowModelModule,
];

const GridExample = () => {
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);

  const [columnDefs, setColumnDefs] = useState<ColDef[]>([
    { field: "athlete" },
    { field: "age" },
    { field: "country" },
    { field: "year" },
    { field: "total" },
  ]);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      editable: true,
    };
  }, []);

  const { data, loading } = useFetchJson<IOlympicData>(
    "https://www.ag-grid.com/example-assets/olympic-winners.json",
  );

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div style={gridStyle}>
          <AgGridReact<IOlympicData>
            rowData={data}
            loading={loading}
            columnDefs={columnDefs}
            defaultColDef={defaultColDef}
          />
        </div>
      </div>
    </AgGridProvider>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(
  <StrictMode>
    <GridExample />
  </StrictMode>,
);
```

[Live example: Simple Cell Editing](https://www.ag-grid.com/examples/cell-editing/simple-editing/reactFunctionalTs)

## Conditional Editing

To dynamically determine which cells are editable, a callback function can be supplied to the `editable` property on the Column Definition:

```jsx
const [columnDefs, setColumnDefs] = useState([
    {
        field: 'athlete',
        // conditionally enables editing for data for 2012
        editable: (params) => params.data.year == 2012
    }
]);

<AgGridReact columnDefs={columnDefs} />
```

In the snippet above, **Athlete** cells will be editable on rows where the **Year** is `2012`.

This is demonstrated in the following example, note that:

- An `editable` callback is added to the **Athlete** and **Age** columns to control which cells are editable based on the selected **Year**.
- A custom `editableColumn` [Column Type](https://www.ag-grid.com/react-data-grid/column-definitions/#default-column-definitions) is used to avoid duplication of the callback for **Athlete** and **Age**.
- Buttons are provided to change the **Year** used by the `editable` callback function to control which cells are editable.
- A blue [Cell Style](https://www.ag-grid.com/react-data-grid/cell-styles/) has been added to highlight editable cells using the same logic as the `editable` callback.

#### Conditional Cell Editing

```tsx
"use client";

import React, {
  useCallback,
  useMemo,
  useRef,
  useState,
  StrictMode,
} from "react";
import { createRoot } from "react-dom/client";
import { AgGridReact, AgGridProvider } from "ag-grid-react";
import "./styles.css";
import {
  CellClassParams,
  CellStyleModule,
  ClientSideRowModelApiModule,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  ColTypeDefs,
  EditableCallbackParams,
  GridApi,
  GridOptions,
  ModuleRegistry,
  NumberEditorModule,
  RowApiModule,
  TextEditorModule,
  enableDevValidations,
} from "ag-grid-community";
import { IOlympicData } from "./interfaces";
import { useFetchJson } from "./useFetchJson";

if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

const modules = [
  RowApiModule,
  NumberEditorModule,
  TextEditorModule,
  CellStyleModule,
  ClientSideRowModelApiModule,
  ClientSideRowModelModule,
];

let editableYear = 2012;

function isCellEditable(params: EditableCallbackParams | CellClassParams) {
  return params.data.year === editableYear;
}

const GridExample = () => {
  const gridRef = useRef<AgGridReact<IOlympicData>>(null);
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);

  const [columnDefs, setColumnDefs] = useState<ColDef[]>([
    { field: "athlete", type: "editableColumn" },
    { field: "age", type: "editableColumn" },
    { field: "year" },
    { field: "country" },
    { field: "sport" },
    { field: "total" },
  ]);
  const columnTypes = useMemo<ColTypeDefs>(() => {
    return {
      editableColumn: {
        editable: (params: EditableCallbackParams<IOlympicData>) => {
          return isCellEditable(params);
        },
        cellStyle: (params: CellClassParams<IOlympicData>) => {
          if (isCellEditable(params)) {
            return { backgroundColor: "#2244cc44" };
          }
        },
      },
    };
  }, []);

  const { data, loading } = useFetchJson<IOlympicData>(
    "https://www.ag-grid.com/example-assets/olympic-winners.json",
  );

  const setEditableYear = useCallback((year: number) => {
    editableYear = year;
    // Redraw to re-apply the new cell style
    gridRef.current!.api.redrawRows();
  }, []);

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div className="example-wrapper">
          <div style={{ marginBottom: "5px" }}>
            <button
              style={{ fontSize: "12px" }}
              onClick={() => setEditableYear(2008)}
            >
              Enable Editing for 2008
            </button>
            <button
              style={{ fontSize: "12px" }}
              onClick={() => setEditableYear(2012)}
            >
              Enable Editing for 2012
            </button>
          </div>

          <div style={gridStyle}>
            <AgGridReact<IOlympicData>
              ref={gridRef}
              rowData={data}
              loading={loading}
              columnDefs={columnDefs}
              columnTypes={columnTypes}
            />
          </div>
        </div>
      </div>
    </AgGridProvider>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(
  <StrictMode>
    <GridExample />
  </StrictMode>,
);
```

[Live example: Conditional Cell Editing](https://www.ag-grid.com/examples/cell-editing/conditional-editing/reactFunctionalTs)

## Editing Events

Cell editing results in the following events.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `cellValueChanged` | `CellValueChangedEvent` |  |  | Cell value has changed. This occurs after the following scenarios: - Editing. Will not fire if any of the following are true: new value is the same as old value; `readOnlyEdit = true`; editing was cancelled (e.g. Escape key was pressed); or new value is of the wrong cell data type for the column. - Cut. - Paste. - Cell clear (pressing Delete key). - Fill handle. - Copy range down. - Undo and redo. See [Editing Events](https://www.ag-grid.com/react-data-grid/cell-editing/#editing-events) for more information. |
| `cellEditRequest` | `CellEditRequestEvent` |  |  | Value has changed after editing. Only fires when `readOnlyEdit=true`. See [Read Only Edit](https://www.ag-grid.com/react-data-grid/value-setters/#read-only-edit) for more information. |
| `rowValueChanged` | `RowValueChangedEvent` |  |  | A cell's value within a row has changed. This event corresponds to Full Row Editing only. See [Full Row Editing](https://www.ag-grid.com/react-data-grid/cell-editing-full-row/) for more information. |
| `cellEditingStarted` | `CellEditingStartedEvent` |  |  | Editing a cell has started. See [Editing Events](https://www.ag-grid.com/react-data-grid/cell-editing/#editing-events) for more information. |
| `cellEditingStopped` | `CellEditingStoppedEvent` |  |  | Editing a cell has stopped. See [Editing Events](https://www.ag-grid.com/react-data-grid/cell-editing/#editing-events) for more information. |
| `rowEditingStarted` | `RowEditingStartedEvent` |  |  | Editing a row has started (when row editing is enabled). When row editing, this event will be fired once and `cellEditingStarted` will be fired for each individual cell. Only fires when doing Full Row Editing. See [Full Row Editing](https://www.ag-grid.com/react-data-grid/cell-editing-full-row/) for more information. |
| `rowEditingStopped` | `RowEditingStoppedEvent` |  |  | Editing a row has stopped (when row editing is enabled). When row editing, this event will be fired once and `cellEditingStopped` will be fired for each individual cell. Only fires when doing Full Row Editing. See [Full Row Editing](https://www.ag-grid.com/react-data-grid/cell-editing-full-row/) for more information. |

## Row Grouping and Cell Editing

For cell editing with row grouping see [Row Grouping - Editing Groups](https://www.ag-grid.com/react-data-grid/grouping-edit/)
