使用react在表中添加和克隆列

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

我是 React 新手,当我单击添加按钮时,它应该创建一个带有文本框的新列,并且文本框中没有值 添加流量数据列内的按钮。 克隆应克隆流数据列。 我调试了但仍然没有运气。 提供下面的代码和 stackblitz。你能让我知道如何解决它吗?

https://stackblitz.com/edit/vitejs-vite-vfkx1u?file=src%2FApp.css,src%2Fmain.tsx,src%2FApp.jsx&terminal=dev

import { useState } from 'react';
import './App.css';
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';

function App() {
  const [panelOpen, setPanelOpen] = useState(false);

  const [testData] = useState([
    {
      id: '663ba042b53ea521b6f77c64',
      flowNames: [
        'SPORTSClearWhatsNewVip',
        'SPORTSClearWhatsNewVip',
        'SPORTS Simplified',
        'SPORTSClearWhatsNewBoxLevel',
        'SPORTSClearWhatsNewBoxLevel',
        'SPORTSClearWhatsNewVip',
        'SPORTSHCFlow',
        'SPORTSClearWhatsNewVip',
        'SPORTSClearWhatsNewBoxLevel',
        'SPORTS Simplified',
      ],
      application: 'SPORTS',
      name: 'SPORTSHC-Copy',
      tags: ['SPORTSHC-Copy'],
      healthCheck: true,
      deleted: false,
    },
  ]);

  const [columns, setColumns] = useState({
    column1: { id: 'column1', items: testData[0].flowNames }, // Populate column1 with flowNames
    column2: { id: 'column2', items: ['Sample_Step1', 'Sample_Step2'] },
    column3: {
      id: 'column3',
      items: ['Sample_Step3', 'Sample_Step4', 'Sample_Step5', 'Sample_Step6'],
    },
  });

  const tableData = [
    { step: 'Sample_Step1', stepNum: '1', data: 'Enter Text' },
    { step: 'Sample_Step2', stepNum: '2', data: 'Click Button' },
  ];

  const handleDragEnd = (result) => {
    console.log('columns', columns);
    const { source, destination } = result;

    if (!destination) return;

    const sourceColumn = columns[source.droppableId];
    const destColumn = columns[destination.droppableId];

    if (source.droppableId === destination.droppableId) {
      const copiedItems = [...sourceColumn.items];
      const [removed] = copiedItems.splice(source.index, 1);
      copiedItems.splice(destination.index, 0, removed);

      setColumns({
        ...columns,
        [source.droppableId]: { ...sourceColumn, items: copiedItems },
      });
    } else {
      const draggedItem = sourceColumn.items[source.index];

      if (destination.droppableId === 'column3') {
        const panelItem = sourceColumn.items[source.index];
        const newItem = {
          step: panelItem,
          stepNum: String(destColumn.items.length + 1),
          data: 'New Data',
        };

        const updatedSourceItems = sourceColumn.items.filter(
          (item, index) => index !== source.index
        );

        setColumns((prevColumns) => ({
          ...prevColumns,
          column3: {
            ...prevColumns.column3,
            items: [...prevColumns.column3.items, panelItem],
          },
          [source.droppableId]: { ...sourceColumn, items: updatedSourceItems },
          tableData: [...tableData, newItem],
        }));
      } else {
        const updatedDestinationItems = [...destColumn.items, draggedItem];

        setColumns((prevColumns) => ({
          ...prevColumns,
          column1: {
            ...prevColumns.column1,
            items: [...prevColumns.column1.items, draggedItem],
          },
          column2: {
            ...prevColumns.column2,
            items: [...prevColumns.column2.items, draggedItem],
          },
          column3: {
            ...prevColumns.column3,
            items: prevColumns.column3.items.filter(
              (item, index) => index !== source.index
            ),
          },
        }));
      }
    }
  };

  console.log('testData[0].flowNames', testData[0].flowNames);

  const handleCloneColumn = (columnId) => {
    setColumns((prevColumns) => ({
      ...prevColumns,
      [`newColumn${columnId}`]: {
        id: `newColumn${columnId}`,
        items: [...prevColumns[columnId].items],
      },
    }));
  };

  const handleDeleteColumn = (columnId) => {
    setColumns((prevColumns) => {
      const newColumns = { ...prevColumns };
      delete newColumns[columnId];
      return newColumns;
    });
  };

  return (
    <div>
      <DragDropContext onDragEnd={handleDragEnd}>
        <div style={{ display: 'flex' }}>
          <Droppable droppableId="column1">
            {(provided) => (
              <div
                className="drag"
                {...provided.droppableProps}
                ref={provided.innerRef}
              >
                <h5>column 1 header</h5>
                {columns.column2.items.map((item, index) => (
                  <Draggable key={item} draggableId={item} index={index}>
                    {(provided) => (
                      <div
                        {...provided.draggableProps}
                        {...provided.dragHandleProps}
                        ref={provided.innerRef}
                      >
                        <p>{item}</p>
                      </div>
                    )}
                  </Draggable>
                ))}
                {provided.placeholder}
              </div>
            )}
          </Droppable>
          <Droppable droppableId="column2">
            {(provided) => (
              <div
                className="drag"
                {...provided.droppableProps}
                ref={provided.innerRef}
              >
                <h5>column 2 header</h5>
                <table>
                  <thead>
                    <tr>
                      <th>Flow Steps</th>
                      <th>+T</th>
                      <th>
                        Flow Data{' '}
                        <p onClick={() => handleCloneColumn('column2')}>
                          clone
                        </p>{' '}
                        <span onClick={() => handleDeleteColumn(columnId)}>
                          Delete
                        </span>
                        <span> ADD</span>
                      </th>
                    </tr>
                  </thead>
                  <tbody>
                    {columns.column2.items.map((item, index) => (
                      <Draggable key={item} draggableId={item} index={index}>
                        {(provided) => (
                          <tr
                            {...provided.draggableProps}
                            {...provided.dragHandleProps}
                            ref={provided.innerRef}
                          >
                            <td>
                              <p>{item}</p>
                            </td>
                            <td>T({`${item.replace('Sample_Step', '')}`})</td>
                            <td>
                              Click button{' '}
                              <input
                                type="text"
                                id="fname"
                                name="fname"
                                value="text1"
                              />
                              <input
                                type="text"
                                id="fname"
                                name="fname"
                                value="text2"
                              />
                            </td>
                          </tr>
                        )}
                      </Draggable>
                    ))}
                  </tbody>
                </table>
                {provided.placeholder}
              </div>
            )}
          </Droppable>
          <Droppable droppableId="column3">
            {(provided) => (
              <div
                className="drag"
                {...provided.droppableProps}
                ref={provided.innerRef}
              >
                <h5>
                  column 3 header{' '}
                  <span onClick={() => setPanelOpen(!panelOpen)}>
                    open panel
                  </span>
                </h5>
                {panelOpen && (
                  <div className="vertical-panel">
                    {columns.column3.items.map((item, index) => (
                      <Draggable key={item} draggableId={item} index={index}>
                        {(provided) => (
                          <div
                            {...provided.draggableProps}
                            {...provided.dragHandleProps}
                            ref={provided.innerRef}
                          >
                            <p>{item}</p>
                          </div>
                        )}
                      </Draggable>
                    ))}
                  </div>
                )}
                {provided.placeholder}
              </div>
            )}
          </Droppable>
          {/* 
          {Object.keys(columns).map((columnId) => (
            <Droppable key={columnId} droppableId={columnId}>
              {(provided) => (
                <div {...provided.droppableProps} ref={provided.innerRef}>
                  <h5>{`column ${columnId.slice(-1)} header`}</h5>
                  {provided.placeholder}
                </div>
              )}
            </Droppable>
          ))} */}

          {/* {Object.keys(columns).map((columnId) => (
            <Droppable key={columnId} droppableId={columnId}>
              {(provided) => (
                <div
                  className="drag"
                  {...provided.droppableProps}
                  ref={provided.innerRef}
                >
                  <h5>
                    {`column ${columnId.slice(-1)} header`}
                    <span onClick={() => handleDeleteColumn(columnId)}>
                      Delete
                    </span>
                  </h5>
                  {provided.placeholder}
                </div>
              )}
            </Droppable>
          ))} */}
        </div>
      </DragDropContext>
    </div>
  );
}

export default App;
javascript html css reactjs
1个回答
0
投票

您似乎正在尝试添加功能以使用 React 在表中动态添加和克隆列。我将指导您完成实现此目标所需的修改:

  1. 添加新列

要在单击“+ ADD”按钮时添加新列,您可以实现一个函数来处理此操作。此函数应更新状态以包含新列。方法如下:

const handleAddColumn = () => {
  const newColumnId = `column${Object.keys(columns).length + 1}`;
  setColumns((prevColumns) => ({
    ...prevColumns,
    [newColumnId]: { id: newColumnId, items: [] }, // Initialize with empty items array
  }));
};
  1. 克隆列:

要克隆列,您已经有了handleCloneColumn函数,但是在调用该函数时需要传递正确的columnId。另外,请确保使用新的唯一列 ID 更新状态。方法如下:

const handleCloneColumn = (columnId) => {
  const newColumnId = `newColumn${Object.keys(columns).length + 1}`;
  setColumns((prevColumns) => ({
    ...prevColumns,
    [newColumnId]: { id: newColumnId, items: [...prevColumns[columnId].items] },
  }));
};
  1. 更新按钮的 JSX:

更新列标题中按钮的 JSX 以包含添加新列和克隆列的功能。这是更新后的 JSX:

<th>
  Flow Data
  <p onClick={() => handleCloneColumn('column2')}>Clone</p>
  <span onClick={() => handleDeleteColumn('column2')}>Delete</span>
  <span onClick={handleAddColumn}>+ ADD</span>
</th>

通过这些修改,您应该能够在 React 表组件中动态添加新列并克隆现有列。请记住相应地调整代码中依赖于列结构或 ID 的任何其他部分。

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