Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Checking whether an Angular2 form is valid or not from within the component

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?

like image 544
balteo Avatar asked May 15 '16 14:05

balteo


People also ask

How do I add validation in template-driven form?

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.

What is ValidatorFn in angular?

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 }


2 Answers

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

like image 50
Eric Weiss Avatar answered Oct 11 '22 18:10

Eric Weiss


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.

like image 39
Günter Zöchbauer Avatar answered Oct 11 '22 18:10

Günter Zöchbauer