Search code examples
angularangular-servicesangular-reactive-formsangular-forms

Get Grand Total From Rows Total


I'm confused on how would i select all total on all rows and automatically calculate it in the grand total? Like what i did in the total, i just get the values of price and quantity but how can select all so i can able to calculate automatically. How can i add the grand total of all total row?

html

<div class="card-block" formArrayName="rows">
  <table class="table table-bordered table-striped">
    <thead>
      <tr>
        <th>Material SKU</th>
        <th>Quantity</th>
        <th>Price</th>
        <th>Total</th>
        <th>Action</th>
      </tr>
    </thead>
    <tbody>
      <tr *ngFor="let row of myForm.controls.rows.controls; let i = index" [formGroupName]="i">
        <td>
          <select formControlName="material_id" class="col-md-10" required>
            <option *ngFor="let mat_order of mat_orders" [ngValue]="mat_order.material_id">
              {{ mat_order.mat_name }}
            </option>
          </select>
        </td>
        <td><input type="number" class="col-md-6" formControlName="quantity" required></td>
        <td><input type="number" class="col-md-6" formControlName="price" required></td>
        <td><input type="number" class="col-md-6" formControlName="total"  [ngModel] ="row.get('quantity').value * row.get('price').value" required></td>
        <td>
          <button type="button" class="btn btn-sm btn-danger" (click)="onDeleteRow(i)"><i class="fa fa-trash-o" aria-hidden="true"></i> Remove</button>
        </td>
      </tr>

    </tbody>
  </table>
  <div class="float-right">
    Grand Total:  <input type="number" class="col-md-5" formControlName="grand_total" required disabled>
  </div>
  <button type="button" class="btn btn-sm btn-primary float-left" (click)="initGroup()"><i class="fa fa-plus-circle" aria-hidden="true"></i>  Add Row</button>
</div>

ts

 constructor(private fb: FormBuilder) { 

    this.myForm = this.fb.group({
      rows: this.fb.array([])
    })

  }


initGroup() {
    let rows = this.myForm.get('rows') as FormArray;
    rows.push(this.fb.group({
      material_id: [''],
      quantity: [''],
      price: [''],
      total: ['']
    }))

  }

Solution

  • You can simply use Array map and reduce here.

    Grand Total:  <input type="number" class="col-md-5" formControlName="grand_total" [ngModel]="calculateTotal()" required disabled>
    

    In your ts file:

    calculateTotal():number{
        let rows = this.myForm.get('rows') as FormArray;
       return rows.controls.
          map((row)=> row.get('quantity').value * row.get('price').value). //calcualte each amount
           reduce((sum,amount) => sum + amount,0); //find sum
    }