HurnsMobile
HurnsMobile

Reputation: 4381

Increment A Variable In AngularJS Template

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

Answers (3)

nikib3ro
nikib3ro

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

Tim Stewart
Tim Stewart

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

dnc253
dnc253

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

Related Questions