35
votes

I have a Login Form which has email and password fields.

I've chosen for browser autofill.

The problems is: When browser autofills login form, both fields are pristine and untouched, so the submit button is disabled.

If I click on disabled button, it enables and fires submit action, what is nice. But the default disabled aspect is pretty bad what can make some users disappointed.

Do you have some ideas about how to deal with?

8
were you able to solve the issue? - JohnDizzle
@JohnDizzle: Did you guys able to get it work? if yes then how? :) - Denish
@Denish No, I must disappoint you. This seems to be an open problem for everyone in the community... - JohnDizzle
@Denish, If you have a reactive form, then something like [disabled]="user.invalid" should work - Vega
It might be related to this issue here: The autofill values only become available after user interacts with the form: github.com/angular/material2/issues/3414 - Kristjan Liiva

8 Answers

5
votes

I solved it by also checking if the form was touched when displaying error messages. So, for example, the submit button looks like this

<input type="submit" class="btn btn-default" [disabled]="loginFormGroup.invalid && loginFormGroup.touched" />
2
votes

I solved this problem with the ChangeDetectorRef Provider.
Simply do a manual detectChanges() before you check if the input is valid.

If you aren't able to check after a button click, then hear on the Input-Event of the Input-Element with the event-binding (input)=changedetectorfunc() and call the changeDetector in this function.
Therefore it must work.
Hope, it helps you.

useful links:

Best wishes

1
votes

I seem to have solved this by just simulating a click on the page AfterViewInit.

public ngAfterViewInit(): void {
    $('body').click();
}

Chrome 67.0.3396.99, Angular 5.1.0

0
votes

I had the same problem.

I solved it by: - removing the Validators.required validator for the password field in the component - using the <input ... required ...> directive at the tag in the template

0
votes

There are two ways to solve this problem

  • Use CSS pseudo class -webkit-autofill it will detect the autofill.

https://developer.mozilla.org/en-US/docs/Web/CSS/:aut

  • Use AutofillMonitor package from angular/cdk module which monkey patch the Validators Since RequiredValidator is not able to acknowledge autofill input.

https://gist.github.com/kherock/fad4c320c5894ec68373588e338955c5

-1
votes

this is not the best practice for code but it will work for sure-

if you are having two way binding then its very easy task just check for length of both textbox if it is greater then zero then return false else return true and call the method in disabled attribute. Method-

    validcheck() {
         return username.length <= 0 || password.length <= 0;     
    }

and call the method inside button disabled attribute

    <button [disabled]="validcheck()">Submit</button>
-2
votes

Had the same problem too. I'm not sure if this is the best way, but I was able to get it to work by adding AfterViewChecked

import { Component, AfterViewChecked } from "@angular/core";

export class LoginComponent implements AfterViewChecked {
    // Beware! Called frequently!
    // Called in every change detection cycle anywhere on the page
    ngAfterViewChecked() {
        console.log(`AfterViewChecked`);
        if (this.usr.userName) {
            // enable to button here.
            console.log("found username in AfterViewChecked");
        }
    }
}

or you might be able to try Angular2's other Lifecycle Hooks https://embed.plnkr.co/?show=preview

-2
votes

According to the offical docs

"pristine" means the user hasn't changed the value since it was displayed in this form

So if you have a validation in your form it's a better approach to check if the form is "valid" or "invalid"

<button [disabled]="formName.invalid">Submit</button>

So it doesn't matter if the form is pristine or not.