I am working with Prime-ng, and I need to expand my registration forms with FormArray and continue to dynamically display other child forms. The image shows what I'm trying to achieve.
In my component I have:
initFrmCotizacion(){
this.frmCotizacion = this.build.group({
ingresoDetalle: null,
descripcion: ['',Validators.required],
cotizacionArray: this.build.array([])
})
}
datosCotizacionArray(): FormArray {
return this.frmCotizacion.get('cotizacionArray') as FormArray;
}
anadirCotizacionArray() {
this.datosCotizacionArray().push(this.newCotizacionArray());
}
newCotizacionArray(){
return this.build.group({
idd: this.dataKey, //<- this use in dataKey to cotizacionArray
adjunto: [null,Validators.required],
proveedor: [1,Validators.required],
cantidad: [1,Validators.required],
precioUnitario: [1,Validators.required],
comentarios: ['',Validators.required],
rangosArray: this.build.array([])
});
}
removeFeature(index: number) {
this.datosCotizacionArray().removeAt(index);
this.myFiles.splice(index,1);
}
anadirRangosArray(index) {
this.datosRangosArray(index).push( this.newRangosArray() );
}
newRangosArray() {
return this.build.group({
id: this.dataKey2, //<- this use in dataKey to rangosArray
min: [null, Validators.required],
max: [null, Validators.required],
precio: [null, Validators.required]
});
}
datosRangosArray(index: number): FormArray{
return this.datosCotizacionArray()
.at(index)
.get('rangosArray') as FormArray;
}
In my html I have:
<p-button label="Nueva cotización" icon="pi pi-plus" (click)="anadirCotizacionArray()" styleClass="p-button-sm"></p-button>
<form [formGroup]="frmCotizacion" (ngSubmit)="saveCotizacion()">
<div formArrayName="cotizacionArray">
<p-table styleClass="p-datatable-sm p-datatable-gridlines" dataKey="idd"
[value]="datosCotizacionArray().controls" responsiveLayout="stack">
<ng-template pTemplate="header">
<tr>
<th style="width: 3rem"></th>
<th>Archivo</th>
<th>Proveedor</th>
<th>Cantidad</th>
<th>Precio U.</th>
<th>Precio T.</th>
<th>Comnetarios</th>
<th style="width: 100px;"></th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-control let-expanded="expanded" let-i="rowIndex">
<tr [formGroupName]="i">
<td>
<button type="button" pButton pRipple [pRowToggler]="control"
[icon]="expanded ? 'pi pi-chevron-down' : 'pi pi-chevron-right'"></button>
</td>
<td>
<input style="width: 70%;" id="adjunto" type="file" multiple name="file" accept="application/pdf"
formControlName="adjunto" pInputText placeholder="adjunto"
(change)="onFileChange($event)">
</td>
<td>
<p-autoComplete formControlName="proveedor" [style]="{width: '100%'}" z-index=""
[suggestions]="filteredCountries" (completeMethod)="filterCountry($event)"
field="name" [minLength]="1" [dropdown]="true">
<ng-template let-country pTemplate="item">
<div >
<div>{{country.name}}</div>
</div>
</ng-template>
</p-autoComplete>
</td>
<td>
<p-inputNumber [inputStyle]="{width: '100%'}" #cant id="cantidad" formControlName="cantidad" placeholder="Cantidad" mode="decimal" [useGrouping]="false" [min]="0"></p-inputNumber>
</td>
<td>
<p-inputNumber [inputStyle]="{'text-align': 'right', width: '100%'}"
#prec id="preciounitario" formControlName="precioUnitario" placeholder="Precio unitario"
mode="decimal" [min]="1" [maxFractionDigits]="5"></p-inputNumber>
</td>
<td>
{{ cant.value * prec.value }}
</td>
<td>
<textarea pInputTextarea formControlName="comentarios"></textarea>
</td>
<td style="width: 100px">
<button pButton pRipple type="button" (click)="removeFeature(i)" icon="pi pi-times" ></button>
<button pButton pRipple type="button" (click)="anadirRangosArray(i)" icon="pi pi-check" ></button>
</td>
</tr>
</ng-template>
<ng-template pTemplate="rowexpansion" let-conti>
<tr>
<td colspan="8">
<div >
<p-table [value]="datosRangosArray(0).controls" dataKey="id">
<ng-template pTemplate="header">
<tr>
<th>Mínimo</th>
<th>Máximo</th>
<th>Precio</th>
<th></th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-rangos let-j="index" >
<tr [formGroupName]="j">
<td>
<p-inputNumber [inputStyle]="{'text-align': 'right', width: '100%'}"
id="min" formControlName="min" placeholder="Cantidad mínima"
mode="decimal" [min]="1" [maxFractionDigits]="5"></p-inputNumber>
</td>
<td>
<p-inputNumber [inputStyle]="{'text-align': 'right', width: '100%'}"
id="max" formControlName="max" placeholder="Cantidad máxima"
mode="decimal" [min]="1" [maxFractionDigits]="5"></p-inputNumber>
</td>
<td>
<p-inputNumber [inputStyle]="{'text-align': 'right', width: '100%'}"
id="precio" formControlName="precio" placeholder="Precio"
mode="decimal" [min]="1" [maxFractionDigits]="5"></p-inputNumber>
</td>
<td><p-button type="button" icon="pi pi-search"></p-button></td>
</tr>
</ng-template>
</p-table>
</div>
</td>
</tr>
</ng-template>
</p-table>
</div>
<br>
<div >
<div >
<textarea rows="5" cols="60" placeholder="Descripción" formControlName="descripcion" pInputTextarea></textarea>
</div>
</div>
<div >
<button pButton icon="pi pi-save" label="Rechazar" ></button>
<button pButton icon="pi pi-trash" label="Guardar" [disabled]="!frmCotizacion.valid" ></button>
</div>
</form>
My problem is that I need to dynamically add the child forms. The parent forms as well as the child forms must be sent to a database with a button, that means that I manually assign the values to "id" which I then use for the dataKey="id". Adding the parent form works fine, but when expanding I need to retrieve
[formGroupName]="i"
it in my ng-template where I put the child forms. Currently I add the value zero to function
[value]="datosRangosArray(0).controls"
This work only for the index "0" in cotizacionArray. The error in the browser console is:
ERROR Error: Cannot find control with path: 'cotizacionArray -> ' Considering that the child forms must be in ng-template how would I go about getting the value of "i"
Please help me
The example in stackblitz
CodePudding user response:
You just need to handle controls by instances and I have added expand button.
datosRangosArray(formGroup: FormGroup): FormArray {
return formGroup.get('rangosArray') as FormArray;;
}
<p-table [value]="datosRangosArray(conti).controls" dataKey="id">