I'm not able to do multi cross filtering, when I click on Apply
(to apply all my selected options from my dropdowns) or Cancel
button (to reset the selected options). For example filter by taste
and availability
(please see the picture). But I'm not able to render the filtered rows/updated table.
export default function MenuDisplay() {
const { menuId } = useParams();
const { match } = JsonData;
const [selected, setSelected] = useState({});
const [hidden, setHidden] = useState({});
const [taste, setTaste] = useState([
{ label: "Good", value: "Good", name: "Good", selected: false },
{ label: "Medium", value: "Medium", name: "Medium", selected: false },
{ label: "Bad", value: "Bad", name: "Bad", selected: false }
]);
const [comments, setComments] = useState([
{ label: "0", value: "0", name: "0", selected: false },
{ label: "1", value: "1", name: "1", selected: false },
{ label: "2", value: "2", name: "2", selected: false },
{ label: "3", value: "3", name: "3", selected: false },
{ label: "4", value: "4", name: "4", selected: false },
{ label: "5", value: "5", name: "5", selected: false }
]);
const [availability, setAvailability] = useState([
{
label: "availability",
value: "availability",
name: "Availability",
selected: false
},
{ label: "trust", value: "trust", name: "Trust", selected: false }
]);
function selectionOpt(setItems) {
return (selection) => {
setItems(selection);
};
}
const impact = (value) => {
if (value === 1) {
return (
<div>
<TaskAltIcon />
</div>
);
} else {
return (
<div>
<CancelIcon />
</div>
);
}
};
// If any row is selected, the button should be in the Apply state
// else it should be in the Cancel state
const buttonMode = Object.values(selected).some((isSelected) => isSelected)
? "apply"
: "cancel";
const rowSelectHandler = (id) => (checked) => {
setSelected((selected) => ({
...selected,
[id]: checked
}));
};
const handleClick = () => {
if (buttonMode === "apply") {
// Hide currently selected items
const currentlySelected = {};
Object.entries(selected).forEach(([id, isSelected]) => {
if (isSelected) {
currentlySelected[id] = isSelected;
}
});
setHidden({ ...hidden, ...currentlySelected });
// Clear all selection
const newSelected = {};
Object.keys(selected).forEach((id) => {
newSelected[id] = false;
});
setSelected(newSelected);
} else {
// Select all currently hidden items
const currentlyHidden = {};
Object.entries(hidden).forEach(([id, isHidden]) => {
if (isHidden) {
currentlyHidden[id] = isHidden;
}
});
setSelected({ ...selected, ...currentlyHidden });
// Clear all hidden items
const newHidden = {};
Object.keys(hidden).forEach((id) => {
newHidden[id] = false;
});
setHidden(newHidden);
}
};
const matchData = (
match.find((el) => el._id_menu === menuId)?._ids ?? []
).filter(({ _id }) => {
return !hidden[_id];
});
const getRowProps = (row) => {
return {
style: {
backgroundColor: selected[row.values.id] ? "lightgrey" : "white"
}
};
};
const data = [
{
Header: "id",
accessor: (row) => row._id
},
{
Header: "Name",
accessor: (row) => (
<Link to={{ pathname: `/menu/${menuId}/${row._id}` }}>{row.name}</Link>
)
},
{
Header: "Taste",
accessor: (row) => row.taste
},
{
Header: "Comments",
//check current row is in hidden rows or not
accessor: (row) => {
const comments = parseInt(row.comments, 10);
return <Counter count={comments} />;
}
},
{
Header: "Price",
accessor: (row) => row.price,
id: "price"
},
{
Header: "Status",
accessor: (row) => row.status
},
{
Header: "Availability",
accessor: (row) => row.availability,
id: "availability",
Cell: (props) => impact(props.value)
},
{
Header: "Trust",
accessor: (row) => row.trust,
id: "trust",
Cell: (props) => impact(props.value)
},
{
Header: "Show",
accessor: (row) => (
<Toggle
value={selected[row._id]}
onChange={rowSelectHandler(row._id)}
/>
)
}
];
const initialState = {
sortBy: [
{ desc: false, id: "id" },
{ desc: false, id: "description" }
],
hiddenColumns: ["dishes", "id"]
};
return (
<div>
<button type="button" onClick={handleClick}>
{buttonMode === "cancel" ? "Cancel" : "Apply"}
</button>
<div className="flex justify-end gap-4 ">
<div>
<Button>Apply</Button>
</div>
<div>
<Button>Cancel</Button>
</div>
</div>
Taste
<ListDrop
placeholder={"Select"}
items={taste}
onSelect={selectionOpt(setTaste)}
hasAll
/>
Comments
<ListDrop
placeholder={"Select"}
items={comments}
onSelect={selectionOpt(setComments)}
hasAll
/>
<p>Availability & Trust </p>
{/* I would like to have in my dropdown Availability and Trust as
options in my dropdown and it refers to the cross where availaibility: 1 and trust:1 ) */}
<ListDrop
placeholder={"Select"}
items={availability}
onSelect={selectionOpt(setAvailability)}
hasAll
/>
<Table
data={matchData}
columns={data}
initialState={initialState}
withCellBorder
withRowBorder
withSorting
withPagination
rowProps={getRowProps}
/>
</div>
);
}
Please check my codeSandbox
Please check the picture to get an idea :