В этой функции я просто загружаю файл с некоторым полем описания (содержащим текст) с компонентом Диалог Material-UI и захватывает файл и связанную строку описания с FormData () с приведенной ниже функцией handleUpload, которая будет активирована при нажатии кнопки onClick.
handleUpload = event => {
event.preventDefault();
const data = new FormData();
data.append(
"file",
this.state.selectedFile,
this.state.document_name,
this.state.description
);
if (data.get("description") !== "" && data.get("document_name") !== "") {
this.props
.createGo(data, history)
.then(() => {
console.log("FORM DATA INSIDE", data);
console.log("FILE IS ", this.state.selectedFile);
this.setState({
open: true,
vertical: "top",
horizontal: "center"
});
})
.catch(error => {
if (error.response.status === 422) {
alert(
"File must be less than 10 MB and type must be one of pdf, jpeg, jpg, png, doc, xlx, xlsx, ppt pptx"
);
} else if (error.response.status === 401) {
history.push("/login");
alert("Please Login, session expired");
}
});
} else {
showEmptyFieldSnackbar();
return false;
}
};
Когда я НЕ пользуюсь диалогом Material-UI, он работает как положено. Рабочий код здесь
Но когда я использую Material-UI для отправки диалога для загрузки файла, он не работает, потому что FormData () остается пустым. Обратите внимание, что строка console.log("FORM DATA INSIDE", data);
дает мне пустую форму FormData. То есть следующий код
const data = new FormData();
data.append(
"file",
this.state.selectedFile,
this.state.document_name,
this.state.description
);
НЕ добавляет ничего.
А вот мой полный компонент, использующий Material-UI для отправки диалога
class GoCreateForm extends Component {
constructor(props) {
super(props);
this.state = {
document_name: "",
description: "",
selectedFile: null,
open: false,
vertical: "top",
horizontal: "center",
dialogOpen: false
};
}
// and below handleClose function as well is for closing snackbar
handleClose = () => {
this.setState({ open: false });
history.push("/dashboard/gos");
};
handleSelectedFile = e => {
e.preventDefault();
this.setState({
selectedFile: e.target.files[0]
});
};
handleUpload = event => {
event.preventDefault();
const data = new FormData();
data.append(
"file",
this.state.selectedFile,
this.state.document_name,
this.state.description
);
if (data.get("description") !== "" && data.get("document_name") !== "") {
this.props
.createGo(data, history)
.then(() => {
console.log("FORM DATA INSIDE", data);
console.log("FILE IS ", this.state.selectedFile);
this.setState({
open: true,
vertical: "top",
horizontal: "center"
});
})
.catch(error => {
if (error.response.status === 422) {
alert(
"File must be less than 10 MB and type must be one of pdf, jpeg, jpg, png, doc, xlx, xlsx, ppt pptx"
);
} else if (error.response.status === 401) {
history.push("/login");
alert("Please Login, session expired");
}
});
} else {
showEmptyFieldSnackbar();
return false;
}
};
handleCancel = () => {
this.setState({
dialogOpen: false
});
};
handleEnterEscapeKeyPress = e => {
if (e.key === "Enter") {
this.onSubmit();
} else if (e.key === "Escape") {
this.handleCancel();
}
};
handleToggle = () => {
this.setState({
dialogOpen: !this.state.dialogOpen
});
};
handleFabOpen = () => {
this.setState({
dialogOpen: true
});
};
render() {
const {
vertical,
horizontal,
open,
document_name,
description,
selectedFile
} = this.state;
const { classes } = this.props;
return (
<MuiThemeProvider>
<FormControl>
<div>
<Fab
onClick={this.handleFabOpen}
aria-pressed="true"
color="secondary"
size="large"
aria-label="Add"
fontSize="large"
className={classes.fabButton}
>
<AddIcon />
</Fab>
<Dialog
open={this.state.dialogOpen}
onClose={this.handleToggle}
aria-labelledby="form-dialog-title"
fullWidth={true}
maxWidth={"sm"}
variant="contained"
PaperProps={{
classes: {
root: classes.paper
}
}}
onKeyDown={this.handleEnterEscapeKeyPress}
>
<form onSubmit={this.handleUpload}>
<DialogTitle
id="form-dialog-title"
disableTypography
className={classes.dialogTitleAdd}
>
<div className={classes.displayFlexDialogTitle}>
<Typography
variant="h5"
className={classes.dialogTitleHeading}
>
Upload a new Government Order
</Typography>
<IconButton
onClick={this.handleToggle}
className={classes.button}
style={{ float: "right" }}
>
<CancelIcon />
</IconButton>
</div>
</DialogTitle>
<DialogContent required>
<div style={{ display: "flex", margin: "auto" }}>
<TextField
required
autoFocus
error={document_name === ""}
fullWidth
classes={{
root: classes.space
}}
type="string"
onChange={e => {
this.setState({
document_name: e.target.value
});
}}
value={document_name}
helperText={
document_name === ""
? "Please enter Document Name"
: " "
}
label="Document Name"
/>
</div>
<div style={{ display: "flex", margin: "auto" }}>
<TextField
required
autoFocus
multiline={true}
error={description === ""}
fullWidth
classes={{
root: classes.space
}}
type="string"
onChange={e => {
this.setState({
description: e.target.value
});
}}
value={description}
helperText={
description === ""
? "Please enter Document Description"
: " "
}
label="Document Description"
/>
</div>
{selectedFile === null ? null : (
<div style={{ marginBottom: "10px" }}>
{selectedFile.name}
</div>
)}
<div
style={{ display: "flex", margin: "auto" }}
className="form-group"
>
<Button variant="contained" component="label">
Upload File
<input
type="file"
style={{ display: "none" }}
onChange={this.handleSelectedFile}
/>
</Button>
</div>
</DialogContent>
<DialogActions className={classes.dialogActions}>
<div className={classes.displayFlexDialogActions}>
<Button
onClick={this.handleCancel}
variant="contained"
size="small"
color="secondary"
className="float-right"
style={{ marginRight: "10px" }}
>
<Link
style={{ textDecoration: "none", color: "inherit" }}
to="/dashboard/gos"
>
Cancel
</Link>
</Button>
<button type="submit" className="btn btn-primary">
Upload
</button>
</div>
</DialogActions>
</form>
</Dialog>
</div>
</FormControl>
</MuiThemeProvider>
);
}
}
GoCreateForm.propTypes = {
classes: PropTypes.object.isRequired
};
export default connect(
null,
{ createGo }
)(withStyles(styles)(GoCreateForm));