Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditional Form Validations for Angular Reactive Form

I'm trying to set conditional form validations on an angular reactive form and need some help.

I have a form control where the user sets their entity type to either Individual or Business

<select formControlName="entity">
  <option [value]="individual">Individual</option>
  <option [value]="business">Business</option>
</select>

I then have form inputs that display or hide based upon what entity is selected:

<div *ngIf="myForm.controls.entity.value == individual>
  <input formControlName="fullName" />
</div>

<div *ngIf="myForm.controls.entity.value == business>
  <input formControlName="businessName" />
</div>

How can I make both inputs required only if the corresponding entity is selected?

like image 922
jordanpowell88 Avatar asked Oct 09 '17 19:10

jordanpowell88


3 Answers

You can use the attribute [formControl]="name_of_your_input_control" assuming this html is within a formGroup element

<div [hidden]="isBusiness">
  <input [formControl]="fullName" />
</div>

<div [hidden]="!isBusiness">
  <input [formControl]="businessName" />
</div>

in your ts class :

After you create your form add this :

isBusiness:boolean = false;
//...
this.nameOfYourForm.valueChanges.subscribe((newForm) => {
     this.isBusiness = (newForm.controls.entity.value == 'business');
     if(this.isbusiness){
        this.nameOfYourForm.controls.fullName.setValidators(/*your new validation here*/);
           //set the validations to null for the other input
     }else{       
           this.nameOfYourForm.controls.businessName.setValidators(/*your new validation here*/);
           //set the validations to null for the other input
     } 
});

Notice that I changed your *ngIf to [hidden] as *ngIf will completely remove the controle from your template where [hidden] will just apply a display none.

You can also add a change listener on a specific control instead of the whole form, but the idea is the same.

like image 144
Mehdi Avatar answered Oct 22 '22 21:10

Mehdi


RXJS is a big part of the angular reactive forms. ReactiveForms has a elegant solution for this problem.


const formGroup= new FormGroup({
    type: new FormControl(), 
    businessForm: new FormGroup({
      businessName: new Formcontrol('')
    }), 
    individualForm:new FormGroup({
      individualName: new Formcontrol('')
    })
}); 

formType$ = this.formGroup.controls['type'].valueChanges; 

<form [formGroup]="formGroup">

   <div formGroupName="businessForm" *ngIf="(formType$ | async) =='business'">       
     <input formControlName="businessName"/>
   </div>

   <div formGroupName="individualForm" *ngIf="(formType$ | async) =='individual'">
     <input formControlName="individualName"/>
   </div>

</form>

like image 35
Ahmet Emrebas Avatar answered Oct 22 '22 20:10

Ahmet Emrebas


I have an other version:

HTML

<select #select formControlName="entity">
  <option  [ngValue]="Individual">Individual</option>
  <option  [ngValue]="Business">Business</option>
</select>
<br>
<div *ngIf="select.value[0]  === '0'">
  <input #input [required]="select.value[0] === '0'" formControlName="fullName" />
  <span *ngIf="!myForm.get('fullName').valid">Invalid</span>
</div>

DEMO

like image 35
Vega Avatar answered Oct 22 '22 21:10

Vega