So, I'm trying to create form with Formik and Material UI. For all the fields everything is working as it should but the problem is with Autocomplete. I cannot find the way to populate the field from the localStorage. I tried everything, from putting the value props, inputValue, defaultValue, etc but nothing seems to work.
import React from 'react'
import { Grid } from '@material-ui/core'
import { Autocomplete } from '@material-ui/lab'
import { Formik, Form, Field } from 'formik'
import { TextField } from 'formik-material-ui'
import * as yup from 'yup'
import { nationality } from '../../constants/nationality'
import Button from '../Button/Button'
export default function ForeignAddress () {
let localStorageData = localStorage.getItem('foreignAddress'),
retrivedData = JSON.parse(localStorageData)
const handleNextClick = () => {
console.log('clicked next')
}
const handleBackClick = () => {
console.log('clicked back')
}
const validationSchema = yup.object({
streetName: yup.string().required('Street name is required'),
streetNumber: yup.string().required('Street number is required'),
postalCode: yup.string().required('Postal code is required'),
city: yup.string().required('City is required'),
country: yup.string().required('Country is required'),
})
console.log(retrivedData)
return (
<React.Fragment>
<div className="pages-wrapper address">
<Formik
initialValues={retrivedData ? retrivedData : {streetName: '', streetNumber: '', postalCode: '', city: '', coAddress: '', country: ''}}
onSubmit={(data) => {
console.log(data)
localStorage.setItem('foreignAddress', JSON.stringify(data))
handleNextClick()
}}
validationSchema={validationSchema}
>
{({setFieldValue}) => (
<Form>
<Grid container spacing={3}>
<Grid item xs={12} md={8}>
<Field component={TextField} name="streetName" label="Street Name" variant="outlined" fullWidth />
</Grid>
<Grid item xs={12} md={4}>
<Field component={TextField} name="streetNumber" label="Street Number" variant="outlined" fullWidth />
</Grid>
<Grid item xs={12} md={4}>
<Field component={TextField} name="postalCode" label="Postal Code" variant="outlined" fullWidth />
</Grid>
<Grid item xs={12} md={8}>
<Field component={TextField} name="city" label="City" variant="outlined" fullWidth />
</Grid>
<Grid item xs={12} md={6}>
<Field component={TextField} name="coAddress" label="C/O Address" variant="outlined" fullWidth />
</Grid>
<Grid item xs={12} md={6}>
<Autocomplete
id="foreignCountry"
className="country-select"
name="country"
options={nationality}
getOptionLabel={option => option.label}
onChange={(e, value) => {
console.log(value)
setFieldValue("country", value.code)
}}
renderInput={params => (
<Field component={TextField} {...params} name="country" label="Country" variant="outlined" fullWidth/>
)}
/>
</Grid>
</Grid>
<div className="button-wrapper">
<Button label="Back" go="back" handleClick={handleBackClick}/>
<Button label="Next" go="next" type="submit" />
</div>
</Form>
)}
</Formik>
</div>
</React.Fragment>
)
}
EDIT:
Thanks to @Vencovsky i was able to get it done
in case someone in the future needs this here is the working code. Just change Autocomplete component to
<Autocomplete
id="foreignCountry"
className="country-select"
name="country"
options={nationality}
getOptionLabel={option => option.label}
defaultValue={values.country}
onChange={(e, value) => {
console.log(value)
setFieldValue("country", value)
}}
renderInput={params => (
<Field component={TextField} {...params} name="country" label="Country" variant="outlined" fullWidth/>
)}
/>
and in the Formik props just add values prop
{({setFieldValue, values}) => (
<Form>,...
There is a few thing you need to change.
First you can't just store the code to load it later, you need to store everything (the hole value
object) from the options.
Change the initial value of country: ''
to country: {code: "", label: "", phone: ""}
which is all the default value of the options.
Then to load the value correctly you should pass value={values.country}
where values
comes from formik props.
And on onChange
you should save the hole value onChange={(e, value) => {setFieldValue("country", value); }}
But you are also importing and using some wrong things like
<Field
component={TextField}
{...params}
name="country"
label="Country"
variant="outlined"
fullWidth
/>
Where Field
is form formik and TextField
from formik material ui.
Not sure why you use it like that, but I have changed it.
Here is a working example