简体   繁体   中英

How to add a new editable row in React-Table?

I'm building a dynamic table using React-Table and i want to add a new row of editable cells. At the moment i can add new row but only when i press the global edit button i can edit it, instead i want to add a row which would be editable at first. This is my code -

Main component

function StyledTable() {
  useEffect(() => {
    dispatch(getData(mokeJsonData));
  }, []);
  const [datatoColumns] = useState(columnDataaa.slice(1));
  const [skipPageReset, setSkipPageReset] = useState(false);
  const data = useSelector((state) => state.dataReducer.data);
  const dispatch = useDispatch();

  const columns = useMemo( 
    () => [
      {
        Header: "",
        id: "expander", 
        Cell2: ({ row }) => { 
          return (
            <span {...row.getToggleRowExpandedProps()}>  
              {row.isExpanded ? "-" : "+"}
            </span>
          );
        },
        Cell: () => {
          return <div></div>;
        },
      },
      {
        Header: columnDataaa[0].Header,
        accessor: columnDataaa[0].accessor,
        Cell: ({ value, row }) => {
          return (
            <FlexDiv>
              <HighlightOffIcon
                style={{ marginRight: "5px", color: "grey", width: "20px" }}
                onClick={() => dispatch(deleteRow(row.index))}
              />
              {value}
            </FlexDiv>
          );
        },
      },
      ...datatoColumns,
    ],
    []
  );

  useEffect(() => {
    setSkipPageReset(false);
  }, [data]);

  const renderRowSubComponent = useCallback(
    ({ row }) => ({
      values: row.original.addInfo && row.original.addInfo,
    }),
    []
  );
  return (
    <Styles>
      <h1>הגדרת מנהל</h1>
      <Table
        columns={columns}
        skipPageReset={skipPageReset}
        renderRowSubComponent={renderRowSubComponent}
      />
    </Styles>
  );
}

export default StyledTable;

Editable Cell

const EditableCell = ({
  value: initialValue,
  row: { index },
  column: { id, editable, type, width, valueOptions },
}) => {
  const [value, setValue] = useState(initialValue);

  const onChange = (e) => {
    setValue(e.target.value);
  };
  const dispatch = useDispatch();

  const onBlur = () => {
    if (value === "") return alert("requiredddd");
    return dispatch(updateMyData({ index, id, value }));
  };

  useEffect(() => {
    setValue(initialValue);
  }, [initialValue]); 

  if (type === "singleSelect")
    return (
      <InputSelect
        value={value}
        onChange={onChange}
        onBlur={onBlur}
        style={{ width: width }}
      >
        {valueOptions.map((item, i) => {
          return (
            <option value={item.label} key={i}>
              {item.label}
            </option>
          );
        })}
      </InputSelect>
    );
  if (type === "date")
    return (
      <DatePicker
        style={{ width: width }}
        type="date"
        disabled={editable === false}
        value={value}
        onChange={onChange}
        onBlur={onBlur}
      />
    );
  return (
    <input
      style={{ width: width }}
      disabled={editable === false}
      value={value}
      onChange={onChange}
      onBlur={onBlur}
    />
  );
};

export default EditableCell;

Add Row function

 addRow: (state, action) => {
      const obj = {};
      action.payload.slice(1).forEach((item) => {
        obj[item.accessor] = '';
      });
      if (
        obj &&
        Object.keys(obj).length === 0 &&
        Object.getPrototypeOf(obj) === Object.prototype
      )
        return;
      else {
        state.data.splice(0, 0, obj);
        state.originalData = state.data;
      }
    },

Thanks

Pass the state variable and method to the useTable() root hook. custom plugin hooks and other variables/methods maintaining the component state are returned from the table instance. These you can later retrieve from anywhere you want.

const {
    // all your hooks...
  } = useTable(
    {
      columns,
      data,
      // all your other hooks...
      updateMyData,
      // pass state variables so that we can access them in edit hook later
      editableRowIndex, // index of the single row we want to edit 
      setEditableRowIndex // setState hook for toggling edit on/off switch
    },
    // other hooks... 
    (hooks) => {
      hooks.allColumns.push((columns) => [
        // other hooks such as selection hook
        ...columns,
        // edit hook
        {
          accessor: "edit",
          id: "edit",
          Header: "edit",
          Cell: ({ row, setEditableRowIndex, editableRowIndex }) => (
            <button
              className="action-button"
              onClick={() => {
                const currentIndex = row.index;
                if (editableRowIndex !== currentIndex) {
                  // row requested for edit access
                  setEditableRowIndex(currentIndex);
                } else {
                  // request for saving the updated row
                  setEditableRowIndex(null); // keep the row closed for edit after we finish updating it
                  const updatedRow = row.values;
                  console.log("updated row values:");
                  console.log(updatedRow);
                  // call your updateRow API
                }
              }}
            >
              {/* single action button supporting 2 modes */}
              {editableRowIndex !== row.index ? "Edit" : "Save"}
            </button>
          )
        }
      ]);
    }
  );

you can found example from bellow link

github repo link: https://github.com/smmziaul/only-one-row-editable

code sandbox link: https://codesandbox.io/s/github/smmziaul/only-one-row-editable

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