简体   繁体   English

如何在不触发 React Table 中整行的 onClick 函数的情况下选择特定列中的行

[英]How to select a row in a specific column without triggering the onClick function for that entire row in React Table

I already have my React Table set up that when the user clicks on a row they will be brought to another page, but now I have added a checkbox in the first column that allows the user to have that row highlighted, but when I click the checkbox, it brings the user to another page as it triggers the function called when clicking an entire row.我已经设置了我的 React Table,当用户单击一行时,它们将被带到另一个页面,但是现在我在第一列中添加了一个复选框,允许用户突出显示该行,但是当我单击复选框,它将用户带到另一个页面,因为它会触发单击整行时调用的函数。

I have tried to get the column accessor name, and if the column that's clicked is the first one then not to route the user to another page, but I'm having trouble getting information out about what column was selected.我试图获取列访问器名称,如果单击的列是第一个,则不要将用户路由到另一个页面,但是我无法获取有关所选列的信息。 I've spent a good bit of time looking at the docs but can't figure it out.我花了很多时间查看文档,但无法弄清楚。

I would really appreciate any help as I am having difficulty getting to grips with React Table in general我真的很感激任何帮助,因为我通常很难掌握 React Table

RecordTable.js记录表.js

    import React from "react";
import {
  useTable,
  useFlexLayout,
  useFilters,
  useGlobalFilter,
  useRowSelect
} from "react-table";
import _ from "lodash";
// noinspection ES6CheckImport
import { useHistory } from "react-router-dom";
import Table from "react-bootstrap/Table";

// Define a default UI for filtering
function GlobalFilter({
  preGlobalFilteredRows,
  globalFilter,
  setGlobalFilter
}) {
  return (
    <span>
      <input
        value={globalFilter || ""}
        onChange={e => {
          setGlobalFilter(e.target.value || undefined); // Set undefined to remove the filter entirely
        }}
        placeholder={" Search by any criteria"}
        style={{
          fontSize: "2.0rem",
          width: "100%"
        }}
      />
    </span>
  );
}

const IndeterminateCheckbox = React.forwardRef(
  ({ indeterminate, ...rest }, ref) => {
    const defaultRef = React.useRef();
    const resolvedRef = ref || defaultRef;

    React.useEffect(() => {
      resolvedRef.current.indeterminate = indeterminate;
    }, [resolvedRef, indeterminate]);

    return (
      <>
        <input type="checkbox" ref={resolvedRef} {...rest} />
      </>
    );
  }
);

export const RecordTable = ({ forms }) => {
  //TODO figure out why react-table crashes if forms is not set to data variable below first
  const data = forms;
  let history = useHistory();

 

  const columns = React.useMemo(
    () => [
      {
        Header: "Disclaimer Form Records",
        columns: [
          {
            Header: "First Name", 
          {
            Header: "Time In",
            accessor: "timeIn"
          },
          {
            Header: "Time Out",
            accessor: "timeOut"
          },
          {
            Header: "€ Price",
            accessor: "totalGroupPrice",
            disableFilters: true,
            disableSortBy: true
          }
        ]
      }
    ],
    []
  );

  const defaultColumn = React.useMemo(
    () => ({
      //minWidth: 20,
      maxWidth: 150,
      width: 120
    }),
    []
  );

  const rowOnClick = (rowObject, column) => {
    console.log("rowObject.original: ", rowObject.original);
    console.log("column.id: ", column);
    history.push("/viewform", { ...rowObject.original });
  };



  // Use the state and functions returned from useTable to build your UI
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow,
    state,
    preGlobalFilteredRows,
    setGlobalFilter,
    setHiddenColumns,
  } = useTable(
    {
      columns,
      data,
      defaultColumn
    },
    useFilters,
    useGlobalFilter,
    useFlexLayout,
    useRowSelect,
    hooks => {
      hooks.visibleColumns.push(columns => [
        // Let's make a column for selection
        {
          accessor: "active",
          Header: "Active",
          width: 50,
          maxWidth: 50,
          minWidth: 50,
          Cell: ({ row }) => (
            <div>
              <IndeterminateCheckbox {...row.getToggleRowSelectedProps()} />
            </div>
          )
        },
        ...columns
      ]);
    }
  );

 

  // Render the UI for your table
  return (
    <div>
      <div>Records: {rows.length}</div>
      <GlobalFilter
        preGlobalFilteredRows={preGlobalFilteredRows}
        globalFilter={state.globalFilter}
        setGlobalFilter={setGlobalFilter}
      />

      <div
        style={{
          height: 500,
          border: "2px solid grey",
          borderRadius: "5px",
          overflow: "scroll"
        }}>
        <Table striped bordered hover responsive={"md"} {...getTableProps()}>
          <thead>
            {headerGroups.map(headerGroup => (
              <tr {...headerGroup.getHeaderGroupProps()}>
                {headerGroup.headers.map(column => (
                  <th {...column.getHeaderProps()}>
                    {column.render("Header")}
                  </th>
                ))}
              </tr>
            ))}
          </thead>

          <tbody {...getTableBodyProps()}>
            {rows.map((row, column, i) => {
              prepareRow(row);
              return (
                <tr
                  {...row.getRowProps({
                    onClick: () => rowOnClick(row, column)
                  })}>
                  {row.cells.map(cell => {
                    return (
                      <td {...cell.getCellProps()}>{cell.render("Cell")}</td>
                    );
                  })}
                </tr>
              );
            })}
          </tbody>
        </Table>
      </div>
    </div>
  );
};

You need to set an onClick={e => e.stopPropagation()} on the checkbox.您需要在复选框上设置onClick={e => e.stopPropagation()}

Technically the click occurred on multiple elements.从技术上讲,点击发生在多个元素上。 The checkbox, the cell the row etc.复选框、单元格、行等。

In JS the event is created on the top element and then propagated ('bubbled') through all DOM elements that are positioned under the mouse cursor.在 JS 中,事件是在顶部元素上创建的,然后通过位于鼠标光标下的所有 DOM 元素传播(“冒泡”)。 The event bubbles through the different layers and all elements may react on it.事件在不同的层中冒泡,所有元素都可能对其做出反应。 But you do want to stop it bubbling in your case.但是你确实想阻止它在你的情况下冒泡。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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