Search code examples
reactjsmaterial-uimui-datatable

Change cell value dynamically in MUI Data Grid


In my Data Grid I have 9 columns where you can see there are two columns named Rate and Transfer. I also have a column named Total where I want to show the multiplication result of Rate and Transfer with the change of Transfer cell's value. Note that I've made Transfer column editable so that the value of Total column changes with Transfer value. In DataGrid there is a prop called onCellFocusOut() which gives you the cell value after you click outside the cell. But this doesn't give you the updated value. I tried using useEffect() and useState() to set the value of the Transfer cell and update the Total accordingly. But it didn't work. Hopefully I've explained clearly about what I want to achieve here.

My code

const Transition = React.forwardRef(function Transition(props, ref) {
  return <Slide direction="left" ref={ref} {...props} />;
});

function FullScreenDialog({ open, handleClose }) {
  const columns = [
    {
      field: "Lot",
      headerName: "Lot#",
      width: 200,
      editable: false,
    },
    { field: "Bill", headerName: "Bill#", width: 130, editable: false },
    {
      field: "Shelf",
      headerName: "Shelf",
      width: 200,
      editable: false,
    },
    {
      field: "Bin",
      headerName: "Bin",
      width: 200,
      editable: false,
    },
    {
      field: "Rate",
      headerName: "Rate",
      width: 200,
      editable: false,
    },
    {
      field: "Stock",
      headerName: "Stock Balance Qty.",
      width: 200,
      editable: false,
    },
    {
      field: "Transfer",
      headerName: "Transfer Qty.",
      width: 200,
      editable: true,
    },
    {
      field: "Total",
      headerName: "Total",
      width: 200,
      editable: false,
    },
  ];

  // React.useEffect(() => {
  //   setTotal(rate * transfer);
  //   console.log("total", total);
  // }, [transfer]);

  const [transferCellValue, setTransferCellValue] = React.useState(null);
  const [total, setTotal] = React.useState(1);
  console.log("transfer cell value", transferCellValue);
  const defaultRows = [
    {
      id: 1,
      Lot: "2101000134",
      Bill: "M0000013092",
      Shelf: "W13-A1",
      Bin: "B01",
      Rate: 221,
      Stock: 128.0,
      Transfer: 12,
      Total: total,
    },
  ];

  // console.log(transferCellValue);

  return (
    <div>
      <Dialog
        fullScreen
        open={open}
        onClose={handleClose}
        TransitionComponent={Transition}
      >
        <div style={{ height: 400, width: "100%" }}>
          <DataGrid
            rows={defaultRows}
            columns={columns}
            onCellFocusOut={(e) => console.log(e.value)}
          />
        </div>
      </Dialog>
    </div>
  );
}

Solution

  • If all you want is that the total column to be calculated by Transfer * Rate, you can use valueGetter to return a dynamic value.

    valueGetter: Function that allows to get a specific data instead of field to render in the cell.

    {
      field: "Total",
      headerName: "Total",
      width: 200,
      valueGetter: (params) => params.row.Transfer * params.row.Rate
    }
    

    https://codesandbox.io/s/mui-datagrid-dynamic-column-tdod5