如何在React功能组件的AgGrid Cell中添加按钮和下拉菜单

问题描述 投票:0回答:2

我有数据列表。我在 React 中使用 AgGrid 来显示此数据列表。对于每一行,我需要显示一个具有删除按钮的列和一个具有下拉菜单和重置按钮的第二列。

当我单击删除按钮时,我需要相应的行数据,当我单击重置按钮时,我需要下拉选项选择以及相应的行数据。

我已经搜索过,但我无法弄清楚如何在反应功能组件中做到这一点。我发现我需要使用 ICellRendererReactComp 但我不知道如何使用,因为我是反应和 AgGrid 的新手

我当前的代码看起来像这样:

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:这是我在单击某个相应行的删除按钮时要调用的函数,
  • resetSessionOptions:这是我需要与重置按钮一起显示在第二列中的下拉列表选项。
  • handleReset:这是我想在单击下拉列表之外的重置按钮以获取某些相应行时调用的函数
javascript reactjs ag-grid
2个回答
2
投票

所以我搜索了很多,终于找到了这个例子:https://stackblitz.com/edit/angular-ag-grid-button-renderer?file=src%2Fapp%2Frenderer%2Fbutton-renderer.component.ts

上面的示例适用于 Angular 并使用类。

我想出了如何在反应功能组件中做到这一点。我没有使用任何接口或其他东西,但实现了上面给出的示例中的所有方法,并为我需要的两列创建了渲染器类。你可以看下面的代码。

更新:我的这个解决方案有效,但这导致我的所有其他状态变量重置为初始状态。我不知道为什么会发生这种情况。我正在寻找解决方案。

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 };


0
投票

我也遇到了这个问题,刚刚找到了解决方案。为了使用包含打开下拉菜单的按钮的单元格渲染器(在本例中,我使用了 React Bootstrap 的下拉组件),您可以像这样包装网格:

    const GridWrapper = styled.div`
      & .ag-row {
        overflow: visible !important;
      }
    
      & .ag-cell-value {
        overflow: visible !important;
      }
    
      & .ag-row.ag-row-focus {
        z-index: 1;
      }
    `;

    ...
    <GridWrapper>
        <AgGridReact></AgGridReact>
    </GridWrapper>
    ...

或者,您可以创建一个 styles.css 文件,其中包含:

      .ag-row {
        overflow: visible !important;
      }
    
      .ag-cell-value {
        overflow: visible !important;
      }
    
      .ag-row.ag-row-focus {
        z-index: 1;
      }

我最初能够通过这个例子解决这个问题: https://plnkr.co/edit/TgVg6uQYap1XcqRv?p=预览&预览

© www.soinside.com 2019 - 2024. All rights reserved.