Reputation: 585
Problem:
I have build a reactive form in angular which is dynamically adding a form field when the user clicks on plus button. This is how my code looks like.
<form [formGroup]="distributionAddForm" (ngSubmit)="onSubmit(distributionAddForm.value)">
<div class="row">
<div class="col-lg-10">
<div formArrayName="stocks">
<div *ngFor="let item of distributionAddForm.controls.stocks.controls; let stockIndex=index"
[formGroupName]="stocks">
<span>Product Item {{stockIndex + 1}}</span>
<div class="form-group">
<label>Stock :</label>
<div class="input-group input-group-alternative mb-3">
<select class="custom-select" id="stockid" formControlName="stockId">
<option value="0">Select Stock Item</option>
<option value="1">GOGREEN MEGA 500ml</option>
<option value="2">GOGREEN PLUS 500ml</option>
</select>
</div>
</div>
<div class="row">
<div class="col-lg-10">
<div class="form-group">
<label>Quantity :</label>
<div class="input-group input-group-alternative mb-3">
<div class="input-group-prepend">
<span class="input-group-text"><i class="nc-icon nc-box"></i></span>
</div>
<input class="form-control" placeholder="10" type="text" formControlName="quantity"
required />
</div>
</div>
</div>
<div class="col-lg-2">
<button type="button" class="btn btn-danger btn-sm" (click)="removeProducts(stockIndex)"><i
class="fas fa-minus-circle"></i></button>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-2">
<button type="button" class="btn btn-info btn-sm mt-4" (click)="addProducts()"><i
class="fas fa-plus-circle"></i></button>
</div>
</div>
<button type="submit" class="btn btn-success" [disabled]="!distributionAddForm.valid">Add</button>
</form>
This is how I have done it in component.ts file.
constructor(
private formBuilder: FormBuilder,
) {
this.distributionAddForm = this.formBuilder.group({
stocks: this.formBuilder.array([this.initStocks()])
});
}
initStocks() {
return this.formBuilder.group({
stockId: ['0', Validators.required],
quantity: ['', Validators.required]
});
}
get AllStockItems(){
return this.distributionAddForm.get('stocks') as FormArray;
}
addProducts() {
const control = <FormArray>this.distributionAddForm.controls['stocks'];
control.push(this.initStocks());
}
removeProducts(i: number) {
if(this.AllStockItems.length>1){
const control = <FormArray>this.distributionAddForm.controls['stocks'];
control.removeAt(i);
}
}
When we consider this piece of code in component.html file.<span>Product Item {{stockIndex + 1}}</span>
stockIndex + 1 is showing the number only in the first input field only. It not showing this number on the dynamically added second input sets. Can someone tell me where I have done wrong? Thank you very much.
Upvotes: 0
Views: 948
Reputation: 9357
I'd suggest you do this:
<div *ngFor="let item of distributionAddForm.controls.stocks.controls; let stockIndex=index"
[formGroupName]="stockIndex">
About the error message:
<div class="input-group input-group-alternative mb-3">
<div class="input-group-prepend">
<span class="input-group-text">
<i class="nc-icon nc-box"></i>
</span>
</div>
<input class="form-control" placeholder="10"
type="text" formControlName="quantity" required>
</div>
<div *ngIf="_showFormArrayError(stockIndex, 'quantity')"
class="alert alert-danger">
Quantity is Required
</div>
And in the typescript class:
/** Notice that formGroupName is an index */
_showFormArrayError(formGroupName: number, controlName: string): boolean {
const formArray: FormArray = this.agentEditForm.get('stocks') as FormArray;
const formGroup: FormGroup = formArray &&
formArray.get(`${formGroupName}`) as FormGroup;
const formControl: FormControl = formGroup &&
formGroup.get(controlName) as FormControl;
return (formControl && !formControl.valid &&
(formControl.dirty | formControl.touched));
}
Upvotes: 1