9

I am trying to turn off autocomplete on an ant design Select but nothing I try works. This is obviously problematic as chromes (only one tested at this point) autocomplete completely covers the Select Options (Image below).

I am using antd in React and have tried the following on both the Select tag and Form tag:

autoComplete="off" autoComplete="nope" autoComplete="business-state"

and none of them seem to turn it off.

Here is a link to a code sandbox with almost the same code but the problem is it does not reproduce the same issue. For some reason the exact same code on sandbox doesn't show the autocomplete. I added an email input to show to test if autocomplete works on that and sure enough it does. I am at a loss for why this is working differently in sandbox than from my server.

https://codesandbox.io/s/wovnzpl9xw

Here is what it looks like when a user is typing to search the Options

enter image description here

Here is what it should look like (it only looks like this on focus but as soon as a user types chrome shows autocomplete)

enter image description here

Scientist1642
  • 1,172
  • 1
  • 11
  • 17
Craig Howell
  • 1,114
  • 2
  • 12
  • 28

7 Answers7

4

Figured out a solution to my question, thanks to @trkaplan for pointing me in the right direction. Not the most elegant solution I am guessing so if anyone else has a better way to implement this I am all ears. I essentially had to create an onFocus method for the Select that grabs all of the elements with class ant-select-search__field loops through them and utilize setAttribute to change the autocomplete attribute to an arbitrary value in order to disable it.

onFocus={() => {
  if (!this.state.autocompleteDisabled) {
    let i;
    const el = document.getElementsByClassName(
      "ant-select-search__field"
    );
    for (i = 0; i < el.length; i++) {
      el[i].setAttribute(
        "autocomplete",
        "registration-select"
      );
    }
    this.setState({ autocompleteDisabled: true });
  }
}}
Craig Howell
  • 1,114
  • 2
  • 12
  • 28
  • In my case I had to use classname - ant-select-selection-search-input In my example I am using an autocomplete for address, and when I filled in name in my form, it would automatically fill in from my google addresses, name, phone, address... I used the above code in a useEffect so that when I filled in my name, address did not fill in. `useEffect(() => { const el = document.getElementsByClassName("ant-select-selection-search-input"); for (let i = 0; i < el.length; i++) { el[i].setAttribute("autocomplete", "registration-select"); } }, []);` – L. Wolf Jan 09 '22 at 07:38
4

I have applied to add the autocomplete="none" into the Select and it is looking fine.

<Select
    showSearch
    optionFilterProp="children"
    onChange={onChange}
    onFocus={onFocus}
    onBlur={onBlur}
    onSearch={onSearchZipCode}
    filterOption={(input, option) => option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
    placeholder="Choose a City"
    autoComplete="none"
    // disabled={true}
>
    {cities.map((city) => (
        <Select.Option key={city.id} value={city.id}>
            {city.name}
        </Select.Option>
    ))}
</Select>;
Dan Homola
  • 3,819
  • 1
  • 28
  • 43
3

Another thing that worked very well for me was the following:

<FormItem>
  <Select
    autoComplete="new-state"
    {...otherProps}
  />
</FormItem>

The autoComplete prop currently isn't documented properly and they don't even cater for TS users properly.

But this worked, if you've got that new word in the autoComplete prop, Chrome (and hopefully other browsers) will ignore that field.

For TypeScript users that have justifiably strict type rules:

<Select
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  // @ts-ignore
  autoComplete="new-state"
  {...otherProps}
/>
Barry Michael Doyle
  • 9,333
  • 30
  • 83
  • 143
1

You could also use AutoComplete instead of Select, because with this it's possible to change the underlying Input

<AutoComplete ... >
  <Input autoComplete='off' id='myId' />
</AutoComplete>

AutoComplete is "new" and intended to be used if you are fetching data for the input instead of the data being static, but essentially its just a copy of Select and could be used the same way.

Ferdinand
  • 11
  • 1
  • The Antd does not highlight this in its documentation but this is the way to do it when using AutoComplete. – Kuldeep Jul 15 '21 at 06:01
0

You have to set filterOption to false

See this code sandbox

trkaplan
  • 3,217
  • 2
  • 23
  • 26
  • I may not have clarified this but I do want the user to be able to filter the options. With filterOption=false the user can not longer "jump" to the state they want and instead have to scroll through 50 options to get to the one they want. Also, code sandbox seems to correct the issue on its own as I put the exact same code in the sandbox and noting happens but I run it from my site and the autocomplete shows up again. – Craig Howell Oct 14 '18 at 21:29
  • Oh I missed the Browser's native autocomplete list. Can you provide a fiddle? Because this does not happen in the example I shared – trkaplan Oct 14 '18 at 21:47
  • added sandbox but can't reproduce the issue for some reason with the same code – Craig Howell Oct 14 '18 at 21:56
  • 1
    Antd uses a hidden input behind its Select element. Some CSS you haven't included in your sandbox may cause this. – trkaplan Oct 14 '18 at 22:07
  • CSS would have an effect on the browsers autoComplete? – Craig Howell Oct 14 '18 at 22:12
  • Not on the autoComplete attribute but, the visibility of the hidden input element which has an autoComplete attribute equals "on" – trkaplan Oct 14 '18 at 22:23
  • 1
    What css are you implying I should/should not have? Not sure I understand. – Craig Howell Oct 14 '18 at 22:42
0

The only "clean" way I found to have no autocomplete when the label of the input is supposed to be aucompleted according to chrome (see here: Which Attributes Does Chrome Autofill Expect?) is to modify the labels by inserting invisible character ‍ in the label

<Form.Item label={<>Cou&#8205;ntry</>}>

for example will be interpreted as

<Form.Item label={<>Cou‍ntry</>}>

But chrome does not recognize it as a Country input field

In my project I had dynamic inputs so the solution was (using _.times):

<Form.Item key={id} label={_.times(name.length, num => <>{tag.name.charAt(num)}&#8205;</>)}>  

Hacky but future proof (I hope)

manu
  • 1,059
  • 1
  • 16
  • 33
0

Going to the FormItem component you can set the name props to "stateEnum" and then your browser won't just assume the field name from the label.

It works nicely for me on Google Chrome.

Example:

<FormItem label="State" name="stateEnum">
   ...
</FormItem>
Barry Michael Doyle
  • 9,333
  • 30
  • 83
  • 143