0
Using Reactiveform I set up a table so the user can add the raw materials of a particular product. The user selects in a mat-select
and add a new row to the table (mat-table
).
The table columns are: Item, Quantity, Value, Subtotal. The addition of new lines works very well, but I’m not able to calculate the subtotal of the line. I’ve actually already done it, but just updating all the rows in the table causes the field to lose focus, and I did it from the following form:
this.materiasPrimaForm.valueChanges.subscribe(value => {
this.rowsMateriasPrima = this.materiasPrimaForm.value;
});
The formgroup
used is that:
this.setFormGroup({
nome: ["", [Validators.required]],
descricao: ["", [Validators.required]],
foto: [""],
materiasPrima: this.fb.array([]),
processos: this.fb.array([]),
cores: ['', Validators.required],
});
These are my columns
// O datasource da tabela é a variável rowsMateriasPrima
<ng-container matColumnDef="quantidade">
<th mat-header-cell *matHeaderCellDef class="mat-fit-cell"> Quantidade </th>
<td mat-cell *matCellDef="let materiaprima;let rowIndex=index;" [formGroupName]="rowIndex" class="mat-fit-cell" >
<input type="text" formControlName="quantidade" #materiaPrimaQuantidade/>
</td>
</ng-container>
<ng-container matColumnDef="valor">
<th mat-header-cell *matHeaderCellDef class="mat-fit-cell"> Valor </th>
<td mat-cell *matCellDef="let materiaprima;let rowIndex=index;"[formGroupName]="rowIndex" class="mat-fit-cell">
<input type="text" formControlName="valor" #materiaPrimaValor/>
</td>
</ng-container>
<ng-container matColumnDef="subtotal">
<th mat-header-cell *matHeaderCellDef class="mat-fit-cell"> Subtotal </th>
<td mat-cell *matCellDef="let materiaprima" class="mat-fit-cell">
{{materiaPrimaQuantidade.value * materiaPrimaValor.value | currency:'BRL':true}}
</td>
</ng-container>
When I run I get the error Cannot read property 'value' of undefined
, in the subtotal column.
How to calculate the subtotal of the line as the user enters the values?
EDIT: I did it, but I don’t know if it’s the best way:
In the subtotal column template
<td mat-cell *matCellDef="let materiaprima;let rowIndex=index;" class="mat-fit-cell"> {{getSubTotalMateriaPrima(rowIndex) | currency:'BRL':true}} </td>
getSubTotalMateriaPrima(rowIndex) {
const { valor, quantidade } = this.materiasPrimaForm.value[rowIndex];
return valor * quantidade;
}
What do you think?
EDIT2:
subscribe for form changes:
this.materiasPrimaForm.valueChanges.subscribe(value => {
this.updateMateriaPrimaSubTotal();
this.updateCustoProducao();
});
/* ... */
updateMateriaPrimaSubTotal() {
for (let rowIndex = 0; rowIndex < this.materiasPrimaForm.value.length; rowIndex++) {
const { valor, quantidade } = this.materiasPrimaForm.value[rowIndex];
this.subTotalMateriaPrima[rowIndex] = valor * quantidade;
}
}
In layout:
<td mat-cell *matCellDef="let materiaprima;let rowIndex=index;"> {{subTotalMateriaPrima[rowIndex] | currency:'BRL'}} </td>
you better create a title and set it onChange from the form. This way it will call your function often.
– Eduardo Vargas
I did this to calculate the sum of the raw materials. How can I do this for the line?
subtotalMateriaPrima[__id__] = valor
?– lcssanches
@Eduardovargas in this way also worked. And really, the way that had made the function was called 8 times, while the with the property was called only once.
– lcssanches