I am trying to implement a row filtering feature based on column values similar to that of MS Excel. I have implemented it as a separate filtering component that gets the value of column data with checkboxes and stores the value of selected data in an array. The filtering component is a child component of the main parent table. I am unable to figure out how to keep the values of column data separately so that I can filter the table data based on it.
Codesandbox:https://codesandbox.io/s/stickyheadtable-material-demo-forked-5xy27?file=/FilteringComponent.js:0-3472
Below is my implementation: "Main Table Component"
```import * as React from "react";
import Paper from "@mui/material/Paper";
import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TableHead from "@mui/material/TableHead";
import TablePagination from "@mui/material/TablePagination";
import TableRow from "@mui/material/TableRow";
import FilteringComponent from "./FilteringComponent";
const columns = [
{ id: "name", label: "Name", minWidth: 170 },
{ id: "code", label: "ISO\u00a0Code", minWidth: 100 },
{
id: "population",
label: "Population",
minWidth: 170,
align: "right",
format: (value) => value.toLocaleString("en-US")
},
{
id: "size",
label: "Size\u00a0(km\u00b2)",
minWidth: 170,
align: "right",
format: (value) => value.toLocaleString("en-US")
},
{
id: "density",
label: "Density",
minWidth: 170,
align: "right",
format: (value) => value.toFixed(2)
}
];
function createData(name, code, population, size) {
const density = population / size;
return { name, code, population, size, density };
}
const rows = [
createData("India", "IN", 1324171354, 3287263),
createData("China", "CN", 1403500365, 9596961),
createData("Italy", "IT", 60483973, 301340),
createData("United States", "US", 327167434, 9833520),
createData("Canada", "CA", 37602103, 9984670),
createData("Australia", "AU", 25475400, 7692024),
createData("Germany", "DE", 83019200, 357578),
createData("Ireland", "IE", 4857000, 70273),
createData("Mexico", "MX", 126577691, 1972550),
createData("Japan", "JP", 126317000, 377973),
createData("France", "FR", 67022000, 640679),
createData("United Kingdom", "GB", 67545757, 242495),
createData("Russia", "RU", 146793744, 17098246),
createData("Nigeria", "NG", 200962417, 923768),
createData("Brazil", "BR", 210147125, 8515767)
];
const filteringAllowed = ["name", "code"];
export default function StickyHeadTable() {
const [page, setPage] = React.useState(0);
const [rowsPerPage, setRowsPerPage] = React.useState(10);
const [columnFilter, setColumnFilter] = React.useState();
const handleChangePage = (event, newPage) => {
setPage(newPage);
};
const handleChangeRowsPerPage = (event) => {
setRowsPerPage(+event.target.value);
setPage(0);
};
//data for filteringcomponent
const data4FilteringComponent = [...rows];
const addFilter = (data) => {
console.log("d", data);
setColumnFilter({ ...data });
};
console.log("from parent", columnFilter);
return (
<Paper sx={{ width: "100%", overflow: "hidden" }}>
<TableContainer sx={{ maxHeight: 440 }}>
<Table stickyHeader aria-label="sticky table">
<TableHead>
<TableRow>
{columns.map((column) => (
<TableCell
key={column.id}
align={column.align}
style={{ minWidth: column.minWidth }}
>
{column.label}
{filteringAllowed.includes(column.id) && (
<FilteringComponent
filteringOn={filteringAllowed.filter(
(x) => x === column.id
)}
columnData={data4FilteringComponent.map(
(x) => x[column.id]
)}
addFilter={addFilter}
/>
)}
</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{rows
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
.map((row) => {
return (
<TableRow hover role="checkbox" tabIndex={-1} key={row.code}>
{columns.map((column) => {
const value = row[column.id];
return (
<TableCell key={column.id} align={column.align}>
{column.format && typeof value === "number"
? column.format(value)
: value}
</TableCell>
);
})}
</TableRow>
);
})}
</TableBody>
</Table>
</TableContainer>
<TablePagination
rowsPerPageOptions={[10, 25, 100]}
component="div"
count={rows.length}
rowsPerPage={rowsPerPage}
page={page}
onPageChange={handleChangePage}
onRowsPerPageChange={handleChangeRowsPerPage}
/>
</Paper>
);
}```
FilteringComponent:
```import * as React from "react";
import Box from "@mui/material/Box";
import Avatar from "@mui/material/Avatar";
import Menu from "@mui/material/Menu";
import MenuItem from "@mui/material/MenuItem";
import ListItemIcon from "@mui/material/ListItemIcon";
import Divider from "@mui/material/Divider";
import IconButton from "@mui/material/IconButton";
import Typography from "@mui/material/Typography";
import Tooltip from "@mui/material/Tooltip";
import FilterAltIcon from "@mui/icons-material/FilterAlt";
import FormLabel from "@mui/material/FormLabel";
import FormControl from "@mui/material/FormControl";
import FormGroup from "@mui/material/FormGroup";
import FormControlLabel from "@mui/material/FormControlLabel";
import Checkbox from "@mui/material/Checkbox";
const FilteringComponent = ({ filteringOn, columnData, addFilter }) => {
const [anchorEl, setAnchorEl] = React.useState(null);
const [checkedState, setCheckedState] = React.useState(
new Array(columnData.length).fill(false)
);
const open = Boolean(anchorEl);
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
const handleOnChange = (position) => {
const updatedCheckedState = checkedState.map((item, index) =>
index === position ? !item : item
);
setCheckedState(updatedCheckedState);
};
React.useEffect(() => {
const a = columnData.filter((x, index) => checkedState[index] === true);
addFilter({ [filteringOn]: a });
}, [checkedState]);
return (
<React.Fragment>
<Box sx={{ display: "flex", alignItems: "center", textAlign: "center" }}>
<Tooltip title="Account settings">
<IconButton onClick={handleClick} size="small" sx={{ ml: 2 }}>
<Avatar sx={{ width: 32, height: 32 }}>
<FilterAltIcon />
</Avatar>
</IconButton>
</Tooltip>
</Box>
<Menu
anchorEl={anchorEl}
open={open}
onClose={handleClose}
onClick={handleClose}
PaperProps={{
elevation: 0,
sx: {
overflow: "visible",
filter: "drop-shadow(0px 2px 8px rgba(0,0,0,0.32))",
mt: 1.5,
"& .MuiAvatar-root": {
width: 32,
height: 32,
ml: -0.5,
mr: 1
},
"&:before": {
content: '""',
display: "block",
position: "absolute",
top: 0,
right: 14,
width: 10,
height: 10,
bgcolor: "background.paper",
transform: "translateY(-50%) rotate(45deg)",
zIndex: 0
}
}
}}
transformOrigin={{ horizontal: "right", vertical: "top" }}
anchorOrigin={{ horizontal: "right", vertical: "bottom" }}
>
{columnData.map((x, index) => {
return (
<MenuItem key={index}>
<FormGroup>
<FormControlLabel
control={
<Checkbox
checked={checkedState[index]}
onChange={() => handleOnChange(index)}
/>
}
label={x}
/>
</FormGroup>
</MenuItem>
);
})}
</Menu>
</React.Fragment>
);
};
export default FilteringComponent;
```