I am trying to prevent the web browser from auto-filling and auto-completing the fields of my forms in my Angular project, since it loads the styles I have added.
In my HTML I have tried to make the fields read-only and then when they get the focus with a JS event remove the read-only, but this only works for me to avoid the initial auto-fill , then the auto-complete help appears.
<section>
<form novalidate [formGroup]="formGroup" (ngSubmit)="onClickSignIn()">
<img src="assets/images/logo.png"/>
<md-input-container>
<input mdInput type="email" placeholder="Email" [formControl]="formGroup.controls['email']" #email appNoAutoComplete readonly>
</md-input-container>
<md-input-container>
<input mdInput type="password" placeholder="Contraseña" [formControl]="formGroup.controls['password']" #password>
</md-input-container>
<button md-button type="submit" [disabled]="formGroup.invalid">ENTRAR</button>
<div id="forgotten-password"><a (click)="onClickForgottenPassword()">¿Has olvidado la contraseña?</a></div>
</form>
</section>
Directive to prevent initial autofill .
import { Directive, ElementRef, HostListener } from '@angular/core';
@Directive({
selector: '[appNoAutoComplete]',
})
export class NoAutoCompleteDirective {
constructor(private el: ElementRef) {}
@HostListener('focus', ['$event'])
public onFocus() {
if (this.el.nativeElement.hasAttribute('readonly')) {
this.el.nativeElement.removeAttribute('readonly');
this.el.nativeElement.blur();
this.el.nativeElement.focus();
}
}
}
I have been reading several methods to solve my problem and I have not found any that work correctly, practically all of them say to do what is described in my directive and to put the autocomplete="off" attribute
I do the tests in Google Chrome.
update
Rendered HTML.
<app-signin _nghost-c0="" class=""><section _ngcontent-c0="">
<form _ngcontent-c0="" novalidate="" ng-reflect-form="[object Object]" class="ng-touched ng-dirty ng-valid">
<img _ngcontent-c0="" src="assets/images/logo.png">
<md-input-container _ngcontent-c0="" class="mat-input-container ng-tns-c1-0 ng-touched ng-dirty ng-valid"><div class="mat-input-wrapper"><div class="mat-input-flex"><!--bindings={
"ng-reflect-ng-if": "0"
}--><div class="mat-input-infix">
<input _ngcontent-c0="" appnoautocomplete="" class="mat-input-element ng-touched ng-dirty ng-valid" mdinput="" placeholder="Email" type="email" ng-reflect-form="[object Object]" ng-reflect-placeholder="Email" ng-reflect-type="email" id="md-input-1" aria-invalid="false">
<span class="mat-input-placeholder-wrapper"><!--bindings={
"ng-reflect-ng-if": "true"
}--><label class="mat-input-placeholder ng-tns-c1-0 mat-float" for="md-input-1">Email <!--bindings={
"ng-reflect-ng-if": "false"
}--></label></span></div><!--bindings={
"ng-reflect-ng-if": "0"
}--></div><div class="mat-input-underline"><span class="mat-input-ripple"></span></div><div class="mat-input-subscript-wrapper" ng-reflect-ng-switch="hint"><!--bindings={
"ng-reflect-ng-switch-case": "error"
}--><!--bindings={
"ng-reflect-ng-switch-case": "hint"
}--><div class="mat-input-hint-wrapper ng-tns-c1-0 ng-trigger ng-trigger-transitionMessages" style="opacity: 1; transform: translateY(0%);"><!--bindings={
"ng-reflect-ng-if": ""
}--><div class="mat-input-hint-spacer"></div></div></div></div></md-input-container>
<md-input-container _ngcontent-c0="" class="mat-input-container ng-tns-c1-1 ng-dirty ng-valid ng-touched"><div class="mat-input-wrapper"><div class="mat-input-flex"><!--bindings={
"ng-reflect-ng-if": "0"
}--><div class="mat-input-infix">
<input _ngcontent-c0="" class="mat-input-element ng-dirty ng-valid ng-touched" mdinput="" placeholder="Contraseña" type="password" ng-reflect-form="[object Object]" ng-reflect-placeholder="Contraseña" ng-reflect-type="password" id="md-input-3" aria-invalid="false">
<span class="mat-input-placeholder-wrapper"><!--bindings={
"ng-reflect-ng-if": "true"
}--><label class="mat-input-placeholder ng-tns-c1-1 mat-float" for="md-input-3">Contraseña <!--bindings={
"ng-reflect-ng-if": "false"
}--></label></span></div><!--bindings={
"ng-reflect-ng-if": "0"
}--></div><div class="mat-input-underline"><span class="mat-input-ripple"></span></div><div class="mat-input-subscript-wrapper" ng-reflect-ng-switch="hint"><!--bindings={
"ng-reflect-ng-switch-case": "error"
}--><!--bindings={
"ng-reflect-ng-switch-case": "hint"
}--><div class="mat-input-hint-wrapper ng-tns-c1-1 ng-trigger ng-trigger-transitionMessages" style="opacity: 1; transform: translateY(0%);"><!--bindings={
"ng-reflect-ng-if": ""
}--><div class="mat-input-hint-spacer"></div></div></div></div></md-input-container>
<button _ngcontent-c0="" class="mat-button" md-button="" type="submit" ng-reflect-disabled="false"><span class="mat-button-wrapper">ENTRAR</span><div class="mat-button-ripple mat-ripple" md-ripple="" ng-reflect-trigger="[object HTMLButtonElement]" ng-reflect-centered="false" ng-reflect-disabled="false"></div><div class="mat-button-focus-overlay"></div></button>
<div _ngcontent-c0="" id="forgotten-password"><a _ngcontent-c0="">¿Has olvidado la contraseña?</a></div>
</form>
</section></app-signin>
One line summary :
autocomplete="new-password"
You are using a field of type
password
. Regardless of whether you have the propertyautocomplete="off"
, browsers will ask the user if they want to save the password. And in the case that the user accepts, the browser will try to autocomplete it.This functionality was developed starting with Firefox 38 , Chrome 34 and IE 11 as a security measure.
Since it is considered that thanks to that, users can now put a ridiculously complicated password (or not) and never remember it, hoping that the browser will autocomplete their passwords.
Anyway, it was thought that to disable this behavior (the autofill even after saving the password ), the property could be used
autocomplete="new-password"
.However,
autocomplete="new-password"
it is not generally implemented. But anyway, if the browser doesn't understand the assigned value, it's not going to try too hard. Therefore;autocomplete="cualquier-cosa"
should also work for you.It may not be what you expect but the only way I was able to achieve it was by emulating the input with a
div
and the propertycontenteditable
.Now angular doesn't recognize divs as elements like it does with a
<input type="text" />
by updating thengModel
with each typed letter, so I had to create a directive so that it would update the model whenever the user types in the div.I apologize that the example is in angularjs 1.* since I don't know angular2 but you will have the idea of how to do it:
In essence, what it does is that for every keyup on the div, it updates the model assigned to the div.
Now the
form
doesn't recognize the attributename
on a div to send it to the server. For that you just have to create an input[hidden] and assign the value of the model to it like this in the example. I will leave this just as an example in case it is necessary.Browsers have not yet agreed on what to use and you can see the problems that this causes us. In my case, the autocomplete="off" attribute worked for me by putting it in the form in chrome v60.0.3112.90 and Edge v40.15063.0.0, but maybe not everyone has an updated browser and not everyone uses chrome or edge.
It's not the most elegant solution but it works perfectly. So no negative points.
What you are trying to do, disable autocomplete, goes against the premises promoted by companies like Google in which said prerogative corresponds to the user.
If you persist in the intention, the first thing is to try what the Mozilla Developer Network recommends
autocomplete="off"
orautocomplete="nope"
The above can fail in browsers like Chrome because, as previously mentioned for Google, the prerogative of autocompletion is the user's, not the developer's. In this case, remember that the autocomplete relies on hints to be able to match the data stored in the browser with the form data like
label
the fields labelname
andid
If possible, use unique labels and names.
Instead of password or password try with "password". Instead of Email try with identifier
Another thing to try is to duplicate the fields by putting the first ones hidden since usually only the first occurrence is autocompleted.
On the other hand, in addition to the form auto-completion function, modern browsers have an independent function of saving usernames and passwords, which makes it even more difficult for the developer to prevent these data from being filled in automatically.
About the code in stacksnippet
The OP mentions that
autocomplete="off"
it does not work but it is not included in the code, but instead the attribute is includedappnoautocomplete=""
.References
Well, it seems that
autocomplete
it was used a lot in the past in versions like IE11, Chrome 34 and Firefox 30 , so it is not feasible to use it at all. However, I found a somewhat old post where you try to solve a similar question, there are several paths to take and maybe one will work for you. how-to-disable-autocomplete-in-formsNOTE: using the
autocomplete="off"
ininput
will not work if the form is also onHTML autocomplete attribute
After researching the subject without finding a definitive solution to the problem, which is simple and at the same time respects the standard already created, I have decided to program a solution and share it since at some point any developer is going to run into this problem because at some point At this point you will have to create a LOGIN form .
This solution tries to maintain the standard already created and through
javascript
making the WEB browsersautocomplete
respect it, it is the HTML AttributeAlthough the standard is very complete in this regard, the example that I leave here only supports the value
autocomplete="off"
at the level of the tag<form>
e<input>
.You can also place a
checkbox
withid="autocomplete"
to force theautocomplete="on"
global scope for all pages where you use this code, (the lines that control this feature are commented out in the code since S O does not allow them).Without further ado, here is the working example of the code:
One way to solve this problem would be to detect the change in this input, and execute a function where the field is given an empty value the first time it is executed. example:
autocomplete
You have used the input control attribute , https://www.w3schools.com/tags/att_input_autocomplete.aspI leave the example of the link