Home > Back-end >  Is there any way to remove table row using react js?
Is there any way to remove table row using react js?

Time:10-13

I'm tired to make a small list where the user can insert rows and clear a row also once the user submits then it should be visible to the same field.

Now I have faced two problems I can't delete an exact row when I clicked on the delete button the row deletes from the last, but I want it should be deleted exact row, that I want.

And another problem with my clear row button, once I clicked on that then it should be clear all rows without three buttons and a table head.

Here is my full code:

function Test2() {

  const [rows, setRows] = useState([]);

  // Initial states
  const [open, setOpen] = useState(false);
  const [isAdd, setAdd] = useState(false);
  const [disable, setDisable] = useState(true);
  const [showConfirm, setShowConfirm] = useState(false);

  const handleClose = (event, reason) => {
    if (reason === "clickaway") {
      return;
    }
    setOpen(false);
  };


  const handleAdd = () => {
    setRows([
      ...rows,
      {
        id: rows.length   1,
        amount: "",
      },
    ]);
    setAdd(true);
  };

  // Function to handle save
  const handleSave = () => {
    setAdd(!isAdd);
    setRows(rows);
    // console.log("saved : ", rows);
    setDisable(true);
    setOpen(true);
    console.log(rows);
  };

  const handleInputChange = (e, index) => {
    setDisable(false);
    const { name, value } = e.target;
    const list = [...rows];
    list[index][name] = value;
    setRows(list);
  };

  const handleConfirm = () => {
    setShowConfirm(true);
  };


  const handleRemoveClick = (i) => {
    const list = [...rows];
    list.splice(i, 1);
    setRows(list);
    console.log(list);
    setShowConfirm(false);
  };

  // Handle the case of delete confirmation
  // where user click no
  const handleNo = () => {
    setShowConfirm(false);
  };

  const handleClearAll = () => {
    setAdd(false);
  };

  return (
    <div style={{ width: 600, margin: "auto" }}>
      <Button onClick={handleAdd}>
        <AddBoxIcon />
        INSERT NEW ROW
      </Button>
      <Button onClick={handleClearAll}>
        <ClearIcon /> CLEAR ROW
      </Button>

      {disable ? (
        <Button disabled align="right" onClick={handleSave}>
          <DoneIcon />
          SUBMIT
        </Button>
      ) : (
        <Button align="right" onClick={handleSave}>
          <DoneIcon />
          SUBMIT
        </Button>
      )}

      <Table>
        <TableHead>
          <TableRow>
            <TableCell>Item name </TableCell>
            <TableCell>Amount</TableCell>
            <TableCell>Action</TableCell>
          </TableRow>
        </TableHead>

        <TableBody>
          {rows?.map((row, i) => {
            return (
              <TableRow key={i}>
                {isAdd ? (
                  <TableCell>{`Item ${row.id}`}</TableCell>
                ) : (
                  <TableCell>{`Item ${row.id}`}</TableCell>
                )}
                {isAdd ? (
                  <TableCell align="left">
                    <TextField
                      sx={{
                        width: 100,
                      }}
                      type="number"
                      value={row.amount}
                      name="amount"
                      onChange={(e) => handleInputChange(e, i)}
                    />
                  </TableCell>
                ) : (
                  <TableCell>{row.amount}</TableCell>
                )}

                {isAdd ? (
                  <TableCell>
                    <Button className="mr10" onClick={handleConfirm}>
                      <ClearIcon />
                    </Button>
                  </TableCell>
                ) : (
                  <TableCell>
                    <Button className="mr10" onClick={handleConfirm}>
                      <DeleteOutlineIcon />
                    </Button>
                  </TableCell>
                )}
                {showConfirm && (
                  <div>
                    <Dialog open={showConfirm} onClose={handleNo}>
                      <DialogTitle id="alert-dialog-title">
                        {"Confirm Delete"}
                      </DialogTitle>
                      <DialogContent>
                        <DialogContentText id="alert-dialog-description">
                          Are you sure to delete
                        </DialogContentText>
                      </DialogContent>
                      <DialogActions>
                        <Button
                          onClick={() => handleRemoveClick(i)}
                          color="primary"
                          autoFocus
                        >
                          Yes
                        </Button>
                        <Button onClick={handleNo} color="primary" autoFocus>
                          No
                        </Button>
                      </DialogActions>
                    </Dialog>
                  </div>
                )}
              </TableRow>
            );
          })}

          <Snackbar open={open} autoHideDuration={2000} onClose={handleClose}>
            <Alert onClose={handleClose} severity="success">
              Record saved successfully!
            </Alert>
          </Snackbar>
        </TableBody>
      </Table>
    </div>
  );
}

export default Test2;

CodePudding user response:

Your problem is you're using i (index) which will be changed when you add/remove rows, so I'd suggest that you should use id (row id) instead

handleRemoveClick(row.id)

And then modify handleRemoveClick to

const handleRemoveClick = (rowId) => {
    const list = rows.filter(row => row.id !== rowId); //only remove the selected row
    setRows(list);
    setShowConfirm(false);
};

Along with that, you also need to make your row ids unique

const generateUniqueId = () => {  
  return 'xxxx-xxxx-xxx-xxxx'.replace(/[x]/g, (c) => {  
        const r = Math.floor(Math.random() * 16);  
        return r.toString(16);  
  });  
}

const handleAdd = () => {
    setRows([
      ...rows,
      {
        id: generateUniqueId(),
        amount: "",
      },
    ]);
    setAdd(true);
};

If you don't want to have a unique id generator, you have to modify all row ids

const handleRemoveClick = (rowId) => {
    let list = rows.filter(row => row.id !== rowId); //only remove the selected row
    list = list.map((row, index) => ({
       ...row,
       id: index //assign the new index for id
    }));
    setRows(list);
    setShowConfirm(false);
};

Side note, this way will re-render all rows that may cause some performance problems if you have too many rows to modify.


For your second problem to clear all rows, you should modify handleClearAll like below

const handleClearAll = () => {
    setAdd(false);
    setRows([]);//clear all rows
};
  • Related