9

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?

1

3 Answers 3

14

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Or you can define your control at runtime: <code> isBusiness:boolean = false; //... this.nameOfYourForm.valueChanges.subscribe((newForm) => { this.isBusiness = (newForm.controls.entity.value == 'business'); if(this.isbusiness){ this.nameOfYourForm.registerControl('yourControl', new FormControl('', [Validators])); }else{ this.nameOfYourForm.removeControl('yourControl'); })</code>
1

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

2 Comments

the template should be used for validation logic only in Template-driven forms
@squirrelsareduck, the solution that I propose is for reactive forms, only the check is done in the template. There is nothing wrong with it, I would say there are some advantages. Otherwise, prove it
1

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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.