Search code examples
javascriptangulartypescriptvalidationangular-forms

How to add required validation to matInput if the checkbox is checked


I have 5 checkboxes in a FormGroup, display using ngFor, and 1 matInput that has to be a required field if any of the checkboxes is checked.

.ts

this.gridForm = this.fb.group({
      cbox1: [''],
      cbox2: [''],
      cbox3: [''],
      cbox4: [''],
      cbox5: [''],
      input1: ['', Validators.required] });

.html

            <div *ngFor="let table of xTables; let i = index;">
              <mat-checkbox formControlName="{{xTableKeys[i]}}">{{table}}</mat-checkbox>
            </div>
            <mat-form-field>
              <input matInput formControlName="xType" placeholder="X Type">
            </mat-form-field>

I've added required validators for the input, but what I need is to make it required only after any of the checkboxes is checked. Current status is I cannot submit the form unless I fill in the input, but with or without checking the checkbox.


Solution

  • You can use custom validator:

    
        this.gridForm = this.fb.group({
              cbox1: [''],
              cbox2: [''],
              cbox3: [''],
              cbox4: [''],
              cbox5: [''],
              input1: ['', [requiredIfValidator(() => this.gridForm.get('cbox1' && 'cbox2' && 'cbox3' && 'cbox4' && 'cbox5').value)]] 
        });
        
            function requiredIfValidator(predicate) {
              return (formControl => {
                if (!formControl.parent) {
                  return null;
                }
                if (formControl.parent.get('cbox1').value) {
                  return Validators.required(formControl);
                }
                if (formControl.parent.get('cbox2').value) {
                  return Validators.required(formControl);
                }
                if (formControl.parent.get('cbox3').value) {
                  return Validators.required(formControl);
                }
                if (formControl.parent.get('cbox4').value) {
                  return Validators.required(formControl);
                }
                if (formControl.parent.get('cbox5').value) {
                  return Validators.required(formControl);
                }
                return null;
              })
            };
    

    Subscribe to the value changes to trigger the conditional validation when you toggle the checkbox.

    
        this.gridForm.get('cbox1').valueChanges
          .subscribe(value => {
            this.gridForm.get('input1').updateValueAndValidity();
          });
        this.gridForm.get('cbox2').valueChanges
          .subscribe(value => {
            this.gridForm.get('input1').updateValueAndValidity();
          });
        this.gridForm.get('cbox3').valueChanges
          .subscribe(value => {
            this.gridForm.get('input1').updateValueAndValidity();
          });
        this.gridForm.get('cbox4').valueChanges
          .subscribe(value => {
            this.gridForm.get('input1').updateValueAndValidity();
          });
        this.gridForm.get('cbox5').valueChanges
          .subscribe(value => {
            this.gridForm.get('input1').updateValueAndValidity();
          });
    
    

    This is known as custom conditional field validator. Checkout this link https://medium.com/ngx/3-ways-to-implement-conditional-validation-of-reactive-forms-c59ed6fc3325