This is my Cell data in column:
import { format } from "date-fns";
export const COLUMNS_ALLLOAN = [
{
Header: "Id",
accessor: "id",
Cell: ({ row }) => Number(row.id) + 1,
},
{
Header: "Account Number",
accessor: "acNumber",
Cell: ({ row }) => <>{row.original.acNumber}</>,
},
{
Header: "Account Name",
accessor: "acName",
},
{
Header: "Loan Type",
accessor: "acType",
Cell: ({ row }) => <>{row.original.acType}</>,
},
{
Header: "Opening Date",
accessor: "acOpen",
Cell: ({ row }) => <>{row.original.acOpen}</>,
},
{
Header: "Sanction Date",
accessor: "acSanction",
Cell: ({ row }) => <>{row.original.acSanction}</>,
},
{
Header: "Expiry Date",
accessor: "acExpiry",
Cell: ({ row }) => <>{row.original.acExpiry}</>,
},
{
Header: "Limit",
accessor: "acLimit",
Cell: ({ row }) => <>{Number(row.original.acLimit)}</>,
},
{
Header: "Outstanding",
accessor: "lastDayBalance",
Cell: ({ row }) => <>{Number(row.original.lastDayBalance)}</>,
},
{
Header: "Overlimit",
accessor: "overlimit",
Cell: ({ row }) => <>{Number(row.original.overLimit)}</>,
},
{
Header: "Available",
accessor: "available",
Cell: ({ row }) => <>{Number(row.original.availableBalance)}</>,
},
{
Header: "Edit",
accessor: "edit",
Cell: ({ row }) => <button className="btn btn-primary">Edit</button>,
},
{
Header: "Delete",
accessor: "X",
Cell: ({ row }) => <button className="btn btn-danger">X</button>,
},
];
This is my page
import React, { useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import { useNavigate } from "react-router-dom";
import Footer from "../../components/Footer";
import { useMemo } from "react";
import { useTable, useSortBy, useGlobalFilter, usePagination } from "react-table";
import { COLUMNS_ALLLOAN } from "../../components/COLUMNS_ALLLOAN.js";
import Globalfilter from "../../components/Globalfilter";
import { deleteById, getLoans } from "../../features/bradvance/advanceSlice";
const Allloans = () => {
const dispatch = useDispatch();
const { allLoans } = useSelector((state) => state.bradvance);
const navigate = useNavigate();
const goBack = async () => {
navigate(-1);
};
const columns = useMemo(() => COLUMNS_ALLLOAN, []);
const data = useMemo(() => allLoans, []);
// console.log(data);
const tableInstance = useTable(
{
columns,
data: allLoans,
initialState: { pageSize: 30 },
},
useGlobalFilter,
useSortBy,
usePagination
);
const {
headerGroups,
getTableProps,
getTableBodyProps,
page,
prepareRow,
state,
setGlobalFilter,
nextPage,
previousPage,
canNextPage,
canPreviousPage,
pageOptions,
setPageSize,
gotoPage,
pageCount,
} = tableInstance;
const { globalFilter, pageIndex, pageSize } = state;
// console.log(data.length);
const totalLoan = allLoans
.map((item, sl) => {
return item.lastDayBalance;
})
.reduce((acc, curValue) => {
// console.log(curValue);
return acc + curValue;
}, 0);
// console.log(totalLoan);
const handleClick = (id) => {
dispatch(deleteById(id));
alert("Deleted Successfully.");
console.log(id);
};
return (
<>
<div className="container">
<div className="row">
<div className="col">
<div className="summary">
<h1 className="p-4 text-center fw-bold mb-0">All Loans</h1>
</div>
</div>
</div>
<div className="row">
<div className="col">
<Globalfilter filter={globalFilter} setFilter={setGlobalFilter} />
</div>
</div>
<div className="row">
<div className="col">
<div className="summary table-responsive">
<table {...getTableProps()} className="table table-hover table-bordered">
<thead>
{headerGroups.map((headerGroup) => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map((column) => (
<th {...column.getHeaderProps(column.getSortByToggleProps())}>{column.render("Header")} </th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{page.map((row, i) => {
prepareRow(row);
return (
<tr {...row.getRowProps()}>
{row.cells.map((cell) => {
return (
<td onClick={() => handleClick(row.original.id)} {...cell.getCellProps()}>
{cell.render("Cell")}
</td>
);
})}
</tr>
);
})}
</tbody>
</table>
</div>
</div>
</div>
<div className="row ">
<div className="col d-flex justify-content-end">
<ul className="list-group list-group-horizontal">
<li className="list-group-item fw-bold">
Total Loan: <span className="fw-bold text-danger">{allLoans.length}</span>
</li>
<li className="list-group-item fw-bold">
Total Amount:<span className="fw-bold text-danger">{totalLoan.toFixed(2)}</span>{" "}
</li>
</ul>
</div>
</div>
<div className="section p-5 pagination col-12">
<button className="page-link" onClick={() => gotoPage(0)} disabled={!canPreviousPage}>
{"<<"}
</button>{" "}
<button className="page-link" onClick={() => previousPage()} disabled={!canPreviousPage}>
{"<"}
</button>{" "}
<button className="page-link" onClick={() => nextPage()} disabled={!canNextPage}>
{">"}
</button>{" "}
<button className="page-link" onClick={() => gotoPage(pageCount - 1)} disabled={!canNextPage}>
{">>"}
</button>{" "}
<span className="page-link">
Page{" "}
<strong>
{pageIndex + 1} of {pageOptions.length}
</strong>{" "}
</span>
<span className="page-link">
| Go to page:{" "}
<input
type="number"
value={pageIndex + 1}
onChange={(e) => {
const page = e.target.value ? Number(e.target.value) - 1 : 0;
gotoPage(page);
}}
style={{ width: "100px" }}
/>
</span>{" "}
<select
className="page-link"
value={pageSize}
onChange={(e) => {
setPageSize(Number(e.target.value));
}}
>
{[20, 50, 100, 200, 500].map((pageSize) => (
<option key={pageSize} value={pageSize} className="page-link">
Show {pageSize}
</option>
))}
</select>
</div>
{/* Go Back */}
<div className="row ">
<div className="col ">
<div className="text-center summary pb-3">
<button className="btn btn-outline-primary mb-0" onClick={goBack}>
<i className="bi bi-skip-backward"></i> Go Back
</button>
</div>
</div>
</div>
<div className="row">
<div className="col">
<Footer />
</div>
</div>
</div>
</>
);
};
export default Allloans;
This is how my page looks:
I can delete each row successfully. The problem is that it deletes when I click on any part of the row. But, I want only the button to be clickable not the whole row. I mean, when I click the delete button only, it should delete.
First, remove the onClick={() => handleClick(row.original.id)}
from your row td tag so it become as follows
{row.cells.map((cell) => {
return (
<td {...cell.getCellProps()}>
{cell.render("Cell")}
</td>
);
})}
next, move your on-click handler to the top of the table instance creation
...
const handleClick = (id) => {
dispatch(deleteById(id));
alert("Deleted Successfully.");
console.log(id);
};
const tableInstance = useTable(
{
...
}
);
then, remove the last two columns' definitions (Edit & Delete def) from COLUMNS_ALLLOAN
and insert those col definitions into useTable and finally add the onClick event listener to the delete button.
const tableInstance = useTable(
{
columns,
data: allLoans,
initialState: { pageSize: 30 },
},
useGlobalFilter,
useSortBy,
usePagination,
// create Edit and Delete col definition by pushing the two into visibleColumns
(hooks) => {
hooks.visibleColumns.push((col) => [
...col,
{
Header: "Edit",
id: "editBtn",
Cell: ({ row }) => <button className="btn btn-primary">Edit</button>,
},
{
Header: "Delete",
id: "deleteBtn",
Cell: ({ row }) => <button onClick={() => handleClick(row.original.id)} className="btn btn-danger">X</button>,
},
]);
}
);
Here is the minimal example: