Roxy Roxy - 1 month ago 19
HTML Question

model driven form: validation not working as expected in Angular 2

I am using the model driven form like this .
Just like normal validations , i want that i show an error message if username and password are missing.

And Submit button should be disabled as long as username and password are not valid.

<div class="login">
<form #f="ngForm" (ngSubmit)="dologin(f)">
<div class="form-group">
<label for="username">Username</label>
<input id="username" type="text" class="form-control" name ="username" ngModel #username="ngModel">

<div [hidden]="username.valid" class="alert alert-danger"> Username is required.</div>
</div>
<div class="form-group">
<label for="password">Password</label>
<input id="password" type="password" class="form-control" name ="password" ngModel #password="ngModel">
<div [hidden]="password.valid" class="alert alert-danger"> Password is required.</div>
</div>

<button type="submit" [disabled]="username.length<0 || password.length<0" class="btn btn-primary" type="submit">Login</button>
</form>
</div>



  • i am seeing quite strange behaviour from validation div. Sometimes
    it is showing "Password is required" and sometimes not.

  • i want to disable the submit button, until the form is valid .i tried




[disabled]="!f.valid"


but as i print it out f is always valid even
though i have not entered any data in username and password.

Component:

constructor(private router: Router,private authenticationService : AuthenticationService,private httpService:HttpService,private formBuilder:FormBuilder) {
this.form=formBuilder.group({
username:['',Validators.required],
password:['',Validators.required]
});

}


UPDATE


Can't bind to 'formGroup' since it isn't a known property of 'form'.
(" ][formGroup]="form"
(ngSubmit)="dologin(form.value)">


][formControl]="form.controls['password']">
[ERROR ->]


Username
[ERROR ->]

"): LoginComponent@4:8 No provider for NgControl ("

Password
[ERROR ->] ; Task: Promise.then ; Value:
Error: Template parse errors:(…) Error: Template parse errors: Can't
bind to 'formGroup' since it isn't a known property of 'form'. ("

][formGroup]="form"
(ngSubmit)="dologin(form.value)">


][formControl]="form.controls['password']">
[ERROR ->]


Username
[ERROR ->]


Thanks.

Answer

The way you have set up your HTML template is missing some key bits that actually ensure you have wired up the front end to the back end for a reactive form. What you have appears to be more in line with a template driven form mixed with model driven. In fact, the template you have posted will not even compile if you remove your FormsModule import.

To begin with remove your FormsModule import which is letting you mix the two different form types together. This will take us down a path where a strict Reactive Forms (aka model driven) implementation is required.

<form #f="ngForm" (ngSubmit)="dologin(f)"> will be changed to <form [formGroup]="form" (ngSubmit="dologin(form.value)"

Each of your inputs and warning divs will change from

<input id="username" type="text" class="form-control" name="username" ngModel #username="ngModel">

<div [hidden]="username.valid" class="alert alert-danger"> Username is required.</div>

To

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

The changes are because the ngModel attribute and #[name]="ngModel" are not supported in the model driven form, so instead you will use either formControlName or [formControl] syntax.

        <div [hidden]="form.controls['username'].valid || form.controls['username'].pristine"
        class="alert alert-danger"> Username is required.</div>

Finally, your submit button changes, note that you have type="submit" twice, from <button type="submit" [disabled]="username.length<0 || password.length<0" class="btn btn-primary" type="submit">Login</button>

To

<button type="submit" [disabled]="!form.valid" class="btn btn-primary">Login</button>

since we have successfully wired up the rest of the form the validation on the form group will now be correct

And here is a working plunker that you can play around with: https://plnkr.co/edit/Mu9vEYGB35SwUr9TEsPI?p=preview