If you want dynamically fetch data and filters from api refer to full dynamic section at the end of answer, there is an implementation that create everything dynamically.
Static Version:
Create name and category as follow
let id = 0;
const unique = prop => {
const res = [];
data.forEach(v => {
if (res.findIndex(i => i[prop] === v[prop]) === -1)
res.push({ ol_id: id++, [prop]: v[prop] });
});
return res;
};
const checkBoxol_name = unique("ol_name");
const checkBoxol_category = unique("category");
Then write a filter
const [filters, setFilters] = useState({
category: [],
ol_name: []
});
const filterData = () => {
let result = data;
Object.keys(filters).forEach(key => {
if (filters[key].length !== 0)
result = result.filter(item => filters[key].indexOf(item[key]) !== -1);
});
return result;
};
Your tableBody should be like this
<tbody>
{filterData().map(item => (
<tr>
<td>{item.ol_name}</td>
<td>{item.ol_id}</td>
<td>{item.ol_Amt}</td>
<td>{item.ol_Date}</td>
<td>{item.category}</td>
</tr>
))
}
</tbody>
change your category checkboxes as follow
<input
type="checkbox"
className="custom-control-input"
id={li.ol_id}
name={li.category}
filter="category"
onChange={handleChange}
/>
change your name checkboxes as follow
<input
type="checkbox"
className="custom-control-input"
id={li.ol_id}
name={li.ol_name}
filter="ol_name"
onChange={handleChange}
/>
Then add handleChange method
const handleChange = e => {
let name = e.target.name;
let filter = e.target.getAttribute("filter");
let checked = e.target.checked;
if (checked) {
let newFilter = [...filters[filter]];
newFilter.push(name);
setFilters({ ...filters, [filter]: newFilter });
} else {
setFilters({
...filters,
[filter]: filters[filter].filter(item => item !== name)
});
}
};
Link to the sandbox (https://codesandbox.io/s/thirsty-edison-is6zy?file=/src/App.js:987-1269).
Full Dynamic Version:
For a full dynamic version do as follow
const data = [....]; // Read from API
const filterBy = [...]; // Read from API
let id = 0;
const unique = prop => {
const res = [];
data.forEach(v => {
if (res.findIndex(i => i[prop] === v[prop]) === -1)
res.push({ ol_id: id++, [prop]: v[prop] });
});
return res;
};
const filterGroups = {};
let init = {};
filterBy.forEach(item => {
init[item] = [];
filterGroups[item] = unique(item);
});
const [filters, setFilters] = useState(init);
const filterData = () => {
let result = data;
Object.keys(filters).forEach(key => {
if (filters[key].length !== 0)
result = result.filter(item => filters[key].indexOf(item[key]) !== -1);
});
return result;
};
const handleChange = e => {
let name = e.target.name;
let filter = e.target.getAttribute("filter");
let checked = e.target.checked;
if (checked) {
let newFilter = [...filters[filter]];
newFilter.push(name);
setFilters({ ...filters, [filter]: newFilter });
} else {
setFilters({
...filters,
[filter]: filters[filter].filter(item => item !== name)
});
}
};
return (
<div className="App">
{filterBy.map(item => (
<div className="container-fluid">
<hr />
<h5>filter with {item}</h5>
{filterGroups[item].map(li => (
<div key={li.ol_id} className="custom-control custom-checkbox">
<div className="form-group each_form_group">
<input
type="checkbox"
className="custom-control-input"
id={li.ol_id}
filter={item}
name={li[item]}
onChange={handleChange}
/>
<label className="custom-control-label" htmlFor={li.ol_id}>
{li[item]}
</label>
</div>
</div>
))}
</div>
))}
<div className="table-responsive">
<table className="table table-bordered">
<thead className="table-secondary">
<tr>
<th>Ol name</th>
<th>Ol Id</th>
<th>Ol Amount</th>
<th>Ol Date</th>
<th>Ol category</th>
</tr>
</thead>
<tbody>
{filterData().map(item => (
<tr>
<td>{item.ol_name}</td>
<td>{item.ol_id}</td>
<td>{item.ol_Amt}</td>
<td>{item.ol_Date}</td>
<td>{item.category}</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
);
Link to full dynamic version: https://codesandbox.io/s/strange-kepler-w8lgl?file=/src/App.js