'Disable autofill/autocomplete with angular form and chrome

I have a simple form where I need disable autofill/autocomplete with angular form.

I have search on StackOverflow, but I didn´t find a solution.

I have used autocomplete="off" or autocomplete="false" but the autocomplete is never disabled.

Sometimes the autocomplete is disabled temporarily when I load a page. But, after some time after, when I reload the page the problem appears again.

enter image description here

//markup from image above

<input type="text" class="form-control input-lg ng-pristine ng-empty ng-invalid ng-invalid-required ng-touched" capitalize-full="" ng-model="user.ENDERECO" required="" placeholder="Digite seu endereço" autocomplete="off" name="street" style="opacity: 1; text-transform: uppercase;">

//markup sample

<form class="form form-horizontal" name="regForm" 
              autocomplete="false" novalidate role="form">
 <input  type="text" class="form-control input-lg"                           
  name="cpf" ng-model="user.CPF" placeholder="Digite seu CPF" 
   required autocomplete="false" >
</form>


Solution 1:[1]

In April 2018: Setting autocomplete="off" on the form itself worked for me (tested on Chrome). Setting this attribute on individual elements did not work.

Solution 2:[2]

Simply put autocomplete="new-feildName" on html control

Example :

 <input class="signup-input-field-01" autocomplete="new-phone" 
            formControlName="phone" name="phone" type="text">

Solution 3:[3]

The autocomplete="off" is effectively respected by Chrome, but what you're experiencing is the Chrome autofill functionality that takes over, ignoring autocomplete="off": https://developers.google.com/web/updates/2015/06/checkout-faster-with-autofill.

In the past, many developers would add autocomplete="off" to their form fields to prevent the browser from performing any kind of autocomplete functionality. While Chrome will still respect this tag for autocomplete data, it will not respect it for autofill data.

I did some test and from what I see here Chrome igonores the autocomplete="off" when it can map the fieldname to one of it's autofill properties. This will work <input type="text" name="somethingAutofillDoesntKnow" autocomplete="off" />, but for this fieldName Autofill will show up <input type="text" name="firstName" autocomplete="off" />.

One workaround is to put an unknown value in the autocomplete, e.g. autocomplete="doNotAutoComplete". When testing this it worked for me most of the time, but for some reason didn't work anymore afterwards.

My advise is not to fight against it and use it's potential by properly using the autocomplete attribute as explained here: https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill

Solution 4:[4]

On Chrome, specifying autocomplete="off" didn't work for me. However, autocomplete="disabled" worked properly.

You can test and evaluate using this page: https://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_input_autocomplete (try changing the off to disabled using your browser).

Goodluck!

Solution 5:[5]

Try <input autocomplete="off" type="search"> it worked for me

Solution 6:[6]

Considering that chrome ignores the autocomplete="off" attribute value in case of credentials/address/credit card data type, as a workaround I have used this directive successfully solving my problem:

import { Directive, ElementRef, OnInit } from '@angular/core';

@Directive({
  selector: '[autocomplete]'
})
/**
 * Alterates autocomplete="off" atribute on chrome because it's ignoring it in case of credentials, address or credit card data type.
 */
export class AutocompleteDirective implements OnInit {
  private _chrome = navigator.userAgent.indexOf('Chrome') > -1;
  constructor(private _el: ElementRef) {}
  ngOnInit() {
    if (this._chrome) {
      if (this._el.nativeElement.getAttribute('autocomplete') === 'off') {
        setTimeout(() => {
          this._el.nativeElement.setAttribute('autocomplete', 'offoff');
        });
      }
    }
  }
}

Solution 7:[7]

In Angular, this directive worked for me. Using the autocomplete="off" should have solved the issue, but it seems as though the DOM rendering sequence prevents that unless you use a timeout.

Additionally, if you use something like mat-form-field and autocomplete is generated based on the unique names, you can add a Zero-width non-joiner anywhere after the first character and before the last character.

import { Directive, ElementRef, OnInit, Renderer2, AfterViewInit } from '@angular/core'

@Directive({
  selector: '[NoAutocomplete]',
})
export class NoAutocompleteDirective implements AfterViewInit {
  constructor(private renderer: Renderer2, private _el: ElementRef) {}
  ngAfterViewInit() {
    setTimeout(() => {
      const inputs = Array.prototype.slice.call(this._el.nativeElement.querySelectorAll('input'))
      inputs.map((e, i) => {
        this.renderer.setAttribute(e, 'autocomplete', 'off')
      })
      // If you're using mat-form-field
      const labels = Array.prototype.slice.call(
        this._el.nativeElement.querySelectorAll('.mat-form-field-label')
      )
      labels.map((l, i) => {
        l.innerHTML = l.innerHTML.replace(
          l.textContent,
          l.textContent.substring(0, 1) + '&zwnj;' + l.textContent.substring(1)
        )
      })
    }, 0)
  }
}

Solution 8:[8]

In my case, for email and password fields, autocomplete="off" [attribute] is not working accordingly. So, I have used autocomplete="new-email" and autocomplete="new-password" for email and password fields, which is disabling auto filling. On the other hand use of autocomplete="cc-name" for both email and password fields is also working fine.

E.g, 1:

<input type="email" autocomplete="new-email" formControlName="email" class="form-control" />
<input type="password" autocomplete="new-password" formControlName="password" class="form-control" />

E.g, 2:

<input type="email" autocomplete="cc-name" formControlName="email" class="form-control" />
<input type="password" autocomplete="cc-name" formControlName="password" class="form-control" />

Solution 9:[9]

I would assume the option is only needed on the input tag.

<input name="q" type="text" autocomplete="off"/>

Solution 10:[10]

autocomplete="off" alone might not do the job. Chrome tries to guess the type of input in absence of a name attribute, and messes up sometimes. The trick that worked for me is to add a name attribute.

<mat-form-field>
    <mat-label>Track</mat-label>
    <input name="track" matInput autocomplete="off" [(ngModel)]="track">
</mat-form-field>

Hope this helps someone ?

Solution 11:[11]

For me neither autocomplete="off" nor changing the name attribute worked alone.

But together (changing autocomplete to a random value - one that is not used by any other site and name attribute to something different) it worked.

I guess Chrome is trying to be too smart and guessing based on autocomplete value and name value.

Here is an example of my working solution:

<input matInput formControlName="email" autocomplete="noac" type="email" name="emailnoauto" placeholder="E-Mail" />

It's not nice, but it works.

Solution 12:[12]

autocomplete="off"/autocomplete="false"/autocomplete="disabled" didn't work for me.

However, setting autocomplete="new-fieldname" worked for me in individual fields. But it won't work with the form element.

Chrome version:81.0.4044.122

<input class="form-control" type="text" name="first_name" autocomplete="new-name" required>

Solution 13:[13]

Long story short, there is no one solution, only a workaround depending on the browser and what are you trying to do. (This answer is for Chrome and Edge)

First things first

  1. autocomplete is not a boolean field, instead, it is a field that can have many values, depending on the type of field, you can look here for more info https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete

  2. Chrome and Edge behave differently even though Edge is using Chromium

  3. I am using Angular, but you can solve it for any other framework, in my case I had to use ngAfterViewInit() and then a setTimeout() of 0.5 seconds

  4. My original issue was using the google address search service (originally I thought that was my only issue)

Solving the problem

  1. set the form with autocomplete=off, hopefully, one day this should be enough, but for some reason, Chrome thinks otherwise

  2. loop thru all the inputs and set autocomplete="off" (this should also be the solution in the distant future)

  3. Set address-form-google-search input to autocomplete="nope" (or anything else other than a real value)

  4. Set all addresses fields to "nope" you can look at the function setAddressFields()

  5. Although "nope" works for the address fields, in Edge, there are also custom fields you can save (look in settings Addresses), for this reason, I had to do a workaround, in my case, nothing worked, so I had to hack and use a valid autocomplete value (in this case I used additional-name), and I was lucky that Edge accepted that value and didn't have it saved in the settings as an option

  6. After the Address fields were fixed, then I had the issue that Chrome/Edge remembers what you typed in the field, even if it's not an address, so I had to rename the name with a random value

I hope I didn't beat around the bushes too much, but if you haven't had all these issues is because you have not tested enough. Please go to Chrome/Edge and open Settings and add Address fields there (make sure is enabled), also add credit card information, and you will see how all the previous answers are just partial solutions. So far everything is looking good, if QA finds another issue I will come back and edit this post.

Note: before using additional-name, I was going down the list and cc-number seems to be working fine, tested everywhere and it was the same solution for Edge and Chrome until I realized that cc-number is for Credit Cards, and sadly I have that in my application, so once I added a credit card, I was back to square 1. So additional-name is working for me so far, but who knows in the future :)

  ngAfterViewInit() {
    setTimeout(() => {
      // turn off any input field
      document.querySelectorAll('input').forEach((element) => {
        element.setAttribute('autocomplete', 'off');
      });
      document.querySelectorAll('textarea').forEach((element) => element.setAttribute('autocomplete', 'off'));

      // this code disable address fields
      document.querySelector('#address-form-google-search').setAttribute('autocomplete', 'nope');
      if (/Edg/.test(navigator.userAgent)) {
        this.setAddressFields('additional-name');
      } else {
        this.setAddressFields('nope');
      }

      // other fields may still save the information by looking at name, here we randomize the name
      const random = Math.random();
      document.querySelectorAll('input').forEach((element) => {
        if (element.id !== 'address-form-google-search') {
          element.setAttribute('name', element.name + '_' + random);
        }
      });

    }, 500);
  }

Solution 14:[14]

autocomplete="off" not working you just need to put something like this.

<input class="form-control" autocomplete="new-username" 
            formControlName="username" name="username" type="text">

instead of:

<input class="form-control" autocomplete="off" 
            formControlName="username" name="username" type="text">

Solution 15:[15]

I have the same problem, for me the problem was LastPass. Once disconnected everything works just fine. And two weeks of code rewriting to find the bug. Of course none that I find on internet fit the solution.

I had two tracks: with Firefox I didn't had the problem and the input field modification happens after few milliseconds the page reload.

So was a Chrome problem ? maybe. But disabling LastPass did the hat trick

Solution 16:[16]

I have been battling with this for years and the only solution that works for me is to override the FormGroup registerControl() function with the code below. It basically finds the input element and appends a guid to it.

@Component({
 selector: '[fsForm]',
 template: `<ng-content></ng-content>`,
 changeDetection: ChangeDetectionStrategy.OnPush,
})
export class FsFormComponent {

  public ngOnInit() {

    this._registerControl = this.ngForm.form.registerControl.bind(this.ngForm.form);

    this.ngForm.form.registerControl = (name: string, control: AbstractControl) => {

      const el: Element = this._element.nativeElement.querySelector(`input[name='${name}']`);

      if (el) {
        el.setAttribute('name', name + '_' + guid());

        if (!el.getAttribute('autocomplete')) {
          el.setAttribute('autocomplete', 'none');
        }
      }

      return this._registerControl(name, control);
    }
  }
}

Solution 17:[17]

I need to do that for my all 89 inputs so, I insert that in my html file and work for me. Chrome 89.0

<script>
    $("input").each((a,b) => $(b).attr("autocomplete", "new-field-" + 
 Math.random().toString(36).substring(2)))
</script>

Solution 18:[18]

All other solutions seems not to work for me.

new-somename works in google. But only the last field that start with new is respected. This directive can be used when multiple fields in a form shouldn't show autocomplete. see new-password in https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete

import { Directive, ElementRef, HostListener } from '@angular/core';

@Directive({ selector: 'input[autocompleteOff]' })
export class AutoCompleOffDirective {
  constructor(private el: ElementRef<HTMLInputElement>) {}
  @HostListener('focus') _ = () => (this.el.nativeElement.autocomplete = 'new-password');
  @HostListener('blur') _1 = () => (this.el.nativeElement.autocomplete = '');
}

Solution 19:[19]

setting name attribute fixed my problem in my angular material form. did that as explained out by Sanjay Verma, in his answer https://stackoverflow.com/a/66739412/6092524

<mat-form-field>
<mat-label>Track</mat-label>
<input name="track" matInput autocomplete="off" [(ngModel)]="track">

Solution 20:[20]

I had encountered the same problem where autocomplete="false" was not working,then I tried autocomplete="off" but in some of my client system autocomplete="off" had worked. but failed for few user ,I suggest you to put in your input code :

 <input autocomplete="nope">

This conditions is working fine for me