Reputation: 4381
I'll preface this by saying I am very new to AngularJS so forgive me if my mindset is far off base. I am writing a very simple single page reporting app using AngularJS, the meat and potatoes is of course using the angular templating system to generate the reports themselves. I have many many reports that I am converting over from a Jinja-like syntax and I'm having a hard time replicating any kind of counter or running tabulation functionality.
Ex.
{% set count = 1 %}
{% for i in p %}
{{ count }}
{% set count = count + 1 %}
{% endfor %}
In my controller I have defined a variable like $scope.total = 0;
which I am then able to access inside of the template without issue. What I can't quite figure out is how to increment this total
from within an ng-repeat
element. I would imagine this would look something like -
<ul>
<li ng-repeat="foo in bar">
{{ foo.baz }} - {{ total = total + foo.baz }}
</li>
</ul>
<div> {{ total }} </div>
This obviously doesn't work, nor does something like {{ total + foo.baz}}
, thanks in advance for any advice.
Upvotes: 13
Views: 59415
Reputation: 20596
I needed running total rather that plain total, so I've added upon what @TimStewart left. Here the code:
app.filter("runningTotal", function () {
return function(items, field, index) {
var total = 0, i = 0;
for (i = 0; i < index+1; i++) {
total += items[i][field];
}
return total;
};
});
To use it in column you just do:
<div>Total price: {{items | runningTotal:'price':$index}}</div>
Upvotes: 5
Reputation: 759
If all you want is a counter (as per your first code example), take a look at $index which contains the current (0 based) index within the containing ngRepeat. And then just display the array length for the total.
<ul>
<li ng-repeat="item in items">
Item number: {{$index + 1}}
</li>
</ul>
<div>{{items.length}} Items</div>
If you want a total of a particular field in your repeated items, say price, you could do this with a filter, as follows.
<ul>
<li ng-repeat="item in items">
Price: {{item.price}}
</li>
</ul>
<div>Total Price: {{items | totalPrice}}</div>
And the filter function:
app.filter("totalPrice", function() {
return function(items) {
var total = 0, i = 0;
for (i = 0; i < items.length; i++) total += items[i].price;
return total;
}
});
Or, for improved reusability, a generic total filter function:
app.filter("total", function() {
return function(items, field) {
var total = 0, i = 0;
for (i = 0; i < items.length; i++) total += items[i][field];
return total;
}
});
Which would be used like:
<div>Total price: {{items | total:'price'}}</div>
Upvotes: 33
Reputation: 40327
I'm not sure I totally understand the question, but are just needing to display the total number in the object you're iterating over? Just set $scope.total
to the length of your array (bar
in your example above). So, $scope.total = $scope.bar.length;
If you're wanting the total of all the foo.baz
properties, you just need to calculate that in your controller.
$scope.total = 0;
angular.forEach($scope.bar, function(foo) {
$scope.total += foo.baz;
});
Upvotes: 0