reactjstypescriptag-grid

Ag-grid cannot change dropdown value. It always goes back to its pre-state


I have ag-grid and one column is dropdown (name of column is Color). I have problem when changing the value of the dropdown. It always goes back to its pre-state. For example below. The first record has Color 'Green' in the dropdown. If I change it to something else and I do onmouse blur, it always comes back to Green. I want to change the value whatever I prefer. Below is my code. Please help.

import React, {
  useState,
  useCallback,
  forwardRef,
  useImperativeHandle,
} from 'react';
import { AgGridReact } from 'ag-grid-react';
import 'ag-grid-community/styles/ag-grid.css';
import 'ag-grid-community/styles/ag-theme-alpine.css';
import { ICellEditorComp } from 'ag-grid-community';
interface DropdownEditorProps {
  value: string;
  values: string[];
}
const DropdownEditor = forwardRef<ICellEditorComp, DropdownEditorProps>(
  (props, ref) => {
    const [selectedValue, setSelectedValue] = useState(props.value);

    useImperativeHandle(ref, () => {
      return {
        getValue() {
          return selectedValue;
        },
        isPopup() {
          return true;
        },
      };
    });

    const handleChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
      setSelectedValue(event.target.value);
    };

    return (
      <select
        value={selectedValue}
        onChange={handleChange}
        style={{ width: '100%' }}
      >
        {props.values.map((option) => (
          <option key={option} value={option}>
            {option}
          </option>
        ))}
      </select>
    );
  }
);
const testapp: React.FC = () => {
  const [rowData, setRowData] = useState([
    { Color: 'Green', make: 'Tesla', model: 'Model Y', price: 64950 },
    { Color: 'Blue', make: 'Ford', model: 'F-Series', price: 33850 },
    { Color: '', make: 'BMW', model: 'BMW Series', price: 5000 },
  ]);
  const [colDefs] = useState([
    {
      field: 'Color',
      editable: true,
      cellEditor: DropdownEditor,
      cellEditorParams: {
      values: ['Normal', 'Green', 'Red', 'Blue'],
      },
    },
    { field: 'make' },
    { field: 'model' },
    { field: 'price' },
  ]);

  return (
    <div className="ag-theme-alpine" style={{ width: 800, height: 400 }}>
      <AgGridReact
        rowData={rowData}
        columnDefs={colDefs}
        singleClickEdit={true}
        gridOptions={{
          stopEditingWhenCellsLoseFocus: true,
          rowSelection: {
            mode: 'singleRow',
            checkboxes: false,
          },
        }}
      />
    </div>
  );
};
export default testapp;

Solution

  • Adding the line props.onValueChange(event.target.value); inside the change handler is essential because it notifies AG Grid that the value inside your custom cell editor has changed. Without calling onValueChange, AG Grid does not detect that the cell’s value has been modified, so it continues to display the original value and does not update the underlying row data.

    import React, {
      useState,
      useCallback,
      forwardRef,
      useImperativeHandle,
    } from 'react';
    import { AgGridReact } from 'ag-grid-react';
    import 'ag-grid-community/styles/ag-grid.css';
    import 'ag-grid-community/styles/ag-theme-alpine.css';
    import { ICellEditorComp } from 'ag-grid-community';
    
    const DropdownEditor = forwardRef((props, ref) => {
      const [selectedValue, setSelectedValue] = useState(props.value);
    
      useImperativeHandle(ref, () => {
        return {
          getValue() {
            return selectedValue;
          },
          isPopup() {
            return true;
          },
        };
      });
    
      const handleChange = (event) => {
        setSelectedValue(event.target.value);
        props.onValueChange(event.target.value);
      };
    
      return (
        <select
          value={selectedValue}
          onChange={handleChange}
          style={{ width: '100%' }}
        >
          {props.values.map((option) => (
            <option key={option} value={option}>
              {option}
            </option>
          ))}
        </select>
      );
    });
    const testapp = () => {
      const [rowData, setRowData] = useState([
        { Color: 'Green', make: 'Tesla', model: 'Model Y', price: 64950 },
        { Color: 'Blue', make: 'Ford', model: 'F-Series', price: 33850 },
        { Color: '', make: 'BMW', model: 'BMW Series', price: 5000 },
      ]);
      const [colDefs] = useState([
        {
          field: 'Color',
          editable: true,
          cellEditor: DropdownEditor,
          cellEditorParams: {
            values: ['Normal', 'Green', 'Red', 'Blue'],
          },
        },
        { field: 'make' },
        { field: 'model' },
        { field: 'price' },
      ]);
    
      return (
        <div className="ag-theme-alpine" style={{ width: 800, height: 400 }}>
          <AgGridReact
            rowData={rowData}
            columnDefs={colDefs}
            singleClickEdit={true}
            gridOptions={{
              stopEditingWhenCellsLoseFocus: true,
              rowSelection: {
                mode: 'singleRow',
                checkboxes: false,
              },
            }}
          />
        </div>
      );
    };
    export default testapp;