Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 template driven form group validation

I have a question regarding the angular 2 template driven form. I have set up one of this form and I would like to be able to give the user a warning display if one input in a form group is invalid.

For example, let's say I have the following form :

<form class="form" #f="ngForm" (submit)="submit()">
    <div class="form-group">
       <input type="text" name="firstName" required [(ngModel)]="user.firstName">
       <input type="text" name="lastName" required [(ngModel)]="user.lastName">
    </div>
    <div class="form-group">
        <input type="text name="address" required [(ngModel)]="user.address">
    </div>
    <button type="submit" [disabled]="!f.valid">Submit</button>
</form>


I would like the entire form-group that contains the input "firstName" and input "lastName" to change if either the firstName and/or the lastName is invalid. I know I could do something like that :

<div class="form-group" [class.has-error]="!firstName.valid || !lastName.valid">
   <input type="text" name="firstName" required [(ngModel)]="user.firstName" #firstName="ngModel">
   <input type="text" name="lastName" required [(ngModel)]="user.lastName" #lastName="ngModel">
</div>


It will works just fine. But here is the tricky part : in this example I only have two inputs with a simple validation rule, so it's easy to check and still readable. But what if I have like 10 inputs to check in a form-group ? I don't want to end up having to manually check the validity of every inputs.

One of the solution I found is to create a subform inside the first one :

<form class="form" #f="ngForm" (submit)="submit()">
    <form #subForm="ngForm" [class.has-error]="!subForm.valid">
       <input type="text" name="firstName" required [(ngModel)]="user.firstName">
       <input type="text" name="lastName" required [(ngModel)]="user.lastName">
    </form>
    <div class="form-group">
        <input type="text name="address" required [(ngModel)]="user.address">
    </div>
    <button type="submit" [disabled]="!f.valid || subForm.valid">Submit</button>
</form>


Here is a plunker I created to illustrate : form validation example

But I find it quite ugly, and I'm force to check the two forms to know if there is any problems. So finally my question is : can I set a div as a angular 2 ngForm to be able to validate multiple inputs at once ? Basically is there a better way to perform this kind of validation than creating a subform ? Something like that for example :

<div class="form-group" #names [class.has-error]="!names.valid">
   <input type="text" name="firstName" required [(ngModel)]="user.firstName" #firstName="ngModel">
   <input type="text" name="lastName" required [(ngModel)]="user.lastName" #lastName="ngModel">
</div>


PS : I know using a function is another solution but it has the same drawbacks : you have to check manually every inputs, depending on the validation rule it can become quite tricky, plus you're losing one of the advantage of using template driven form instead of reactive ones.

like image 675
Orodan Avatar asked Feb 09 '17 10:02

Orodan


1 Answers

Yeah, you can use the ngModelGroup directive for this.

<form class="form" #f="ngForm" novalidate>

  <div class="form-group" #fgName="ngModelGroup" ngModelGroup="name" [class.has-error]="!fgName.valid">
    <input type="text" class="form-control" name="firstName"
            [(ngModel)]="user.firstName"
            placeholder="first name"
            required>

    <input type="text" class="form-control" name="lastName"
            [(ngModel)]="user.lastName"
            placeholder="last name"
            required>
  </div>

  <div class="form-group">
    <input type="text" class="form-control" name="address"
            [(ngModel)]="user.address"
            placeholder="address"
            required>
  </div>

  <button class="btn btn-primary" [disabled]="!f.valid">Submit</button>

</form>
like image 133
Brother Woodrow Avatar answered Sep 29 '22 23:09

Brother Woodrow