Reputation: 61
Angular 4 template driven validation fails. Is this a known issue, or my bug?
Html:
<div class="form-group">
<label for="email">Email</label>
<input type="email" class="form-control" id="email" required
[(ngModel)]="model.email" name="email" #email="ngModel" #spy>
<div>TODO remove: {{spy.className}}</div>
<div [hidden]="email.valid || email.pristine" class="alert alert-danger">
Valid email is required
</div>
</div>
Component class has property: model = new SignupModel('','','','');
CSS:
input:invalid:not(.ng-pristine) {
border-left: 5px solid #a94442; /* red */
}
input:valid:not(.ng-pristine) {
border-left: 5px solid #42A948; /* green */
}
When page first loads, you can see email class names: form-control ng-untouched ng-pristine ng-invalid The alert message is hidden due to email.pristine === true
When user starts typing "aa" the class names change: form-control ng-dirty ng-valid ng-touched Now the message is hidden due to email.valid === true However, since "aa" is not a valid email, the left border shows as red via css.
Why does Angular consider email.valid to be true and sets ng-valid class, when the css correctly interprets the input as invalid?
The style class does change to ng-invalid when you remove "aa", correctly interpreting "required" property.
Upvotes: 2
Views: 2681
Reputation: 61
Solution is to add additional "email" attribute to input tag:
<input type="email" class="form-control" id="email" required email
[(ngModel)]="model.email" name="email" #email="ngModel">
Upvotes: 2