简体   繁体   中英

Add dynamic form fields and validations to formArray in Angular

I'm trying to build a dynamic form, where the field names and their validations will come from an API

so I'm creating a simple form, with a formArray inside, something like this:

this.myForm = this.formBuilder.group({
  dynamicFields: this.formBuilder.array([])  // where I will be pushing the custom fields and their validations
});

Just for testing, I'm trying to add a field 'country', with 2 validations (required, minLength of 22)

this is what I'm doing:

let customControl = this.fb.control('country', [ Validators.required, Validators.min(10) ]);
(this.myForm.get('dynamicFields') as FormArray).push(customControl);

I also created the bellow getter to use it in my template

getDynFields() {
  return this.myForm.get('dynamicFields') as FormArray;
}

and this is the template:

<form [formGroup]="myForm">
  <div formArrayName="dynamicFields">
    <div *ngFor="let control of getDynFields().controls; let i = index">
      <mat-form-field>
        <input
          [formControlName]="i"
          matInput
          type="text"
          placeholder="{{ control.value }}"
        />
      </mat-form-field>
    </div>
  </div>
</form>

what is happening (as you see below) is that for the field value and placeholder I'm getting 'country' pre-populated (I only want the placeholder to be 'country' and the value should be empty of course) And the second issue is that only required validation is working, minLength is not doing anything

在此处输入图像描述

Thanks in advance.

FormControl takes 'state' or default value as first param while initialising. Also for min length, you should use Validators.minLength(n) .

constructor(formState: any = null, validatorOrOpts?: ValidatorFn | AbstractControlOptions | ValidatorFn[], asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[])

instead of this

let customControl = this.fb.control('country', [ Validators.required, Validators.min(10) ]);

you should do this

let customControl = this.fb.control('', [ Validators.required, Validators.minLength(10) ]);

Validators.min() vs Valiadators.minLength()

You are using Validators.min() . This is intented to check numerical input values, not to get the length of a string:

let customControl = this.fb.control('country', [ Validators.required, Validators.min(10) ]);

Use Validators.minLength() instead:

let customControl = this.fb.control('country', [ Validators.required, Validators.minLength(10) ]);

The first parameter of a FormControl is its value

The first parameter of a FormControl is its value . You are setting a value of 'country' in your example:

let customControl = this.fb.control('country', [ Validators.required, Validators.minLength(10) ]);

If you set it to null you will see whatever placeholder you have set.

let customControl = this.fb.control(null, [ Validators.required, Validators.minLength(10) ]);

You can implement the placeholder however you want in your template. As a string or a reference to some objects property.

For min length please use Validators.minLength(22)
Please refer: https://angular.io/api/forms/Validators#minLength for more info.
min(10) used to add validation as minimum value can be 10.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM