1

I've simulated my problem in this fiddle.

I have this HTML:

<table ng-app='Payments'>
    <thead>
        <tr>
            <th>Date</th>   <th>Cash</th>   <th>Total</th>
        </tr>
    </thead>
    <tbody ng-controller='paymentsController'>
        <tr ng-repeat='pay in payments | orderBy : "date"'>
            <td>{{pay.date}}</td>
            <td><input type="textbox" ng-model="pay.cash"/></td>
            <td></td>
        </tr>
    </tbody>
</table

And this JS:

var appModule = angular.module('Payments', []);

appModule.controller('paymentsController', function($scope) {
    $scope.payments = [
        {'id' : '1', 'date' : '2015-07-27', 'cash' : '149.98'},
        {'id' : '2', 'date' : '2015-07-29', 'cash' : '70.00'},
        {'id' : '3', 'date' : '2015-07-27', 'cash' : '129.99'},
        {'id' : '4', 'date' : '2015-07-28', 'cash' : '349.90'}
    ];
});

How do I fill the third column with Angular?

The third column should be initially:

149.98       // due to   0.00 + 149.98
279.97       // due to 149.98 + 129.99
629.87       // due to 279.97 + 349.90
699.87       // due to 629.87 +  70.00

Then, ng-model should do the trick to update them automatically later.

Thanks in advance.

2 Answers 2

2

You could add a function to the scope to calculate the total at that index. You have to keep in mind that you are using order by which means you should us the as syntax to calculate the value from the ordered list.

CalculatePay function:

$scope.calculatePay = function(index) {
  var sum = 0;
  for(var i = 0; i <= index; i++) {
    sum += parseFloat($scope.orderedList[i].cash);
  }
  return sum;
};

html:

<table ng-app='Payments'>
    <thead>
        <tr>
            <th>Date</th>   <th>Cash</th>   <th>Total</th>
        </tr>
    </thead>
    <tbody ng-controller='paymentsController'>
        <tr ng-repeat="pay in payments | orderBy: 'date' as orderedList track by pay.id">
            <td>{{pay.date}}</td>
            <td><input type="textbox" ng-model="pay.cash"/></td>
            <td>{{calculatePay($index)}}</td>
        </tr>
    </tbody>
</table>

track by is also helpful if the id is truely unique

Example: http://plnkr.co/edit/igBGY1h5RIKMNkncxhp6?p=preview

Sign up to request clarification or add additional context in comments.

1 Comment

I was struggling here.. I updated my angular to the same you used in your plunker.. now, your answer works fine.. thank you !!
2

You would need to handle sorting in code, as the orderBy in ng-repeat creates a new list used for the display, and doesn't modify the original list. This would mean that the indexes of items in the display list don't match up with that in the original list. You'll also need a watcher on the payments collection to automatically update the totals at each position.

Something like

$scope.$watch('payments', function(newPayments) {
    $scope.payments = orderByFilter($scope.payments, "date");
    $scope.total = 0;
    angular.forEach($scope.payments, function(payment) {
        $scope.total += parseFloat(payment.cash);
        payment.total = $scope.total;
    });
}, true);

Fiddle: http://jsfiddle.net/29mh8bfe/4/

4 Comments

I would avoid adding a deep watch to the scope, this can affect performance in an application with a lot of watchers.
I don't know why.. but for me it shows orderByFilter is undefined
You need to inject orderByFilter into the controller.
Oh.. I see, it was that I copied from the answer, not the fiddle.. +1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.