I have the code of a components class below:
import {FormBuilder, FormGroup, Validators, FormControl, FormArray} from '@angular/forms'
...
form: FormGroup
constructor(private _fb: FormBuilder) { }
this.form = this._fb.group({
name: ['', [Validators.required]],
sortItem: this._fb.array([
this.initSort(),
])
});
initSort(){
return this._fb.group({
locationName: ['', [Validators.required]],
locationItems: this._fb.array([
this.initSortItems()
])
})
}
initSortItems(){
return this._fb.group({
itemName: ['', [Validators.required]],
itemPicture: ['', []],
})
}
addSort(){
const control = <FormArray>this.form.controls['sortItem'];
control.push(this.initSort());
}
addSortLocationItem(i?: number, t?: number){
// add more locationItems to the sort. This is where I am stuck
// if tried the following with no avail (<FormArray>this.form.get('sortItem').value[i].controls).push(this.initSortItems());
}
I am trying to add more locationItems but what I've tried in the addSortLocationItem() method doesn't work. How can I access the form controls of the correct iteration of sortItem and add multiple locations items to that iteration?
This is my markup:
<div class="">
<a (click)="addSort()" style="cursor: default">
Add Sort Locations +
</a>
</div>
<div formArrayName="sortItem">
<div *ngFor="let sortLocation of form.controls.sortItem.controls; let i=index">
<!-- address header, show remove button when more than one address available -->
<div>
<span>Location {{i + 1}}</span>
<span *ngIf="form.controls.sortItem.controls.length > 1"
(click)="removeAddress(i)">
</span>
</div>
<div [formGroupName]="i">
<!--name-->
<div>
<label>Location Name</label>
<input type="text" formControlName="locationName">
<!--display error message if street is not valid-->
<small [hidden]="form.controls.sortItem.controls[i].controls.locationName.valid">
Street is required
</small>
</div>
<div formArrayName="locationItems">
<div *ngFor="let eachItem of form.controls.sortItem.controls[i].controls.locationItems.controls; let t=index">
<!-- address header, show remove button when more than one address available -->
<div class="">
<a (click)="addSortLocationItem(i,t)" style="cursor: default">
Add Items +
</a>
</div>
<div>
<span>Location Item {{t + 1}}</span>
<span *ngIf="form.controls.sortItem.controls[i].controls.locationItems.controls[t].length > 1"
(click)="removeAddress(t)">
</span>
</div>
<div [formGroupName]="t">
<!--name---->
<div>
<label>Item Name</label>
<input type="text" formControlName="itemName">
<!--display error message if street is not valid-->
<small [hidden]="form.controls.sortItem.controls[i].controls.locationItems.controls[t].controls.itemName.valid">
Name is required
</small>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Any help with this will be greatly appreciated.
If i
is the index
of the main control
, so you can easily get with the following:
addSortLocationItem(i: number, t: number) {
const control = this.sortItem.get(`${i}.locationItems`) as FormArray;
control.push(this.initSortItems());
}
And, as an advice, I'd recommend you to create some variables in order to facilitate the readability of your code
.
form: FormGroup;
name: FormControl;
sortItem: FormArray;
This:
<div *ngFor="let sortLocation of form.controls.sortItem.controls; let i=index">
...
<div *ngFor="let eachItem of form.controls.sortItem.controls[i].controls.locationItems.controls; let t=index">
Can be replaced by:
<div *ngFor="let sortLocation of sortItem.controls; let i = index">
...
<div *ngFor="let eachItem of sortLocation.get('locationItems').controls; let t = index">
The complete code:
import { Component, OnInit } from '@angular/core';
import { FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'
@Component({
...
})
export class BlaBlaComponent implements OnInit {
form: FormGroup;
name: FormControl;
sortItem: FormArray;
constructor(private readonly formBuilder: FormBuilder) { }
ngOnInit(): void {
this.name = this.formBuilder.control('', [Validators.required]);
this.sortItem = this.formBuilder.array([this.initSort()]);
this.form = this.formBuilder.group({
name: this.name,
sortItem: this.sortItem
});
}
initSort() {
return this.formBuilder.group({
locationName: ['', [Validators.required]],
locationItems: this.formBuilder.array([
this.initSortItems()
])
})
}
initSortItems() {
return this.formBuilder.group({
itemName: ['', [Validators.required]],
itemPicture: ['', []],
})
}
addSort() {
this.sortItem.push(this.initSort());
}
addSortLocationItem(i: number, t: number) {
const control = this.sortItem.get(`${i}.locationItems`) as FormArray;
control.push(this.initSortItems());
}
}
PS : I didn't test, let me know if I forgot something.
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.