Search code examples
angularjsangularjs-ng-repeat

How to create subtotals in a ng-repeat in Angular JS


I'm just learning AngularJS and need to create the report below. I have all the detail lines working well but have no idea how to create the subtotal lines.

Detail lines...

<tr data-ng-repeat-start="t in testReferrers">
    <td>{{t.ReferrerName}}</td>
    <td>{{t.AddressLine1}}}</td>
    <td>{{t.DatePlaced  | date:'MM/dd/yyyy'}}</td>
    <td>{{t.InvoiceNumber }}</td>
    <td>{{t.InvoiceAmountLessDiscount | currency : $ : 2 }}</td>
</tr>

My first attempt at subtotal line, but I don't know how to calculate {{subTotal}} and how to control when this row shows up. I need a grouping and group footer capability but don't know how to do that in AngularJS. I was going to use JQuery to find the subTotalRow and either show or hide...

<tr id="subtotalRow" data-ng-repeat-end style="display:none">
    <td colspan=3></td>
    <td style="border-top: solid 1px #000000">Total:</td>
    <td style="border-top: solid 1px #000000">{{subTotal | currency : $ : 2 }}</td>
</tr>

Desired output...

enter image description here


Solution

  • angular.module('app', []).controller('ctrl', function($scope){
      $scope.data = [
        {Referrer: 'Henry', Amount: 20, Location: 'NY'},
        {Referrer: 'Tom', Amount: 10, Location: 'London'},    
        {Referrer: 'Sam', Amount: 10, Location: 'Paris'},
        {Referrer: 'Henry', Amount: 10, Location: 'NY'},
        {Referrer: 'Tom', Amount: 20, Location: 'London'},    
        {Referrer: 'Henry', Amount: 30, Location: 'NY'}
      ];
      $scope.sum = function(name){
        return $scope.data.filter(function(x) { return x.Referrer == name; })
          .map(function(x) { return x.Amount; }).reduce(function(a, b) { return a + b; });
      }
    })
    table, th, td {
      border: 1px solid black;
      border-collapse: collapse;
    }
    .totalRow{
      border-style: solid;  
    }
    .total{  
      text-align: right;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js">
    </script>
    
    <div ng-app='app' ng-controller='ctrl'>
      <table>
        <thead>
          <tr>
            <th>Referrer</th>
            <th>Location</th>        
            <th>Amount</th>
          </tr>
        </thead>
        <tbody>
          <tr ng-init='next = $index + 1' ng-repeat-start='item in dataSorted = (data | orderBy : "Referrer")'>
            <td>{{item.Referrer}}</td>
            <td>{{item.Location}}</td>
            <td>{{item.Amount}}</td>
          </tr>
          <tr class='totalRow' ng-repeat-end ng-if='!dataSorted[next] || (dataSorted[next].Referrer != item.Referrer)'>
            <td colspan='2' class='total'>Total:</td>        
            <td>{{sum(item.Referrer)}}</td>
          </tr>
        </tbody>
      </table>
    </div>