【发布时间】:2020-04-01 03:47:00
【问题描述】:
我有一个 Material UI 自动完成功能,它可以呈现芯片列表。我在 PopperComponent 的底部添加了一个按钮,单击该按钮应打开一个对话框。
但自动完成功能不允许打开对话框。但奇怪的是,如果我在自动完成中添加“打开”,它就可以工作。
我尝试添加 onMouseDown 事件而不是 onClick。另外,尝试了 event.preventDefault()。它们都不起作用。但是 onMouseDown 确实为对话框调用了我的侦听器并将其打开状态更改为 true,但对话框没有出现。
这是沙盒的链接。 Sandbox to the code
这是实现对话框的组件。
import React, { useState } from "react";
import { withStyles } from "@material-ui/core/styles";
import Button from "@material-ui/core/Button";
import Dialog from "@material-ui/core/Dialog";
import MuiDialogTitle from "@material-ui/core/DialogTitle";
import MuiDialogContent from "@material-ui/core/DialogContent";
import MuiDialogActions from "@material-ui/core/DialogActions";
import IconButton from "@material-ui/core/IconButton";
import CloseIcon from "@material-ui/icons/Close";
import Typography from "@material-ui/core/Typography";
import { orange } from "@material-ui/core/colors";
const styles = theme => ({
form: {
display: "flex",
flexDirection: "column",
margin: "auto",
width: "fit-content"
},
formControl: {
marginTop: theme.spacing(2),
minWidth: 120
},
formControlLabel: {
marginTop: theme.spacing(1)
},
closeButton: {
position: "absolute",
right: theme.spacing(1),
top: theme.spacing(1),
color: theme.palette.grey[500]
},
selectEmpty: {
marginTop: theme.spacing(2)
},
floatingLabelFocusStyle: {
color: "green"
},
separator: {
marginTop: theme.spacing(1)
},
menuStyle: {
border: "1px solid black",
borderRadius: "5%",
backgroundColor: "lightgrey"
}
});
const DialogTitle = withStyles(styles)(props => {
const { children, classes, onClose, ...other } = props;
return (
<MuiDialogTitle disableTypography className={classes.root} {...other}>
<Typography variant="h6">{children}</Typography>
{onClose ? (
<IconButton
aria-label="close"
className={classes.closeButton}
onClick={onClose}
>
<CloseIcon />
</IconButton>
) : null}{" "}
</MuiDialogTitle>
);
});
const DialogContent = withStyles(theme => ({
root: {
padding: theme.spacing(2)
}
}))(MuiDialogContent);
const DialogActions = withStyles(theme => ({
root: {
margin: 0,
padding: theme.spacing(1)
}
}))(MuiDialogActions);
const ActionButton = withStyles(theme => ({
root: {
color: "#E87424",
backgroundColor: "white",
"&:hover": {
backgroundColor: orange[100]
}
}
}))(Button);
const ManageTagButton = withStyles(theme => ({
root: {
color: "#E87424"
}
}))(Button);
const TagContainer = props => {
const [open, setOpen] = useState(false);
const handleClickOpen = () => {
console.log("Dialog box clicked");
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
return (
<div>
<ManageTagButton
onMouseDown={event => {
event.preventDefault();
handleClickOpen();
}}
size="small"
>
MANAGE TAGS
</ManageTagButton>
<Dialog
fullWidth
maxWidth={"sm"}
onClose={handleClose}
aria-labelledby="customized-dialog-title"
open={open}
>
<DialogTitle id="customized-dialog-title">Manage Tags</DialogTitle>
<DialogContent dividers>
<h1>
This is the component of the dialog box. In reality I neeed to
display a data table with CRUD operations to add more tags.
</h1>
</DialogContent>
<DialogActions>
<ActionButton autoFocus onClick={handleClose} color="secondary">
CLOSE
</ActionButton>
</DialogActions>
</Dialog>
</div>
);
};
export default TagContainer;
这是实现自动完成的组件。
import React, { Fragment } from "react";
import Chip from "@material-ui/core/Chip";
import Autocomplete from "@material-ui/lab/Autocomplete";
import { withStyles } from "@material-ui/core/styles";
import { makeStyles } from "@material-ui/core/styles";
import TextField from "@material-ui/core/TextField";
import Button from "@material-ui/core/Button";
import List from "@material-ui/core/List";
import ListItem from "@material-ui/core/ListItem";
import ListItemText from "@material-ui/core/ListItemText";
import ListItemSecondaryAction from "@material-ui/core/ListItemSecondaryAction";
import Paper from "@material-ui/core/Paper";
import TagContainer from "./TagContainer";
const ListItemCustom = withStyles(theme => ({
gutters: {
paddingLeft: 0,
paddingRight: 0
},
secondaryAction: {
paddingRight: 0
}
}))(ListItem);
const AutocompleteCustom = withStyles(theme => ({
endAdornment: {
display: "none"
}
}))(Autocomplete);
const CreateButton = withStyles(theme => ({
root: {
color: "#E87424"
}
}))(Button);
const MuiFilledInputCustom = makeStyles(
{
underline: {
"&&&:before": {
borderBottom: "none"
},
"&&:after": {
borderBottom: "none"
}
}
},
{ name: "MuiFilledInput" }
);
const loadCustomStyles = () => {
MuiFilledInputCustom();
};
export default function AddTagToThread() {
loadCustomStyles();
const handleSubmit = () => {
console.log("Add tags to thread");
};
const useStyles = makeStyles({
root: {
minWidth: 300,
width: 300,
height: 250,
minHeight: 250,
zIndex: 1
},
buttons: {
display: "flex",
justifyContent: "flex-end"
}
});
const PaperComponentCustom = options => {
const classes = useStyles();
const { containerProps, children } = options;
return (
<Paper className={classes.root} {...containerProps} square>
{children}
<div className={classes.buttons}>
<TagContainer />
</div>
</Paper>
);
};
return (
<List dense={false}>
<ListItemCustom>
<ListItemText>
<AutocompleteCustom
multiple
id="size-small-filled-multi"
size="medium"
options={tagList}
noOptionsText="No options"
freeSolo
filterSelectedOptions
PaperComponent={PaperComponentCustom}
getOptionLabel={option => option.name}
onChange={(event, value) => {
console.log(value);
}}
renderTags={(value, getTagProps) =>
value.map((option, index) => (
<Chip
variant="default"
style={{
backgroundColor: option.color
}}
label={option.name}
size="medium"
{...getTagProps({ index })}
/>
))
}
renderOption={option => (
<Fragment>
<Chip
variant="default"
style={{
backgroundColor: option.color,
padding: "15px",
marginLeft: "12px"
}}
label={option.name}
size="medium"
/>
</Fragment>
)}
renderInput={params => (
<TextField
{...params}
variant="filled"
label="Filter By Tag"
placeholder="Select Tag"
/>
)}
/>
</ListItemText>
<ListItemSecondaryAction>
<CreateButton onClick={handleSubmit}>ADD TAG</CreateButton>
</ListItemSecondaryAction>
</ListItemCustom>
</List>
);
}
const tagList = [
{ name: "Follow Up", tagId: 1, color: "#FFC107" },
{ name: "Important", tagId: 2, color: "#46B978" },
{ name: "Idea", tagId: 3, color: "#EEA5F6" },
{ name: "Non Issue", tagId: 4, color: "#2EACE2" }
];
过去几天我一直被困在这个问题上。任何帮助是极大的赞赏。
【问题讨论】:
-
我认为这里的问题是 Paper 组件在单击后被卸载,因此实际上没有显示对话框。另外我没有得到以下部分
But the weird part is if I add 'open' to Autocomplete it works.你能详细说明一下吗 -
是的,我想你是对的,popper 在对话框打开之前就被卸载了。但是,如果我通过添加“打开”道具保持我的自动完成弹出器打开,那么它会起作用,因为它会导致纸质组件保持安装状态。
-
对话框打开时如何防止纸质组件被卸载?
-
你没有,你只保留按钮和自动完成之外的对话框组件。如果你愿意,我可以修改你的沙盒并向你展示如何
-
好的,请告诉我怎么做。谢谢
标签: reactjs autocomplete material-ui