Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Autocomplete] Triggers change event twice with "enter" #18344

Closed
2 tasks
andiksetyawan opened this issue Nov 13, 2019 · 8 comments · Fixed by #18786
Closed
2 tasks

[Autocomplete] Triggers change event twice with "enter" #18344

andiksetyawan opened this issue Nov 13, 2019 · 8 comments · Fixed by #18786
Labels
bug 🐛 Something doesn't work component: autocomplete This is the name of the generic UI component, not the React module! good first issue Great for first contributions. Enable to learn the contribution process.

Comments

@andiksetyawan
Copy link

  • The issue is present in the latest release.
  • I have searched the issues of this repository and believe that this is not a duplicate.

Current Behavior 😯

I have used Autocomplete with FreeSolo prop, but I have a problem. when I have typed the word in the textfield / input and then I press Enter, the textfield becomes blank (deleted text). What I want, the word doesn't disappear when I press enter, how do I fix this?

<Autocomplete
     freeSolo
     id="combo-box-demo"
     options={top100Films}
     getOptionLabel={option => option.title}
     style={{ width: 300 }}
     renderInput={params => (
       <TextField {...params} label="Combo box" variant="outlined" fullWidth />
     )}
   />

https://codesandbox.io/s/material-demo-k1uyh

Expected Behavior 🤔

If I type text in the textfield and then I press Enter, the text should not be lost or not deleted

Your Environment 🌎

Tech Version
Material-UI v4.6.1
React 16.11.0
@material-ui/lab ^4.0.0-alpha.32
@andiksetyawan
Copy link
Author

i think this problem of getOptionLabel

<Autocomplete
     freeSolo
     id="combo-box-demo"
     options={top100Films}
     getOptionLabel={option => option.title}
     style={{ width: 300 }}
     renderInput={params => (
       <TextField {...params} label="Combo box" variant="outlined" fullWidth />
     )}
   />

if enter:

index.js:1 Material-UI: the `getOptionLabel` method of useAutocomplete do not handle the options correctly.
The component expect a string but received undefined.
For the input option: "11111111231", `getOptionLabel` returns: undefined. 
    in Autocomplete (created by WithStyles(ForwardRef(Autocomplete)))
    in WithStyles(ForwardRef(Autocomplete)) (at pages/​index.js:253)
    in Index (created by WithStyles(Index))
    in WithStyles(Index) (at _app.js:37)
    in MyApp

### But work and no error if use

<Autocomplete
     freeSolo
     id="combo-box-demo"
     options={top100Films.map(option => option.title)}
     style={{ width: 300 }}
     renderInput={params => (
       <TextField {...params} label="Combo box" variant="outlined" fullWidth />
     )}
   />

or

<Autocomplete
     freeSolo
     id="combo-box-demo"
     options={top100Films}
     getOptionLabel={option => option.title?option.title:option}
     style={{ width: 300 }}
     renderInput={params => (
       <TextField {...params} label="Combo box" variant="outlined" fullWidth />
     )}
   />

@Sai-Srikar

This comment has been minimized.

@oliviertassinari oliviertassinari added bug 🐛 Something doesn't work good first issue Great for first contributions. Enable to learn the contribution process. component: autocomplete This is the name of the generic UI component, not the React module! labels Nov 13, 2019
@oliviertassinari oliviertassinari changed the title AutoComplete freeSolo, Text Will Be Deleted if You Press Enter [AutoComplete] freeSolo, can trigger change event twice with "enter" Nov 13, 2019
@oliviertassinari
Copy link
Member

oliviertassinari commented Nov 13, 2019

@setyawanandik Thank you for the feedback. Your codesandbox is invalid, see the error it reports. When you set freeSolo to true, the user can pick a string value. Unless you adapt the value to match the exisiting options, you need to tell getOptionLabel how to handle the new shape:

    <Autocomplete
      freeSolo
      options={[{ title: 'foo' }]}
-     getOptionLabel={option => option.title}
+     getOptionLabel={option => typeof option === 'string' ? option : option.title}

However, there is an interesting wrong behavior I haven't anticipated that surface here. The Enter key shouldn't trigger a new onChange event if its already currently selected. This can be solved with:

diff --git a/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js b/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js
index ba7dcb7e4..2723e2648 100644
--- a/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js
+++ b/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js
@@ -531,7 +531,7 @@ export default function useAutocomplete(props) {
           // We don't want to validate the form.
           event.preventDefault();
           selectNewValue(event, filteredOptions[highlightedIndexRef.current]);
-        } else if (freeSolo && inputValue !== '') {
+        } else if (freeSolo && inputValueFilter !== '') {
           selectNewValue(event, inputValue);
         }
         break;

Do you want to work on this problem? We would need to add a test case as it's subtle.

@darrenfurr
Copy link

darrenfurr commented Nov 15, 2019

@oliviertassinari - I experienced the same issue, but am not using freeSolo. I used your getOptionLabel workaround getOptionLabel={option => typeof option === 'string' ? option : option.title} & that worked for me in MUI: 4.6.1 & lab: 4.0.0-alpha.32.

I used the combo box example straight off the site with my dataset which is just an array of { label: "bla", value: "bla" }

<Autocomplete
  id="combo-box-demo"
  options={top100Films}
  getOptionLabel={option => option.title}
  style={{ width: 300 }}
  renderInput={params => (
    <TextField {...params} label="Combo box" variant="outlined" fullWidth />
  )}
/>

@gmltA
Copy link
Contributor

gmltA commented Nov 18, 2019

I encounter the same issue with freeSolo configuration. Is this a really good decision to set typed in text directly as selected option on Enter? This makes option typing a bit confusing, as we have an adapter to convert arbitrary option value to displayable text, but nothing to perform counter-action. Maybe it makes sense to introduce a property which can hold a function to convert free-form user input to option type?

@tplai
Copy link
Contributor

tplai commented Nov 20, 2019

I can try and work on a test case for this @oliviertassinari if no one else has started on one.

@oliviertassinari
Copy link
Member

@tplai Awesome, you are free to go :)

@oliviertassinari
Copy link
Member

Maybe it makes sense to introduce a property which can hold a function to convert free-form user input to option type?

@gmltA This should already be possible by controlling the value prop.

@oliviertassinari oliviertassinari changed the title [AutoComplete] freeSolo, can trigger change event twice with "enter" [Autocomplete] freeSolo triggers change event twice with "enter" Nov 30, 2019
@oliviertassinari oliviertassinari changed the title [Autocomplete] freeSolo triggers change event twice with "enter" [Autocomplete] Triggers change event twice with "enter" Nov 30, 2019
tplai added a commit to tplai/material-ui that referenced this issue Dec 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐛 Something doesn't work component: autocomplete This is the name of the generic UI component, not the React module! good first issue Great for first contributions. Enable to learn the contribution process.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants