0

It maybe sounds weird but based in the following table I need to sum all rows by using jQuery. I'm using angularjs to list all users but I need to get each row with jQuery and then show the sum of all them.

The only problem is I don't know how to get the value of each row in order to make the operation.

HTML

<div data-ng-app="app" data-ng-controller="controllerApp">
<table border="1">
    <thead>
        <tr>
            <th>Name</th>
            <th>Age</th>
        </tr>
   </thead>
   <tbody>
         <tr data-ng-repeat="user in users">
             <td>{{user.name}}</td> 
             <td class="sum">{{user.age}}</td>
         </tr>
   </tbody>
   <tfoot>
         <tr>
              <td><strong>Sum</strong></td>
              <td></td>
         </tr>
   </tfoot>
</table>
</div>

Javascript

$(function(){
function tally (selector) {
    $(selector).each(function () {
        var total = 0,
            column = $(this).siblings(selector).andSelf().index(this);
        $(this).parents().prevUntil(':has(' + selector + ')').each(function () {
            total += parseFloat($('td.sum:eq(' + column + ')', this).html()) || 0;
        })
        $(this).html(total);
    });
}
tally('td.total');
});

Angularjs

var app = angular.module("app", []);
app.controller("controllerApp", function($scope){
    $scope.users = [
        {name: "Marie", age: 24},
        {name: "Andy", age: 26},
        {name: "Peter", age: 21},
        {name: "Elizabeth", age: 23},
        {name: "Frank", age: 27},
        {name: "Claire", age: 25}
    ]
});
wilson
  • 627
  • 2
  • 11
  • 24

2 Answers2

1

The best solution is not to do any modification outside of the angulars scope
Read this: "Thinking in AngularJS" if I have a jQuery background?

But if you really must access it from outside of angular then this is the correct way to do it:

$('table').scope().users.reduce((a,b) => a+b.age, 0)

I would do it something more like this:

$scope.users = [
    {name: "Marie", age: 24},
    {name: "Andy", age: 26},
    {name: "Peter", age: 21},
    {name: "Elizabeth", age: 23},
    {name: "Frank", age: 27},
    {name: "Claire", age: 25}
]

$scope.totally = $scope.users.reduce((a,b) => a+b.age, 0)
// <td class="total">{{totally}}</td>
Community
  • 1
  • 1
Endless
  • 34,080
  • 13
  • 108
  • 131
1

After deciding that it's more trouble than it's worth to figure out how to execute jQuery after Angular is finished rendering, the following is my solution using just Angular and some LoDash.

var app = angular.module("app", []);
app.controller("controllerApp", function($scope){
    $scope.users = [
        {name: "Marie", age: 24},
        {name: "Andy", age: 26},
        {name: "Peter", age: 21},
        {name: "Elizabeth", age: 23},
        {name: "Frank", age: 27},
        {name: "Claire", age: 25}
    ];
    $scope.sum = _.reduce($scope.users, function(sum, n) {
      return sum + n.age;
    }, 0);
});
<script src="https://cdn.jsdelivr.net/lodash/4.16.6/lodash.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div data-ng-app="app" data-ng-controller="controllerApp">
<table border="1">
    <thead>
        <tr>
            <th>Name</th>
            <th>Age</th>
        </tr>
   </thead>
   <tbody>
         <tr data-ng-repeat="user in users">
             <td>{{user.name}}</td> 
             <td class="sum" tally>{{user.age}}</td>
         </tr>
   </tbody>
   <tfoot>
         <tr>
              <td><strong>Sum</strong></td>
              <td>{{ sum }}</td>
         </tr>
   </tfoot>
</table>
</div>
Samuel Reid
  • 1,756
  • 12
  • 22
  • You don't need lodash for just this simple thing... javascript has reduce built in ...in decent browsers – Endless Nov 10 '16 at 21:16
  • Yea you're right, you don't "need" it cause javascript has it built in. I wan't aware that javascript has it built in until I saw your answer. In my brain I went "oh that'll need some collection operation, so LoDash!" – Samuel Reid Nov 10 '16 at 21:20