Skip to content

Instantly share code, notes, and snippets.

@rathorevaibhav
Created February 26, 2025 10:18
Show Gist options
  • Save rathorevaibhav/bf719002285c04d607958b23906ec6ce to your computer and use it in GitHub Desktop.
Save rathorevaibhav/bf719002285c04d607958b23906ec6ce to your computer and use it in GitHub Desktop.
multi-select-table with infinite scroll
import React, { useState, useEffect, useRef } from "react";
const generateRows = (start, count) =>
Array.from({ length: count }, (_, i) => ({
id: start + i + 1,
name: `Item ${start + i + 1}`,
}));
const MultiSelectTable = () => {
const [rows, setRows] = useState(generateRows(0, 20)); // Initial 20 rows
const [selectedRows, setSelectedRows] = useState(new Set());
const [isSelectAll, setIsSelectAll] = useState(false);
const tableRef = useRef(null);
// Handle individual row selection
const toggleRowSelection = (id) => {
setSelectedRows((prev) => {
const newSelected = new Set(prev);
if (newSelected.has(id)) {
newSelected.delete(id);
} else {
newSelected.add(id);
}
setIsSelectAll(newSelected.size === rows.length);
return newSelected;
});
};
// Handle "Select All" toggle
const toggleSelectAll = () => {
if (isSelectAll) {
setSelectedRows(new Set());
} else {
setSelectedRows(new Set(rows.map((row) => row.id)));
}
setIsSelectAll(!isSelectAll);
};
// Infinite Scroll Load More
const handleScroll = () => {
if (tableRef.current) {
const { scrollTop, scrollHeight, clientHeight } = tableRef.current;
if (scrollHeight - scrollTop <= clientHeight + 20) {
const newRows = generateRows(rows.length, 20);
setRows((prevRows) => [...prevRows, ...newRows]);
}
}
};
useEffect(() => {
const tableEl = tableRef.current;
if (tableEl) {
tableEl.addEventListener("scroll", handleScroll);
}
return () => {
if (tableEl) {
tableEl.removeEventListener("scroll", handleScroll);
}
};
}, [rows]);
// Get selected row IDs
const getSelectedRowIds = () => Array.from(selectedRows);
return (
<div>
<h3>Selected Rows: {selectedRows.size}</h3>
<table ref={tableRef} style={{ height: "400px", overflowY: "auto", display: "block" }}>
<thead>
<tr>
<th>
<input
type="checkbox"
checked={isSelectAll}
onChange={toggleSelectAll}
/>
</th>
<th>Name</th>
</tr>
</thead>
<tbody>
{rows.map((row) => (
<tr
key={row.id}
style={{
backgroundColor: selectedRows.has(row.id) ? "purple" : "white",
color: selectedRows.has(row.id) ? "white" : "black",
}}
>
<td>
<input
type="checkbox"
checked={selectedRows.has(row.id)}
onChange={() => toggleRowSelection(row.id)}
/>
</td>
<td>{row.name}</td>
</tr>
))}
</tbody>
</table>
<button onClick={() => console.log(getSelectedRowIds())}>Get Selected Row IDs</button>
</div>
);
};
export default MultiSelectTable;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment