如何使新添加的行立即可编辑?

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

我正在使用 Prime React 表来渲染 React 中的动态数据。我在 datatable 文档的帮助下构建了我的组件。

当我单击“添加行”按钮时,我希望用户可以立即编辑新添加的行(最好使用我稍后添加的键盘焦点),而无需他们使用编辑按钮来编辑空的新行。这可能吗?

import { DataTable } from "primereact/datatable";
import { Column } from "primereact/column";
import { data } from "../data";
import { useState } from "react";
import { InputText } from "primereact/inputtext";

export const Table = () => {
  const [users, setUsers] = useState(data);

  const handleAddRow = (): void => {
    const newRow: any = {
      firstName: "",
      lastName: "",
      email: "",
      phone: "",
      freeTextField: "",
    };
    setUsers((prevList: any) => [newRow, ...prevList]);
  };

  const onRowEditComplete = (e: any) => {
    const _users = [...users];
    const { newData, index } = e;

    _users[index] = newData;

    setUsers(_users);
  };

  const textEditor = (options: any) => {
    return (
      <InputText
        type="text"
        value={options.value}
        onChange={(e) => options.editorCallback(e.target.value)}
      />
    );
  };

  return (
    <div className="table-wrapper">
      <h2 className="table-name">PrimeReact data table</h2>
      <button onClick={handleAddRow}>add row</button>

      <DataTable
        value={users}
        tableStyle={{ minWidth: "50rem" }}
        editMode="row"
        onRowEditComplete={onRowEditComplete}
      >
        <Column
          field="firstName"
          header="firstName"
          editor={(options) => textEditor(options)}
        ></Column>
        <Column
          field="lastName"
          header="lastName"
          editor={(options) => textEditor(options)}
        ></Column>
        <Column
          field="email"
          header="email"
          editor={(options) => textEditor(options)}
        ></Column>
        <Column
          field="phone"
          header="phone"
          editor={(options) => textEditor(options)}
        ></Column>
        <Column style={{ maxWidth: "15%" }} rowEditor>
          edit
        </Column>
      </DataTable>
    </div>
  );
};
reactjs crud primereact
2个回答
3
投票

这可以通过对上面的代码进行一些调整来实现。

  1. 您需要在
    dataKey
    上引入道具
    DataTable
    ,这对于您的数据来说应该是独特,并且您可以在创建行时添加到数据中,我使用
    id
    进行演示。
  2. 您需要引入道具
    onRowEditChange
    ,以便表可以处理编程激活。
  3. 您需要引入属性
    editingRows
    ,您将在指示哪一行处于编辑模式的状态下传递该属性。这是表通过利用步骤 1 中提到的
    dataKey
    属性在内部处理的。

请参阅下面的代码,将有助于进一步理解上述几点。

* 我为

users
状态使用了一些硬编码值,以便代码可以工作。不要忘记更改数据的值

export const Table = () => {
    const [users, setUsers] = useState([
        { id: 'john1', firstName: "John1", lastName: "Doe1", email: "[email protected]", phone: "1234567890", freeTextField: "Random1" },
        { id: '2', firstName: "John2", lastName: "Doe2", email: "[email protected]", phone: "2345678901", freeTextField: "Random2" },
        { id: '3', firstName: "John3", lastName: "Doe3", email: "[email protected]", phone: "3456789012", freeTextField: "Random3" },
        { id: '4', firstName: "John4", lastName: "Doe4", email: "[email protected]", phone: "4567890123", freeTextField: "Random4" },
        { id: '5', firstName: "John5", lastName: "Doe5", email: "[email protected]", phone: "5678901234", freeTextField: "Random5" },
    ]);
    const [editingRows, setEditingRows] = useState({});


    const handleAddRow = (): void => {
        const newRow: any = {
            id: users.length + 1,
            firstName: "",
            lastName: "",
            email: "",
            phone: "",
            freeTextField: "",
        };
        setUsers((prevList: any) => [newRow, ...prevList]);
        const val = {...{ [`${users.length + 1}`]: true }  }
        setEditingRows(val);
    };

    const onRowEditComplete = (e: any) => {
        const _users = [...users];
        const { newData, index } = e;

        _users[index] = newData;

        setUsers(_users);
    };

    const textEditor = (options: any) => {
        return (
            <InputText
                type="text"
                value={options.value}
                onChange={(e) => options.editorCallback(e.target.value)}
            />
        );
    };

    const onRowEditChange = (e:any) => {
        setEditingRows(e.data);
    }

    return (
        <div className="table-wrapper">
            <h2 className="table-name">PrimeReact data table</h2>
            <button onClick={handleAddRow}>add row</button>

            <DataTable
                value={users}
                tableStyle={{ minWidth: "50rem" }}
                editMode="row"
                editingRows={editingRows}
                dataKey="id"
                onRowEditChange={onRowEditChange}
                onRowEditComplete={onRowEditComplete}
            >
                <Column
                    field="firstName"
                    header="firstName"
                    editor={(options) => textEditor(options)}
                ></Column>
                <Column
                    field="lastName"
                    header="lastName"
                    editor={(options) => textEditor(options)}
                ></Column>
                <Column
                    field="email"
                    header="email"
                    editor={(options) => textEditor(options)}
                ></Column>
                <Column
                    field="phone"
                    header="phone"
                    editor={(options) => textEditor(options)}
                ></Column>
                <Column style={{ maxWidth: "15%" }} rowEditor>
                    edit
                </Column>
            </DataTable>
        </div>
    );
};

0
投票

正如我们的朋友@Petros 之前提到的,您需要 3 点

添加 useState 但我会将其修改为适用于任何添加的新行

任何没有定义 id 的新行都将是未定义的,所以我们将使用这个技巧

const [editingRows, setEditingRows] = useState({undefined: true}); 

在handleAddRow中不需要

const val = {...{ [`${users.length + 1}`]: true }  }
        setEditingRows(val);

handleAddRow 中的小注释,如果有人尝试复制...请确保您不会添加像 {} 这样的空对象,也许至少不会有一个像 { dummy: "" } 这样的空字段

import { DataTable } from "primereact/datatable";
import { Column } from "primereact/column";
import { data } from "../data";
import { useState } from "react";
import { InputText } from "primereact/inputtext";

export const Table = () => {
  const [users, setUsers] = useState(data);
  const [editingRows, setEditingRows] = useState({undefined: true});

  const handleAddRow = (): void => {
    const newRow: any = {
      firstName: "",
      lastName: "",
      email: "",
      phone: "",
      freeTextField: "",
    };
    setUsers((prevList: any) => [newRow, ...prevList]);
  };
  const onRowEditChange = (e:any) => {
        setEditingRows(e.data);
    }

  const onRowEditComplete = (e: any) => {
    const _users = [...users];
    const { newData, index } = e;

    _users[index] = newData;

    setUsers(_users);
  };

  const textEditor = (options: any) => {
    return (
      <InputText
        type="text"
        value={options.value}
        onChange={(e) => options.editorCallback(e.target.value)}
      />
    );
  };

  return (
    <div className="table-wrapper">
      <h2 className="table-name">PrimeReact data table</h2>
      <button onClick={handleAddRow}>add row</button>

      <DataTable
        dataKey="id"
        value={users}
        tableStyle={{ minWidth: "50rem" }}
        editMode="row"
        editingRows={editingRows}
        onRowEditComplete={onRowEditComplete}
      >
        <Column
          field="firstName"
          header="firstName"
          editor={(options) => textEditor(options)}
        ></Column>
        <Column
          field="lastName"
          header="lastName"
          editor={(options) => textEditor(options)}
        ></Column>
        <Column
          field="email"
          header="email"
          editor={(options) => textEditor(options)}
        ></Column>
        <Column
          field="phone"
          header="phone"
          editor={(options) => textEditor(options)}
        ></Column>
        <Column style={{ maxWidth: "15%" }} rowEditor>
          edit
        </Column>
      </DataTable>
    </div>
  );
};
© www.soinside.com 2019 - 2024. All rights reserved.