Using Material-UI's Autocomplete component with Formik
Your problem is that handleChange
won't work the way you are doing.
If you take a look at the handleChange docs:
General input change event handler. This will update the values[key] where key is the event-emitting input's name attribute. If the name attribute is not present, handleChange will look for an input's id attribute. Note: "input" here means all HTML inputs.
Which should work fine, but the problem is that the TextField
inside Autocomplete
will only trigger handleChange
when you type something on it, and the value will be the text, not the id
or other property you want, so you need to move handleChange
to the Autocomplete
.
And there is another problem, you can't use handleChange
in the Autocomplete
because it doesn't references the input you want and it also have different parameters from the normal onChange
of the input
, as you can see in the docs.
onChange
func
Callback fired when the value changes.
Signature:
function(event: object, value: any) => void
event
: The event source of the callback
value
: null
So what you need to do is use setFieldValue
and pass it to Autocomplete
like
onChange={(e, value) => setFieldValue("city_id", value)}
You need to pass the name of your field and what value you want to get.
Here is a working example
@vencovsky has provided the correct answer that is still working for me with Material UI 14.10.1.
I'm adding a bit more to it as I have my field set to required
in using Yup
validation.
To get this to work correctly I have the following:
Yup
config:
validationSchema = {
Yup.object().shape({
contact: Yup.string().max(255).required('Contact is required'),
})
}
react:
<Autocomplete
id="contact-autocomplete"
options={contacts}
getOptionLabel={(contact) => `${contact?.firstName} ${contact?.lastName}`}
onChange={(e, value) => setFieldValue("contact", value?.id || "")}
onOpen={handleBlur}
includeInputInList
renderInput={(params) => (
<TextField
{...params}
error={Boolean(touched.contact && errors.contact)}
fullWidth
helperText={touched.contact && errors.contact}
label="Contact Person"
name="contact"
variant="outlined"
/>
)}
/>
When the user click on the Autocomplete
element, it fires the onOpen
which runs the Formik
onBlur
and marks the field as touched. If an item is then not picked, Formik flags
the field and displays the Contact is required
validation message.