Reputation: 5756
I was creating fields dynamically based on Json. For example if my json array has 3 value then i will create 3 input checkbox dynamically like below
<ng-template ngFor let-numberOfRow [ngForOf]="numberOfRows">
<mat-checkbox [formControlName]="numberOfRow.row" [value]="numberOfRow.row" [name]="numberOfRow.row">All</mat-checkbox>
</ng-template>
now i m trying to create formBuilder for this fields like below but its not working. Could someone please tell me how to declare formbuilder for dynamic fields ?
public ngOnInit() {
this.myForm= this.fb.group(this.formFields);
}
public formFields() {
let empArr = [];
for (let val of this.myArrayList) {
empArr.push(val + ": ''");
}
let allFields = '{' + empArr.join(',') + '}';
return allFields;
}
basically the above formFields function will return string like this { allRow: '', firstRow: '', secondRow: '', thirdRow: '' }
so instead if declaring statically this.myForm= this.fb.group({ allRow: '', firstRow: '', secondRow: '', thirdRow: '' });
i want to declare the fields dynamically.
Upvotes: 1
Views: 5316
Reputation: 3147
I maintain an array with the json object fields names, and an array with the form controls, then i itterate over the field names in order to create the form checkboxes
TypeScript file:
import { FormBuilder, FormGroup } from '@angular/forms';
export class SomeComponent
{
form!: FormGroup;
fieldNames: string[];
formControls: any;
constructor(
private formBuilder: FormBuilder,
)
{
const someJsonOnject = {env: "Dev", name: "SRV", ver: "21.1" };
this.fieldNames= [];
this.formControls= {};
Object.keys(someJsonOnject).forEach(currentFieldName => {
// add the current field name to the fieldNames array
this.fieldNames.push(currentFieldName);
// create a boolean formControl from each field
this.formControls[currentFieldName] = [true];
});
// add formControls to the form
this.form = this.formBuilder.group(this.formControls);
}
}
HTML Template file:
<form [formGroup]="form">
<ng-container *ngFor="let currentFormControl of fieldNames">
<div><mat-checkbox formControlName="{{ currentFormControl }}">{{ currentFormControl }}</mat-checkbox></div>
</ng-container>
</form>
Upvotes: 0
Reputation: 1683
building with formBuilder example:
component.ts
form: FormGroup;
constructor(
private fb: FormBuilder
) { }
ngOnInit() {
this.form = this.fb.group({
dropOffAddress : ['', Validators.required]
})
}
addInput() {
this.form.addControl(`input-${Object.keys(this.form.value).length}`, new FormControl('', [Validators.required]))
}
removeInput(key: string) {
this.form.removeControl(key)
}
component.html
<form [formGroup]="form" *ngIf="show">
<ng-container *ngFor="let f of form.controls | keyvalue">
<mat-form-field appearance="outline" class="w-100" color="primary">
<mat-label>Label of Input</mat-label>
<mat-icon (click)="addInput()" color="accent" matPrefix>add</mat-icon>
<input type="text" [formControlName]="f.key" [name]="f.key" autofocus matInput placeholder="Digite um endereço">
<mat-icon (click)="removeInput(f.key)" matSuffix>remove</mat-icon>
<mat-error *ngIf="form.invalid">Please fill the field</mat-error>
</mat-form-field>
</ng-container>
</form>
Upvotes: 0
Reputation: 5756
As per @charlietfl issue is i am sending the string data instead of object, so i send as object like below now its working fine.
public ngOnInit() {
this.myForm= this.fb.group(this.formFields());
}
public formFields() {
let empArr = {};
for (let val of this.myArrayList) {
empArr[val] = '';
}
return empArr;
}
so the above method formField created object like { allRow: '', firstRow: '', secondRow: '', thirdRow: '' }
so now its working fine. Thanks everyone :)
Upvotes: 1
Reputation: 12052
You can do this by first building the FormControl in code using the control method of the FormBuilder and then using the addControl method of the FormGroup. For example like this:
this.myForm.addControl('controlName',
this.fb.control({ disabled: false, value: controlValue }, validators, asyncValidators));
Then you need to bind it using the FormControlDirective instead of the FormControlName directive because the control is already created. The binding will then look like this:
<mat-checkbox [formControl]="myForm.controls['controlName']" [value]="numberOfRow.row" [name]="numberOfRow.row">All</mat-checkbox>
Upvotes: 1