Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing validator’s state inside a template for an control in a FormArray

I am using Angular’s reactive forms and would like to apply a css style to controls inside a FormArray depending on the value of the control’s invalid property. I have come up with the following approach but I think the expression inside the ngClass property is too long and complex. Is there a more succinct way to access the invalid property for a control within a FormArray?

Template:

<form [formGroup]="myForm" class="form-horizontal">
    <div class="form-group" [ngClass]="{'has-error': myForm.controls.name.invalid }">
        <label class="control-label">Name</label>
        <input formControlName="name" type="text" class="form-control" />
    </div>
    <div formArrayName="array1">
        <div *ngFor="let f of array1_FA.controls; let i = index" [formGroupName]="i">
            <div>
                <div class="form-group" 
                    [ngClass]="{'has-error': myForm.controls.array1.at(i).controls.question.invalid}">

                    <label class="control-label">Question #{{i+1}}</label>
                    <input formControlName="question" class="form-control" type="text" />
                </div>
                <div class="form-group" 
                    [ngClass]="{'has-error': myForm.controls.array1.at(i).controls.response.invalid}">

                    <label class="control-label">Answer #{{i+1}}</label>
                    <input formControlName="response" class="form-control" type="text" />
                </div>
            </div>
        </div>
    </div>
</form>

Component:

import { Component } from '@angular/core';
import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms';

@Component({
    selector: 'form-array-validation',
    templateUrl: './form-array-validation.component.html'
})

export class FormArrayValidationComponent {

    myForm: FormGroup;
    questions = ['Q1', 'Q2', 'Q3', 'Q4'];

    constructor(private fb: FormBuilder) {
        this.createForm();
    }

    createForm() {
        this.myForm = this.fb.group({
            name: ['Name1', Validators.required],
            array1: this.fb.array(this.questions.map(val => this.fb.group({
                question: [val, Validators.required],
                response: [null, Validators.required]
            })))
        });
    }

    get array1_FA(): FormArray {
        return this.myForm.get('array1') as FormArray;
    };
}
like image 325
EricAZ Avatar asked Oct 18 '17 18:10

EricAZ


People also ask

How do I validate FormArray controls?

Validating Angular FormArray First you need to add the required validators while creating a new product form group inside the addProduct method. Now let's add a span element adjacent to the input control. Add the following CSS to the app. component.

How do I add a form control in FormArray?

Adding input controls dynamically Let's add a mat-icon-button besides the input form field to add a new control. To do that we'll have to add some style and convert the div into a flex row. We'll add a class to the div and add the styles in our css file. Next, let's add the button itself.

How do I use FormArray in FormBuilder?

First, we need to import the FormArray from the Angular Forms Module. Build a formGroup orderForm using the FormBuilder. We define items as FormArray. We need to capture two fields under each item, the name of the item & description and price.

How do I disable FormControl in FormArray?

push(new FormGroup({ 'inputValue': new FormControl({ value: '', disabled: true }, Validators. required), })); You have to remember that disabling the form input will not allow you to submit. Instead, you can use the readonly property as below.


1 Answers

In this case you can make use of your f in the iteration in template:

*ngFor="let f of array1_FA.controls;

which makes your code a bit shorter/cleaner, so instead of:

[ngClass]="{'has-error': myForm.controls.array1.at(i).controls.question.invalid}">

do:

[ngClass]="{'has-error': f.get('question').invalid}

or

[ngClass]="{'has-error': f.controls.question.invalid}
like image 191
AT82 Avatar answered Sep 22 '22 13:09

AT82