Search code examples
reactjsag-gridag-grid-react

ag-grid cell style based on dynamic condition


I am looking for dynamic rendering of cells in ag-grid based on a settable threshold value above which the cell is rendered green else red.

I tried the following:

<AgGridReact
  onGridReady={onGridReady}
  pagination={true}
  columnDefs={[
    { headerName: "SYMBOL", field: "symbol" },
    {
      headerName: "PRICE",
      field: "price",
      volatile: true,
      cellStyle: function (params) {
        if (params.value < threshold) {
          return { backgroundColor: "red" };
        } else {
          return { backgroundColor: "green" };
        }
      }
    }
  ]}
/>

and take input for threshold (which sets the state). However, even though the state changes no change happen in the columnDefs.

I am using .applyTransactionAsync() for high frequency updates. Hence upon using .setColumnDefs() the table does not show any data.

Is there any way that this cell styling happens based on a dynamic condition on dynamic data instead of a fixed one?


Solution

  • You can use AgGrid's context to update dynamic value that can then be used to pass around the grid. Here is how you can reference the context object in your cellStyle callback.

    {
      headerName: "PRICE",
      field: "price",
      cellStyle: (params) => {
        if (params.value < params.context.threshold) {
          return { backgroundColor: "lightCoral" };
        } else {
          return { backgroundColor: "deepSkyBlue" };
        }
      }
    }
    

    Setting up context is easy

    <AgGridReact
      columnDefs={columnDefs}
      rowData={rowData}
      context={{
        threshold
      }}
      ...
    />
    

    Where threshold is a dynamic value that you can get from redux store or an API response for example. In the demo code below, you can update threshold locally using the value from the input.

    const [threshold, setThreshold] = React.useState(20);
    const updateThreshold = () => {
      const inputEl = document.getElementById("thresholdInput");
      const newValue = parseFloat((inputEl as HTMLInputElement).value);
      setThreshold(newValue);
    };
    
    return (
      <>
        <input id="thresholdInput" defaultValue={threshold} />
        <button onClick={updateThreshold}>Update threshold</button>
        ...
      </>
    );
    

    Live Demo

    Edit 63975972/ag-grid-cell-style-based-on-dynamic-condition