reactjstypescriptag-gridag-grid-react

Ag-Grid ReactJS checkbox cell with aligned center items has issue when cell is clicked using TypeScript


I have a 3-column grid. The first column is a checkbox aligned in the center cell, which is editable (can be checked/unchecked).

My issue is that when I click the cell outside the checkbox item, the layout of the selected cell switches to align left. I want to retain the alignment center if I click the cell. To see the behavior, run the app and in the first column, click the box of the cell (don't click the checkbox itself just outside of it). You will see that the alignment switches. Please help. I want to retain the alignment center even if I select the cell outside the checkbox.

import React, {
  useState,
  useRef,
  useEffect,
  forwardRef,
  useImperativeHandle,
  GridReadyEvent,
  useCallback,
} from 'react';
import { AgGridReact } from 'ag-grid-react';

const InputCellEditor = (props, ref) => {
  const inputRef = useRef(null);
  const [value, setValue] = useState(props.value);

  useEffect(() => {
    if (inputRef.current) {
      inputRef.current.focus();
    }
  }, []);

  const onChange = (e) => {
    const newValue = e.target.value;
    setValue(newValue);
    props.onValueChange?.(newValue);
  };

  const onKeyDown = (e) => {
    if (e.key === 'Enter') {
      props.stopEditing(false);
      e.stopPropagation();
    } else if (e.key === 'Escape') {
      props.stopEditing(true);
      e.stopPropagation();
    }
  };

  const handleBlur = () => {
    props.stopEditing(false);
  };

  return (
    <input
      type="text"
      ref={inputRef}
      style={{ width: '100%' }}
      value={value}
      onChange={onChange}
      onKeyDown={onKeyDown}
      onBlur={handleBlur}
    />
  );
};
const App = () => {
  const onGridReady = useCallback((params: GridReadyEvent) => {
    params.api.getDisplayedRowAtIndex(0)?.setSelected(true);
  }, []);
  const gridRef = useRef(null);
  const [rowData, setRowData] = useState([
    { id: 1, isSelectable: true, value: 'Initial Value 1' },
    { id: 2, isSelectable: false, value: 'Initial Value 2' },
    { id: 3, isSelectable: true, value: 'Initial Value 3' },
  ]);
  const [columnDefs] = useState([
    { field: 'isSelectable', editable: true,headerName:'Selectable',cellStyle: {
        display: 'flex',
        justifyContent: 'center',
        alignItems: 'center',
        border: 'none',
      } },
    { field: 'name', editable: false },
    { field: 'value', editable: true, cellEditor: InputCellEditor },
  ]);

  const onCellValueChanged = (params) => {
    const updatedRowData = rowData.map((item) =>
      item.id === params.data.id
        ? { ...item, [params.colDef.field]: params.newValue }
        : item
    );
    setRowData(updatedRowData);
  };

  return (
    <div className="ag-theme-alpine" style={{ height: 300, width: 600 }}>
      <AgGridReact
        ref={gridRef}
        rowData={rowData}
        columnDefs={columnDefs}
        singleClickEdit={true}
        onGridReady={onGridReady}
        onCellValueChanged={onCellValueChanged}
        gridOptions={{
          stopEditingWhenCellsLoseFocus: true,
          rowSelection: {
            mode: 'singleRow',
            checkboxes: false,
            enableClickSelection: true,
          },
        }}
      />
    </div>
  );
};

export default App;

enter image description here


Solution

  • Instead of using editable: true on the first column, you can use this cellRenderer to have better control over the checkbox behavior and styling:

    cellRenderer: (params) => (
      <div
        style={{
          display: 'flex',
          justifyContent: 'center',
          alignItems: 'center',
          height: '100%',
          width: '100%',
        }}
        onClick={() => {
          params.node.setDataValue(params.colDef.field, !params.value);
        }}
      >
        <input type="checkbox" checked={params.value} readOnly />
      </div>
    )
    

    This way, the checkbox is centered, and clicking anywhere inside the cell toggles the checkbox value without losing the alignment or causing unexpected style changes. Unfortunately, I don't know of an automatic way to apply styles during editing mode.