I am using Material UI multiple select and my goal is to set all checkboxes checked, including the All
, if nothing is checked after closing the dropdown.
So if nothing is selected and dropdown is closed, I want to have all checkboxes checked.
I have created a boolean
state called open
which triggers if the dropdown closes.
I have isAllSelected
boolean which also turns to true if all are selected. So this is the way I'm trying to implement via the booleans, but something doesn't work.
Demo sandbox link and Code example below
import React, { useState } from "react";
import InputLabel from "@mui/material/InputLabel";
import Checkbox from "@mui/material/Checkbox";
import ListItemIcon from "@mui/material/ListItemIcon";
import ListItemText from "@mui/material/ListItemText";
import MenuItem from "@mui/material/MenuItem";
import FormControl from "@mui/material/FormControl";
import Select from "@mui/material/Select";
import { MenuProps, useStyles, options } from "./utils";
function App() {
const [open, setOpen] = React.useState(false);
const handleOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
const classes = useStyles();
const [selected, setSelected] = useState(options);
const isAllSelected =
options.length > 0 && selected.length === options.length;
const handleChange = (event) => {
const value = event.target.value;
if (value[value.length - 1] === "all" && open) {
setSelected(selected.length === options.length ? [] : options);
return;
}
setSelected(value);
};
console.log("open", open);
console.log("isAllSelected", isAllSelected);
return (
<FormControl className={classes.formControl}>
<InputLabel id="mutiple-select-label">Multiple Select</InputLabel>
<Select
open={open}
onOpen={handleOpen}
onClose={handleClose}
labelId="mutiple-select-label"
multiple
value={selected}
onChange={handleChange}
renderValue={(selected) =>
!isAllSelected ? selected.join(", ") : "alle"
}
MenuProps={MenuProps}
>
<MenuItem
value="all"
classes={{
root: isAllSelected ? classes.selectedAll : ""
}}
>
<ListItemIcon>
<Checkbox
//defaultChecked={!isAllSelected}
classes={{ indeterminate: classes.indeterminateColor }}
checked={!isAllSelected && !open}
indeterminate={
selected.length > 0 && selected.length < options.length
}
/>
</ListItemIcon>
<ListItemText
classes={{ primary: classes.selectAllText }}
primary="Select All"
/>
</MenuItem>
{options.map((option) => (
<MenuItem key={option} value={option}>
<ListItemIcon>
<Checkbox
//defaultChecked
checked={
!isAllSelected && !open ? true : selected.indexOf(option) > -1
}
/>
</ListItemIcon>
<ListItemText primary={option} />
</MenuItem>
))}
</Select>
</FormControl>
);
}
export default App;
CodePudding user response:
You need to update the state for the checkbox once you change it and For default settings You can use defaultChecked
CodePudding user response:
I solved the problem, updating the setter value via useEffect.
I am checking if the dropdown is closed and nothing is checked/selected, then wrap all elements in the selected
array.
Code and demo sandbox link
React.useEffect(() => {
if (selected.length < 1 && !open) {
setSelected(options);
}
}, [open, isAllSelected, selected]);