简体   繁体   中英

How to add a button and a dropdown in AgGrid Cell in react Functional Component

I have list of data. I am using AgGrid in react to display this data list. For each row i need to display a column having a delete button and a second column having a dropdown and a reset button.

When i click the delete button i need the corresponding row data and when i click reset button i need the dropdown option select as well as the corresponding row data.

I have searched but i am not able to figure out how to do it in react functional components. I have found that i need to use ICellRendererReactComp but i am not sure how as i am new to react and AgGrid

My current code looks something like this:

import React, { useState } from "react";
import toaster from "toasted-notes";

import { apiRequest, errorHandler } from "../../utilis/apiRequest";
import { columnDefsFromArr } from "../Threads/columnDefs";
import { AgGridReact, ICellRendererReactComp } from "ag-grid-react";
import { isResourcePresent } from "../../utilis/helper";

function Sessions(props) {
  const [email, setEmail] = useState("");
  const [reid, setReid] = useState(null);
  const [sessionsResp, setSessionsResp] = useState(null);
  const [columnDefs, setColumnDefs] = useState(null);
  const [rowData, setRowData] = useState(null);
  const defaultColDef = {
    sortable: true,
    filter: true,
    resizable: true,
  };
  const colsToExlude = ["requestId"];
  const resetSessionOptions = [
    "None",
    "ClearClientCache",
    "PasswordChange",
    "Suspended",
    "InvalidSession",
    "Expired",
  ];

  const handleEmailChange = (e) => {
    setEmail(e.target.value);
  };

  const handleGetSession = () => {
    setReid(email);
    getSessions({ reid: email, env: props.env });
  };

  const getSessions = (data) => {
    console.log(data, reid);
    let isError = validateForm(data);
    if (isError.status) {
      apiRequest(
        props.sessionToken,
        "get_session",
        data,
        (res) => {
          if (res.status === 200) {
            console.log(res.data);
            setRowData(res.data.sessions);
            makeGrid(res.data);
          }
        },
        (err) => {
          errorHandler(err);
        }
      );
    } else {
      toaster.notify(isError.msg, {
        duration: 1500,
      });
    }
  };

  const handleDelete = (data) => {
    console.log(data);
  };

  const handleReset = (data) => {
    console.log(data);
  };

  const makeGrid = (data) => {
    let cols = [];
    data.sessions.map((ele) => {
      Object.keys(ele).map((key) => cols.push(key));
    });
    let localCols = [];
    if (isResourcePresent(props.resources, "del_session")) {
      localCols.push({
        headerName: "Delete Sessio",
      });
    }
    if (isResourcePresent(props.resources, "reset_session")) {
      localCols.push({
        headerName: "Reset Session"
      });
    }
    cols = [...new Set(cols)];
    colsToExlude.map((key) => {
      let ind = cols.indexOf(key);
      if (ind > -1) {
        cols.splice(ind, 1);
      }
    });
    let finalColDefs = [...localCols, ...columnDefsFromArr(cols)];
    console.log(finalColDefs);
    setColumnDefs(finalColDefs);
  };

  const validateForm = (data) => {
    if (data.reid.trim() === "") {
      return { status: false, msg: "Email/Email Id is reqd" };
    } else {
      return { status: true };
    }
  };

  return (
    <div className="container-fluid">
      <div>
        <h5>Get Sessions Information</h5>
      </div>

      <div className="card mt-2 p-3 bg-red shadow p-3 mb-5 bg-white rounded">
        <div className="row m-2">
          <div className="col-sm-6">
            <input
              type="text"
              className="form-control"
              value={email || ""}
              placeholder="Email / Email ID"
              onChange={handleEmailChange}
            />
          </div>
          <div className="col-sm-2">
            <button className="button btn-primary" onClick={handleGetSession}>
              Get Information
            </button>
          </div>
        </div>
      </div>
      {rowData == null ? null : (
        <div className="card mt-2 p-3 bg-red shadow p-3 mb-5 bg-white rounded">
          <div
            className="ag-theme-balham"
            style={{ height: "500px", width: "100%" }}
          >
            <AgGridReact
              columnDefs={columnDefs}
              rowData={rowData}
            ></AgGridReact>
          </div>
        </div>
      )}
    </div>
  );
}

export { Sessions };

  • handleDelete: this is the function i want to call when that delete button is clicked for some corresponding row,
  • resetSessionOptions: this is the dropdown list options i need to display in second column along with Reset button.
  • handleReset: this the function i want to call when that Reset button besides the dropdown is clicked for some corresponding row

So I searched a lot and finally came across this example: https://stackblitz.com/edit/angular-ag-grid-button-renderer?file=src%2Fapp%2Frenderer%2Fbutton-renderer.component.ts

Above example is for Angular and uses classes.

I figured out how to do it in react Functional Components. I did not used any interface or something but implemented all methods in above given example and made Renderer classes for the two columns i needed. You can see the code below.

UPDATE: My this solution works but this is causing my all other state variables to reset to initial state. I am not sure why thats happening. I am looking for a solution for that.

Session.js

import React, { useState } from "react";
import toaster from "toasted-notes";

import { apiRequest, errorHandler } from "../../utilis/apiRequest";
import { columnDefsFromArr } from "../Threads/columnDefs";
import { AgGridReact, ICellRendererReactComp } from "ag-grid-react";
import { isResourcePresent } from "../../utilis/helper";
import { ButtonRenderer } from "./ButtonRenderer";
import { DropDownRender } from "./DropDownRender";

function Sessions(props) {
  const [email, setEmail] = useState("");
  const [reid, setReid] = useState(null);
  const [sessionsResp, setSessionsResp] = useState(null);
  const [columnDefs, setColumnDefs] = useState(null);
  const [rowData, setRowData] = useState(null);
  const frameworkComponents = {
    buttonRenderer: ButtonRenderer,
    dropDownRenderer: DropDownRender,
  };
  const defaultColDef = {
    sortable: true,
    filter: true,
    resizable: true,
  };
  const colsToExlude = ["requestId"];
  const resetSessionOptions = [
    "None",
    "ClearClientCache",
    "PasswordChange",
    "Suspended",
    "InvalidSession",
    "Expired",
  ];

  const handleEmailChange = (e) => {
    setEmail(e.target.value);
  };

  const handleGetSession = () => {
    setReid(email);
    getSessions({ reid: email, env: props.env });
  };

  const getSessions = (data) => {
    console.log(data, reid);
    let isError = validateForm(data);
    if (isError.status) {
      apiRequest(
        props.sessionToken,
        "get_session",
        data,
        (res) => {
          if (res.status === 200) {
            console.log(res.data);
            setRowData(res.data.sessions);
            makeGrid(res.data);
          }
        },
        (err) => {
          errorHandler(err);
        }
      );
    } else {
      toaster.notify(isError.msg, {
        duration: 1500,
      });
    }
  };

  const handleDelete = (data) => {
    console.log("DEL", data);
  };

  const handleReset = (data) => {
    console.log("RESET", data);
  };

  const makeGrid = (data) => {
    let cols = [];
    data.sessions.map((ele) => {
      Object.keys(ele).map((key) => cols.push(key));
    });
    let localCols = [];
    if (isResourcePresent(props.resources, "del_session")) {
      localCols.push({
        headerName: "Delete Sessio",
        cellRenderer: "buttonRenderer",
        cellRendererParams: {
          onClick: handleDelete,
          label: "Delete",
        },
      });
    }
    if (isResourcePresent(props.resources, "reset_session")) {
      localCols.push({
        headerName: "Reset Session",
        cellRenderer: "dropDownRenderer",
        cellRendererParams: {
          onClick: handleReset,
          label: "RESET",
          dropDown: resetSessionOptions,
        },
      });
    }
    cols = [...new Set(cols)];
    colsToExlude.map((key) => {
      let ind = cols.indexOf(key);
      if (ind > -1) {
        cols.splice(ind, 1);
      }
    });
    let finalColDefs = [...localCols, ...columnDefsFromArr(cols)];
    setColumnDefs(finalColDefs);
  };

  const validateForm = (data) => {
    if (data.reid.trim() === "") {
      return { status: false, msg: "Email/Email Id is reqd" };
    } else {
      return { status: true };
    }
  };

  return (
    <div className="container-fluid">
      <div>
        <h5>Get Sessions Information</h5>
      </div>

      <div className="card mt-2 p-3 bg-red shadow p-3 mb-5 bg-white rounded">
        <div className="row m-2">
          <div className="col-sm-6">
            <input
              type="text"
              className="form-control"
              value={email || ""}
              placeholder="Email / Email ID"
              onChange={handleEmailChange}
            />
          </div>
          <div className="col-sm-2">
            <button className="button btn-primary" onClick={handleGetSession}>
              Get Information
            </button>
          </div>
        </div>
      </div>
      {rowData == null ? null : (
        <div className="card mt-2 p-3 bg-red shadow p-3 mb-5 bg-white rounded">
          <div
            className="ag-theme-balham"
            style={{ height: "500px", width: "100%" }}
          >
            <AgGridReact
              defaultColDef={defaultColDef}
              columnDefs={columnDefs}
              rowData={rowData}
              frameworkComponents={frameworkComponents}
            ></AgGridReact>
          </div>
        </div>
      )}
    </div>
  );
}

export { Sessions };

ButtonRenderer.js

import React from "react";

function ButtonRenderer(params) {
  const refresh = (param) => {
    return true;
  };

  const onClick = ($event) => {
    if (params.onClick instanceof Function) {
      const retParams = {
        event: $event,
        rowData: params.node.data,
      };
      params.onClick(retParams);
    }
  };
  return (
    <button className="button btn-primary" onClick={onClick}>
      {params.label}
    </button>
  );
}

export { ButtonRenderer };

DropDownRenderer.js

import React, { useState } from "react";

function DropDownRender(params) {
  const [selection, setSelection] = useState(params.dropDown[0]);
  const refresh = (param) => {
    return true;
  };

  const handleDropDown = (e) => {
    setSelection(e.target.value);
  };

  const onClick = ($event) => {
    if (params.onClick instanceof Function) {
      const retParams = {
        event: $event,
        rowData: params.node.data,
        selection: selection,
      };
      params.onClick(retParams);
    }
  };
  return (
    <div className="row">
      <div className="col">
        <select className="form-control" onChange={handleDropDown}>
          {params.dropDown.map((i) => {
            return (
              <option key={i} value={i}>
                {i}
              </option>
            );
          })}
        </select>
      </div>
      <div className="col">
        <button className="button btn-primary" onClick={onClick}>
          {params.label}
        </button>
      </div>
    </div>
  );
}

export { DropDownRender };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM