Ag Grid React Custom CellRenderer Component - How to display only for certain cells

42 views Asked by At

enter image description here

I am using ag grid react (community edition) where I have a column name Ticker. I also have another column 'Percentage'. The second column is initially hidden and when a cellvalue in Ticker column is changed, second column is visible and it displays the +/- X% has changed from previous cellvalue of that row. For Ex: if a cell has 100, and if user changes it to 200, then the second column will display it as '100 %' with green arrow. if the value is reduced, then it shows '-60%' with red downward arrow. I am able to get these values based on cells, but the custom component which is conditional for uparrow(green icon) or down arrow (red icon) is changing in other rows too.For example, I change in first row from 100 to 200. This is increase of 100% which displays with green arrow. But when i decrease the value in second row from 50 to 30, the percentage column should display downarrow in red only in second row. But with below code this is changing in first row as well which has green uparrow. See the first row of percentage column is now changed from greenarrow to red because the i decreased the value in second row of Ticker column. I am stuck in this and wondering if anyone has tried to get this component displayed independent of other rows.

Code is available here

output:

import "./styles.css";
import React, { useState } 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 CustomElements from "./customElements.jsx";

function PriceGrid() {
  const [rowData2, setRowData2] = useState([
    { ticker: 100 },
    { ticker: 50 },
    { ticker: 2004 },
    { ticker: 2000 },
  ]);

  const [showPercentage, setshowPercentage] = useState(false);
  const [percValue, setpercValue] = useState(0);

  const numberToColor = (val) => {
    let val1 = toString(val);
    if (typeof val === "number") {
      return "#aaaaff";
    } else if (typeof val === "string") {
      return "#ffaaaa";
    } else {
      return "#aaffaa";
    }
  };

  const cellStyle = (params) => {
    const color = numberToColor(params.value);
    return {
      backgroundColor: color,
    };
  };

  const numberParser = (params) => {
    const newValue = params.newValue;
    let valueAsNumber;
    if (newValue === null || newValue === undefined || newValue === "") {
      valueAsNumber = null;
    } else {
      valueAsNumber = parseFloat(params.newValue);
    }
    return valueAsNumber;
  };

  const columnDefs2 = [
    {
      headerName: "Ticker",
      field: "ticker",
      editable: true,
      minWidth: 300,
      valueParser: numberParser,
      //cellClassRules: ragCellClassRules,
      cellRenderer: (params) => (
        <div className="custom-element">
          <input defaultValue={params.value ? params.value : ""} />
        </div>
      ),
      //cellStyle: cellStyle,
    },
    {
      headerName: "Percentage",
      field: "percentage",
      hide: { showPercentage },
      minWidth: 50,
      //valueParser: numberParser,
      //cellClassRules: ragCellClassRules,
      cellRenderer: CustomElements,
      cellRendererParams: (params) => ({
        rowIndex: params.rowIndex,
        //params: params,
        percValue: percValue,
      }),
    },
  ];

  const handleCellValueChanged2 = (params) => {
    const newValue = parseFloat(params.newValue);
    const oldValue = parseFloat(params.oldValue);
    const node = params.node;

    console.log("newValue: ", newValue);
    console.log("oldValue: ", oldValue);
    console.log("rowIndex: ", params.rowIndex);
    //console.log("node: ", (newValue - oldValue) / oldValue);

    let perchange = parseFloat(((newValue - oldValue) / oldValue) * 100);
    perchange = perchange.toFixed(2);
    console.log("perchange: ", perchange);

    {
      /*} let icon;
    if (perchange > 0) {
      icon = String(perchange) + "% up";
    } else if (perchange < 0) {
      icon = String(perchange) + "% down";
    } */
    }

    setpercValue(parseFloat(perchange));

    // Update the cell with the new value
    node.setDataValue("ticker", newValue);
    // Check if the cell value has changed
    if (newValue !== oldValue) {
      // If the value has changed, set the row data with the updated value
      const updatedRowData = rowData2.map((row) =>
        row === params.data
          ? { ...row, ticker: newValue, percentage: parseFloat(perchange) } //{ ...row, ticker: newValue + " ==> " + icon }
          : row
      );
      setshowPercentage(true);
      setRowData2(updatedRowData);
    }
  };

  return (
    <div>
      <div
        className="ag-theme-alpine"
        style={{
          height: "300px",
          width: "600px",
          margin: "auto",
          paddingTop: "20px",
        }}
      >
        <AgGridReact
          rowData={rowData2}
          columnDefs={columnDefs2}
          onCellValueChanged={handleCellValueChanged2}
        />
      </div>
    </div>
  );
}

export default PriceGrid;


//************************************************************************************************************//

//CustomElements.js


import React from "react";
import { UilChartDown } from "@iconscout/react-unicons";
import { UilArrowGrowth } from "@iconscout/react-unicons";
import Chip from "@mui/joy/Chip";

export default ({ data, rowIndex, percValue }) => {
  //console.log(data);
  //console.log(showPercentage);

  console.log("percValue: ", percValue);
  console.log("data: ", data);

  return (
    <div className="custom-element">
      {/*{showPercentage && newValue !== oldValue && (
        <UilChartDown size="20" color="#61DAFB" />
      )}*/}
      {/* we are using data.percentage as compararison as this is only differentiator with other non edited rows*/}
      {data.percentage != undefined && percValue > 0 ? (
        <Chip
          variant="soft"
          startDecorator={<UilArrowGrowth size="20" color="#12AB4E" />}
        >
          {data.percentage}%
        </Chip>
      ) : data.percentage != undefined && percValue < 0 ? (
        <Chip
          variant="soft"
          startDecorator={<UilChartDown size="20" color="#FF5733" />}
        >
          {data.percentage}%
        </Chip>
      ) : null}
    </div>
  );
};

0

There are 0 answers