Angular 2 and browser autofill
The problem in Chrome browser: it does not allow access to the value of the password field after autofill (before user click on the page). So, there are two ways:
- remove validation of the password field;
- disable password autocompletion.
I found out that you can use autocomplete="new-password"
As is decribed here
This way your password fields will not be autofilled at all, and that was my case.There are many others autocomplete attributes available in the link above.
I faced the same issue with Chrome v58.0.3029.96. Here is my workaround to keep validation and autocompletion:
export class SigninComponent extends UIComponentBase{ //-------------------------------------------------------------------------------------------- // CONSTRUCTOR //-------------------------------------------------------------------------------------------- constructor(viewModel: SigninViewModel) { super(viewModel); // Autofill password Chrome bug workaround if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) { this._autofillChrome = true; this.vm.FormGroup.valueChanges.subscribe( (data) => { if (this._autofillChrome && data.uname) { this._password = " "; this._autofillChrome = false; } }); } } //-------------------------------------------------------------------------------------------- // PROPERTIES //-------------------------------------------------------------------------------------------- private _password: string; private _autofillChrome: boolean; //-------------------------------------------------------------------------------------------- // COMMAND HANDLERS //-------------------------------------------------------------------------------------------- private onFocusInput() { this._autofillChrome = false; }}
And in my html:
<input mdInput [placeholder]="'USERNAME_LABEL' | translate" [formControl]="vm.FormGroup.controls['uname']" (focus)="onFocusInput()" />[...]<input mdInput type="password" [placeholder]="'PASSWORD_LABEL' | translate" [formControl]="vm.FormGroup.controls['password']" (focus)="onFocusInput()" [(ngModel)]="_password" />
I hope it helps.
Note: vm
is defined in UIComponentBase
and refers to the view-model SigninViewModel
of my component. The FormGroup
instance is defined in the view-model as the business logic is strictly separated from the view in my application.
UPDATE
Since v59, it seems that the input's focus event is fired when auto-completing fields. So the above workaround doesn't work anymore. Here is the updated workaround, using a timeout to determine if fields are updated by the auto-completion or by the user (I haven't found a better way):
export class SigninComponent extends UIComponentBase{ //-------------------------------------------------------------------------------------------- // CONSTRUCTOR //-------------------------------------------------------------------------------------------- constructor(viewModel: SigninViewModel) { super(viewModel); // Autofill password Chrome bug workaround if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) { this._autofillChrome = true; setTimeout( () => { this._autofillChrome = false; }, 250 // 1/4 sec ); this.vm.FormGroup.valueChanges.subscribe( (data) => { if (this._autofillChrome && data.uname) { this._password = " "; this._autofillChrome = false; } }); } } //-------------------------------------------------------------------------------------------- // PROPERTIES //-------------------------------------------------------------------------------------------- private _password: string; private _autofillChrome: boolean;}
And in my html:
<input mdInput [placeholder]="'USERNAME_LABEL' | translate" [formControl]="vm.FormGroup.controls['uname']" />[...]<input mdInput type="password" [placeholder]="'PASSWORD_LABEL' | translate" [formControl]="vm.FormGroup.controls['password']" [(ngModel)]="_password" />