I'm new to react and fiddling around with Material-UI. I'm trying to use DataPicker
and then access the form data with the new FormData()
- even though it seems to use TextField
, values for start
and end
are not present. I've used this SignUp form for the beginning.
How do I get them?
App.js
import * as React from 'react';
import Avatar from '@mui/material/Avatar';
import Button from '@mui/material/Button';
import CssBaseline from '@mui/material/CssBaseline';
import TextField from '@mui/material/TextField';
import Link from '@mui/material/Link';
import Grid from '@mui/material/Grid';
import Box from '@mui/material/Box';
import EventAvailableIcon from '@mui/icons-material/EventAvailable';
import Typography from '@mui/material/Typography';
import Container from '@mui/material/Container';
import { createTheme, ThemeProvider } from '@mui/material/styles';
import MyDataPicker from './MyDataPicker';
const theme = createTheme();
export default function SignUp() {
const handleSubmit = (event) => {
event.preventDefault();
const data = new FormData(event.currentTarget);
// eslint-disable-next-line no-console
console.log(data);
// Display the key/value pairs
for (var pair of data.entries()) {
console.log(pair[0] ': ' pair[1]);
}
};
return (
<ThemeProvider theme={theme}>
<Container component="main" maxWidth="xs">
<CssBaseline />
<Box
sx={{
marginTop: 8,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
}}
>
<Avatar sx={{ m: 1, bgcolor: 'primary.main' }}>
<EventAvailableIcon />
</Avatar>
<Typography component="h1" variant="h5">
Make Calendar link
</Typography>
<Box component="form" noValidate onSubmit={handleSubmit} sx={{ mt: 3 }}>
<Grid container spacing={2}>
<Grid item xs={12}>
<MyDataPicker
name="start"
label="Start date"
date={null}
/>
</Grid>
<Grid item xs={12}>
<MyDataPicker
name="end"
label="End date"
date={null}
/>
</Grid>
<Grid item xs={12}>
<TextField
required
fullWidth
name="timezone"
label="Timezone"
defaultValue="Europe/Prague"
helperText="See: https://www.php.net/manual/en/timezones.php"
/>
</Grid>
<Grid item xs={12}>
<TextField
required
fullWidth
name="title"
label="Title"
/>
</Grid>
<Grid item xs={12}>
<TextField
multiline
required
fullWidth
name="description"
label="Description"
rows={4}
/>
</Grid>
<Grid item xs={12}>
<TextField
fullWidth
name="location"
label="Location"
/>
</Grid>
</Grid>
<Button
type="submit"
fullWidth
variant="contained"
sx={{ mt: 3, mb: 2 }}
>
Generate links
</Button>
</Box>
</Box>
</Container>
</ThemeProvider>
);
}
MyDataPicker.js
import * as React from 'react';
import Stack from '@mui/material/Stack';
import TextField from '@mui/material/TextField';
import AdapterDateFns from '@mui/lab/AdapterDateFns';
import LocalizationProvider from '@mui/lab/LocalizationProvider';
//https://mui.com/api/date-time-picker/
import DateTimePicker from '@mui/lab/DateTimePicker';
export default function MaterialUIPickers(props) {
const [value, setValue] = React.useState(props.date);
console.log(props);
const handleChange = (newValue) => {
setValue(newValue);
console.log(props);
};
return (
<LocalizationProvider dateAdapter={AdapterDateFns}>
<Stack spacing={3}>
<DateTimePicker
label={props.label}
value={value}
onChange={handleChange}
renderInput={(props) => <TextField {...props} />}
clearable
cleartext="Clear"
/>
</Stack>
</LocalizationProvider>
);
}
CodePudding user response:
You have 2 params with the same name props
inside MaterialUIPickers
:
export default function MaterialUIPickers(props /* ---------------> props 1 */) {
return (
<LocalizationProvider dateAdapter={AdapterDateFns}>
<Stack spacing={3}>
<DateTimePicker
{...}
renderInput={(props /* ---------------> props 2 */) => {
return (
<TextField {...props} />
);
}}
clearable
cleartext="Clear"
/>
</Stack>
</LocalizationProvider>
);
}
Because props 1 is from the outer scope, it will be overridden by props 2, which prevents you from passing the name
attribute down to the input
element, that's why the form
can't find the field value. The fix is pretty simple, rename the param to a differentiate between the 2 props:
renderInput={(params) => {
return (
<TextField
{...params}
{...props} // put props after to let it overrides the name here
inputProps={{
...params.inputProps,
...props.inputProps
}}
InputProps={{
...params.InputProps,
...props.InputProps
}}
/>
);
}}