I'm dynamically adding rows each with three select menus in my angular project and I need to access the values of them in the component ts file.
Right now the select menus are named Col1
, Comparator
, Col2
.
When I add another row, the menus in the 2nd row are named the same. That's a problem. How can I change it to a dynamic naming?
Like row 1 has Col1-a
, Comparator-a
, Col2-a
row 2 has Col1-b
, Comparator-b
, Col2-b
component html:
<div [formGroup]="form">
<ng-container formArrayName="block">
<ng-container *ngFor="let blockForm of block.controls; let j = index">
<div [formGroupName]="j">
<mat-form-field [style.width.px]=150 [style.margin-left.px]=10 appearance="fill">
<mat-select formControlName="Col1" (click)="getCols()" placeholder="select column 1">
<mat-option *ngFor="let i of DfCols" [value]="i" >{{i}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field [style.width.px]=100 [style.margin-left.px]=10 appearance="fill">
<mat-select formControlName="Comparator" placeholder="comparator">
<mat-option *ngFor="let com of comparator" [value]="com" >{{com}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field [style.width.px]=150 [style.margin-left.px]=10 appearance="fill">
<mat-select formControlName="Col2" (click)="getCols()" placeholder="select column 2">
<mat-option *ngFor="let i of DfCols" [value]="i" >{{i}}</mat-option>
</mat-select>
</mat-form-field>
<app-button [style.margin-left.px]=0 color="grey" text="test" (btnClick)="test()"></app-button>
<app-button [style.margin-left.px]=0 color="salmon" text="Delete condition block" (btnClick)="deleteblock(j)"></app-button>
</div>
</ng-container>
</ng-container>
<app-button [style.margin-left.px]=0 color="lightblue" text="Add condition block" (btnClick)="addblock()"></app-button>
</div>
component ts:
export class FormgroupStrategyComponent implements OnInit {
DfCols!:any;
comparator = ['>', '>=', '<', '<=', '==', '!=']
form = this.fb.group({
block: this.fb.array([])
});
constructor(private fb:FormBuilder, private calculationService: DfCalculationService) { }
get block() {
return this.form.controls["block"] as FormArray;
}
addblock() {
const blockForm = this.fb.group({
Col1: ['', Validators.required],
Comparator: ['', Validators.required],
Col2: ['', Validators.required]
});
this.block.push(blockForm)
}
deleteblock(blockIndex: number) {
this.block.removeAt(blockIndex);
}
CodePudding user response:
You could just keep a counter to give a unique id to each group. You can nest each group inside the main group.
form = new FormGroup({});
get groups() {
return Object.keys(this.form.controls);
}
constructor(private fb: FormBuilder) {}
deleteblock(blockId: string) {
this.form.removeControl(blockId);
}
counter = 0;
addblock() {
const id = this.counter ;
const blockForm = this.fb.group({
Col1: ['', Validators.required],
Comparator: ['', Validators.required],
Col2: ['', Validators.required],
});
this.form.addControl(id.toString(), blockForm);
}
<form [formGroup]="form">
<div *ngFor="let group of groups" [formGroupName]="group">
<mat-form-field>
<mat-select formControlName="Col1"></mat-select>
</mat-form-field>
<mat-form-field>
<mat-select formControlName="Comparator"> </mat-select>
</mat-form-field>
<mat-form-field>
<mat-select formControlName="Col2"> </mat-select>
</mat-form-field>
<button (click)="deleteblock(group)">DELETE</button>
</div>
<button (click)="addblock()">ADD</button>
</form>
Since each group has their own id, the form controls will have their own namespace. FormGroup.get()
supports an array of strings to get a control from a nested group
this.form.get(['2', 'Col1']);