I am trying to check whether a form is valid or not to prevent further execution if it is not.
Here is my form:
<form (ngSubmit)="updateFirstName(firstNameForm)" #firstNameForm="ngForm" novalidate>
<div class="form-group" ng-class="getCssClasses(formCtrl, formCtrl.firstName)">
<div class="input-group">
<input type="text"
ngControl="firstName"
#firstName="ngForm"
required
minlength="2"
maxlength="35"
pattern_="FIRST_NAME_PATTERN"
[ngModel]="currentUserAccount?.firstName"
(ngModelChange)="currentUserAccount ? currentUserAccount.firstName = $event : null"
placeholder="{{'FIRST_NAME_FORM.NEW_FIRST_NAME'| translate }}"
class="form-control"/>
</div>
<div [hidden]="firstName.valid">
<div *ngIf="firstName?.errors?.minlength" class="control-label">{{'FIRST_NAME_FORM.MIN_LENGTH'| translate}}</div>
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary pull-right" [disabled]="buttonDisabled">{{'FIRST_NAME_FORM.SUBMIT'| translate}}</button>
<a [routerLink]="['/dashboard/useraccount']" class="btn btn-link pull-right text-right">{{'FORM_CANCEL' | translate}}</a>
</div>
</form>
However, when I submit an invalid form, I notice in the console that the valid attribute of NgForm
is true
...
updateFirstName(firstNameForm) {
console.log(firstNameForm);//the valid attribute of firstNameForm is true...
}
Can anyone please let me know why this is the case?
To add validation to a template-driven form, you add the same validation attributes as you would with native HTML form validation. Angular uses directives to match these attributes with validator functions in the framework.
A function that receives a control and synchronously returns a map of validation errors if present, otherwise null. interface ValidatorFn { (control: AbstractControl<any, any>): ValidationErrors | null }
You are doing template driven forms. Please refer to this simple plunk
<h1>Employee Form</h1>
<form #personForm="ngForm" (submit)="personFormSubmit(personForm)" novalidate>
<div>
<div>
<input id="nameInput" type="text" name="name"
ngControl="name"
required
minlength="2"
maxlength="35"
[(ngModel)]="person.name" />
</div>
</div>
<div>
<button type="submit">Submit</button>
</div>
<div style="color: red">{{validationMessage}}</div>
</form>
and then the controller:
import { Component } from '@angular/core';
import { FORM_DIRECTIVES, ControlGroup, Control, Validators, FormBuilder, Validator, } from '@angular/common';
import 'rxjs/Rx';
export class Person {
id: number;
name: string;
}
@Component({
selector: 'my-app',
directives: [FORM_DIRECTIVES],
templateUrl: 'app/app.component.html'
})
export class AppComponent {
person: Person;
validationMessage: string;
constructor() {
this.person = new Person();
this.validationMessage = "";
}
personFormSubmit(personForm: ControlGroup) {
if (personForm.valid) {
this.validationMessage = "Form Is Valid";
}
else
{
this.validationMessage = "Form Is Not Valid";
}
}
}
If you want to move to more complex dynamic validation then it would be better to convert to Model driven Forms. As with this plunk
That's the intended behavior
I found in the change log for 2.0.0-alpha.46 (2015-11-11)
Previously, the controlsErrors getter of ControlGroup and ControlArray returned the errors of their direct children. This was confusing because the result did not include the errors of nested children (ControlGroup -> ControlGroup -> Control). Making controlsErrors to include such errors would require inventing some custom serialization format, which applications would have to understand. Since controlsErrors was just a convenience method, and it was causing confusing, we are removing it. If you want to get the errors of the whole form serialized into a single object, you can manually traverse the form and accumulate the errors. This way you have more control over how the errors are serialized.
Then the docs for ControlGroup
and ControlArray
should be updated
See also https://github.com/angular/angular/issues/6504#issuecomment-171950667
You can check if firstNameForm.valid
is false
and then iterate the control groups and controls for errors.
The NgForm
class has the errors
property because it inherits from AbstractControlDirective
but the errors from nested controls are not collected there.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With