Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS Dynamic sum of list

I am using angularJS ontop of my application.

I have a basic example of a controller:

function OrderListCtrl($scope, $http) {
  $http.get('/static/angular/app/phones/van1.json').success(function(data) {
    $scope.van1 = data;
  });

  $http.get('/static/angular/app/phones/van2.json').success(function(data) {
    $scope.van2 = data;
  });

}

And a sample JSON entry

{
        "id": "3", 
        "custName": "Mrs Smith",
        "accountNumber": "416", 
        "orderNumber": "12348", 
        "orderWeight": "120.20"
}, 

My html looks like this:

<div id=1>
<h1>Van 1 - Total Weight = XXX </h1>
<ul class="sortdrag">
    <li ng-repeat="van1 in van1" id="[[ van1.id ]]">
      [[van1.custName]] [[van1.accountNumber]] [[van1.orderWeight]]

    </li>
</ul>
</div>

Now, I want to get the total weight for every li item in the ul.

This WOULD be easy if the lists where static, however the lists are using jQuery-ui and I have multiple lists where the li items are dragged and dropped between each list. My question is, how can I have the XXX dynamically update to the value of all weights in each li in the ul, or more to the question can this even be done?

I dont really want to use an onDrop event as this will not work on the pre-populated lists, so ideally I would like to use code that takes its values from all van1.orderWeight values in the ul.

Any suggestions on the best way to approach this would be very much appreciated! And before anyone asks im using [[ and ]] as opposed to {{ and }} because I am using jinja2 templates.

UPDATE:

Ok to after reading the answer below have amended the original controller to:

function OrderListCtrl($scope, $http) {
  $http.get('/static/angular/app/phones/van1.json').success(function(data) {
    $scope.van1 = data;
    // This part is easy, calcuate the sum of all weights from the JSON data
    $scope.sumV1 = _.reduce(_.pluck($scope.van1, 'orderWeight'), function (m, w) {return m + w}, 0);
  });

  $scope.getVan1Weight = function(){
    // here I try and write a function to calculate the dynamic weight
    // of a van, which will update when items get dropped in/out of the ul
     _.reduce(_.pluck($scope.van1, 'orderWeight'), function (m, w) {return m + w}, 0);
    }

And my template

<div id="app" ng-controller="OrderListCtrl">

<div id=1>
<h1>Van 1 - Total Weight = [[getVan1Weight()]]  
Starting Weight - [[sumV1]]</h1>
<ul class="sortdrag">
    <li ng-repeat="van1 in van1" id="[[ van1.id ]]">
      [[van1.custName]] [[van1.accountNumber]] [[van1.orderWeight]]

    </li>
</ul>
</div>

Now im using the underscorejs libary to help perform the calculations, but I can only seem to get this to work using the initial data, and not to update when new orders are dragged in from another ul

like image 679
Crooksey Avatar asked Dec 14 '12 15:12

Crooksey


2 Answers

That is pretty each to achieve in Angular. You have to write a function in your controller that does the calculation for you and interpolate that function in your view. Something like

<div id=1>
<h1>Van 1 - Total Weight = [[getVanWeight()]] </h1>
<ul class="sortdrag">
    <li ng-repeat="van1 in vans" id="[[ van1.id ]]">
      [[van1.custName]] [[van1.accountNumber]] [[van1.orderWeight]]

    </li>
</ul>
</div>

Inside your controller you do :

$scope.getVanWeight = function(){
// write your logic for calculating van weight here.

}
like image 100
ganaraj Avatar answered Dec 01 '22 04:12

ganaraj


Thanks to @ganaraj I used the guide found at

http://www.smartjava.org/content/drag-and-drop-angularjs-using-jquery-ui

I also replaced my underscore code with pure angularjs code

$scope.getVan1Weight = function(){
     var sum = 0;
     for( t=0; t < $scope.van1.length; t++) { sum += $scope.van1[t].orderWeight }
     return sum.toFixed(2);;
}

At the beginning of my controller I also defined an empty array (to get overwritten later)

// Define an empty array
$scope.van1 = [];

As this stops any errors producing as the $http get takes a while to load and when you load a browser window the .length returns an error, so if you define an empty array it stops any errors. I could have tested to see if an array was valid and put some if clauses in, but my angularjs knowledge is very limited so this solution worked best for me.

like image 43
Crooksey Avatar answered Dec 01 '22 05:12

Crooksey