I'm working on a registration form made with yup, react-hook-form and MUI DatePicker/TextField. I'd like to have a date of birth field that checks if the user is above 18 years old. The error message is displayed correcly but the red color of the error state works only if the input is empty (and not when the age is below 18). I'm console logging the value of "invalid" that dictates the red color, and it is set to true when it should.
Here is a sandbox link: https://codesandbox.io/s/datepicker-yup-validation-8rod3?file=/src/App.js
this solution was wrote with formik , yup and material datepicker :
import "./styles.css";
import LocalizationProvider from "@mui/lab/LocalizationProvider";
import AdapterDateFns from "@mui/lab/AdapterDateFns";
import DateTimePicker from "@mui/lab/DateTimePicker";
import * as Yup from "yup";
import { useFormik } from "formik";
import { Button, TextField } from "@mui/material";
import moment from "moment";
var y = new Date();
y.setFullYear(y.getFullYear() - 18);
const validationSchema = Yup.object().shape({
voyageNumber: Yup.number(),
voyageStartDate: Yup.date(),
voyageEndDate: Yup.date().when("voyageStartDate", (voyageStartDate, schema) =>
moment(voyageStartDate).isValid() ? schema.max(voyageStartDate) : schema
)
});
export default function App() {
const formik = useFormik({
initialValues: {
voyageStartDate: moment().add(-18, "years"),
voyageEndDate: null
},
validationSchema: validationSchema,
onSubmit: (values) => {
console.log(values);
}
});
return (
<div className="App">
<form autoComplete="off">
<LocalizationProvider dateAdapter={AdapterDateFns}>
<DateTimePicker
renderInput={(props) => (
<TextField
variant="standard"
className="w-100"
name="voyageEndDate"
required
{...props}
error={
formik.touched?.voyageEndDate &&
!!formik.errors?.voyageEndDate
}
helperText={
formik.touched?.voyageEndDate && formik.errors?.voyageEndDate
}
/>
)}
name="voyageEndDate"
label="Voyage End"
value={formik.values?.voyageEndDate}
onChange={(newValue) => {
console.log(
moment(newValue).format("YYYY-MM-DD HH:mm:ss"),
moment(y).format("YYYY-MM-DD HH:mm:ss"),
formik.errors
);
formik.setFieldTouched("voyageEndDate");
formik.setFieldValue(
"voyageEndDate",
moment(newValue).format("YYYY-MM-DD HH:mm:ss")
);
}}
onKeyPress={() => formik.setFieldTouched("voyageEndDate")}
/>
</LocalizationProvider>
<div style={{ marginTop: "15px" }}>
<Button variant="contained" color="primary" type="submit">
Add Voyage
</Button>
</div>
</form>
</div>
);
}
You need to just put error attribute after {...params} like this:
<DatePicker
...
renderInput={(params) => (
<TextField
helperText={invalid ? error.message : null}
id="dateOfBirth"
variant="standard"
margin="dense"
fullWidth
color="primary"
autoComplete="bday"
{...params}
error={invalid}
/>
)}
/>