Reset AutoComplete in React Material UI - reactjs

I need to reset the state_id when I select the city_id Autocomplete.
How do I reset the state_id? It doesn't clear out.
Pls check codesandbox here
CLICK HERE
CODE
<Autocomplete
values={values.city_id}
options={cities ? cities : []}
getOptionSelected={(option, value) => option.id === value.id}
getOptionLabel={(option) => option.name}
onChange={(e, value) => {
setFieldValue("city_id", value ? value : "");
setFieldValue("state_id", "");
}}
renderInput={(params) => (
<TextField
name="city_id"
fullWidth
label="City"
variant="outlined"
onBlur={handleBlur}
helperText={touched.city_id && errors.city_id}
error={touched.city_id && Boolean(errors.city_id)}
{...params}
/>
)}
/>

Looks like a typo is the reason it's not working as expected. Instead of values={values.state_id} you should write value={values.state_id} as the prop for the Autocomplete.
BTW, for these kinds of things ("do something in fieldA if fieldB changed") we built a component based on https://github.com/formium/formik/issues/1633#issuecomment-520121543 in my project. This is close to the API of https://github.com/jaredpalmer/formik-effect, but still it may be worth implementing it yourself because jaredpalmer/formik-effect has not been committed to in the last 3 years.

Related

React - Mui - Autocomplete - asks for keys

console: Warning: Encountered two children with the same key
how can i add keys?
i tried
<Stack spacing={2} sx={{ width: 300 }}>
<Autocomplete
id="free-solo-demo"
freeSolo
options={cityObj.map((option) => option.name)}
renderInput={(params) => (
<TextField
{...params}
error={weatherData?.error ? true : false}
fullWidth
label="name your city here..."
value={search}
onChange={(e) => {
setSearch(e.target.value);
}}
ref={inputField}
onKeyDown={(e) => e.key === "Enter" && handleSubmit(e)}
/>
)}
/>
</Stack>
Autocomplete automatically maps your options and put the option value as key for each option.
So evidently you have some duplicate name values in in your cityObj array.
I don't know if there is a way to change the keys in order to suppress the warning, but even if there is, I recommend to not fiddling with it and fixing the problem in a correct manner by removing the duplicate value from your options array. Because why would we have two or more identical options in a autocomplete anyway?

Setting initial selected values for Autocomplete as a controlled component

What's happening is on page load, the: form.values.statistics?.ethnicity generates the Chips fine but doesn't set the selected values in the Autocomplete component.
Like in the image below, the Caucasian appears to be not selected when it should be selected from the Autocomplete component
What I've thought of and tried so far in which data.data.attributes.statistics.ethnicity === form.values.statistics.ethnicity:
Maybe I'm missing the "name" property from the Autocomplete component - tried adding so, but I can't. It says the property doesn't exist for the component. Which is weird?
value={ethnicityOptions[arrayOfSelectedIds]} or value={ethnicityOptions[data.data.attributes.statistics.ethnicity]}
Autocomplete code:
<Autocomplete
multiple
options={ethnicityOptions}
getOptionLabel={(ethnicityOptions) => ethnicityOptions.name}
id="multiple-tags"
value={form.values.statistics?.ethnicity}
onChange={(e, newValue) => {
form.setFieldValue('statistics.ethnicity', newValue);
form.handleChange(e);
}}
renderTags={() => null}
renderInput={(params) => (
<Grid className={classes.autoCompleteGrid}>
<TextField
{...params}
variant="outlined"
onChange={form.handleChange}
placeholder="Ethnicities"
/>
</Grid>
)}
/>
Code for generating Chips:
{form.values.statistics?.ethnicity
? form.values.statistics?.ethnicity?.map((v) => (
<Chip
key={v.name}
label={v.name}
onDelete={() => {
onEthnicityChipDelete(v);
}}
/>
))
: ''}
I'm currently stuck on this and I might be just missing something. Any help to breakthrough would be really appreciated!

Material UI 5.0 : When autocomplete value is empty every items are selected

Current Behavior 😯
When the Input is null the style is highlight as grey light (something like this)
Here is my current code
<Field
name="day"
render={({ input }) =>
<Autocomplete
options={this.days}
getOptionLabel={(option) => {
return option.toString()
}}
{...input}
onChange={(e, val) => {
input.onChange(val);
}}
isOptionEqualToValue={(option, value) => {
if (value === "" || value === option)
return true;
}}
renderInput={(params) => <TextField {...params} label="Day" variant="outlined" />}
/>
} />
Note : I use "Field" wrapper for react-final-form (cause mui-rff didn't upgrade yet to MUI 5.0)
Expected Behavior 🤔
On this picture, when I select a value, it match to my option's array and the style come back to normal.
Context 🔦
Chrome: 94.0.4606.71
Finally I found the solution.
I needed to move {...input} as first prop before options={this.days} by adding this option : value={null}.
Take care where you declare {...input}.

Material UI Autocomplete: Display part of selection

I'm displaying three property values (option.primary_line, option.city, option.state, and option.zip_code) from state in the autocomplete suggestions; however, I'm trying to display only the option.primary_line value in the textarea when an option from the list is selected. I've tried setting the option.primary_line value to state and adding it as a value (tried defaultValue as well) to the textarea to no avail. What am I missing?
<Autocomplete
id="combo-box-demo"
options={addressSuggestions}
getOptionLabel={(option) =>
`${option.primary_line}, ${option.city}, ${option.state} ${option.zip_code}`
}
onInputChange={handleAddressLookup}
freeSolo={true}
renderInput={(params) => (
<TextField
{...params}
variant="outlined"
fullWidth
/>
)}
/>
You should use renderOption instead, and in getOptionLabel return the value you want to be assigned to the input
<Autocomplete
...
renderOption={(option) =>
`${option.primary_line}, ${option.city}, ${option.state} ${option.zip_code}`
}
getOptionLabel={(option) => option.primary_line}
...
/>

React material UI autocomplete is not working with the formik

I have this code snippet, which is written by someone else.
<FormControl className={classes.formControl}>
<InputLabel id="combo-box-demo">
{values.type === "forAllCustomers" ? "" : ""}
</InputLabel>
<Autocomplete
id="combo-box-demo"
name="customerId"
onBlur={handleBlur}
onChange={handleChange}
value={values.customerId}
options={agents}
getOptionLabel={(option) => option.name}
disabled={values.type === "forAllCustomers"}
renderTags={(value, getTagProps) => {
filteredAgents(values.type).map(
(option, agentId) => (
<Chip
variant="outlined"
label={option.name}
// size="small"
{...getTagProps({ agentId })}
/>
)
);
}}
renderInput={(params) => (
<TextF
{...params}
variant="outlined"
label="Customer"
placeholder="Select"
name="agentId"
/>
)}
/>
</FormControl>
Here we load bunch of agents. If user pick one agent, that agents id should set as the customerId.
Here we use formik, so onBlur={handleBlur} onChange={handleChange} is controlled by the formik.
I tried by setting value to values.customerId But it seems not working and also I am getting an error in the console saying
index.js:1 Material-UI: The getOptionLabel method of Autocomplete
returned undefined instead of a string for "".
How do I fix this issue?
Anyhelp!
Thanks in advance. =)
See, the signature of the function onChange of AutoComplete is:
function(event: object, value: T | T[], reason: string) => void
However, signature of handleChange of Formik is
handleChange: (e: React.ChangeEvent<any>) => void
The problem is that simply passing onChange={handleChange} will not do what you think.
See, if you put, before the return statement a console.log(values), you'll see your initialValues object. However, a change in the Autocomplete will fill this object with strange combo-box-demo-option-0 1, 2 and so on. This is because how the Autocomplete component handles the combobox and the name and id properties. According to Formik, handleChange will look for the name or id to operate, and none have the correspondence you want.
Enough said, to fix your problem, you have to use another method provided by Formik: setFieldValue
Your Autocomplete should look something on the lines of:
<Autocomplete
id="combo-box-demo"
name="customerId"
onChange={(e, v) => {
setFieldValue("name", v?.name || "");
setFieldValue("customerId", v?.id || "");
}}
value={values}
options={agents}
getOptionLabel={(option) => option.name || ''}
style={{ width: 300 }}
renderInput={(params) => (
<TextField {...params} label="Combo box" variant="outlined" />
)}
/>;
You will not need the useState because you are not handling yourself any state changes. A regular javascript object will be enough.
Please check the agents you are getting. There might be an issue with your agents data coming from API RESPONSE or from anywhere else. According to Material-UI, the parameter you pass to options should be in an Array but your one might be an Object.
Please convert the Data type of agents to Array instead of Object if it is not in an Array and it will work!
<Autocomplete
id="combo-box-demo"
name="customerId"
onBlur={handleBlur}
onChange={handleChange}
value={values.customerId}
options={agents} //This should be in An Array
getOptionLabel={(option) => option.name} //Then access name
disabled={values.type === "forAllCustomers"}
/>
Please check the Official Docs of Material-UI https://material-ui.com/components/autocomplete/

Resources