Question

I have an array of Requests that "are made up of" an array of tasks. I need the duration field of each Request to equal the sum of the Duration field of the tasks that are associated with each Request and able to react to changes in the tasks.

I have tried angular.forEach and even just a javascript for loop. I think there is an Angular simple concept that I am missing to do this. Please tell me how I can do this.

I started here but realized that I had no way to filter the Tasks by the applicable Req_ID before adding them together -- I need a WHERE clause (LOL):

$scope.Requests.Duration = function($scope.Requests.id){
   return angular.forEach($scope.Tasks, function($scope.Tasks.Duration){
     // get the right tasks
   });
 }

Here is my controller:

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

app.controller('MainController', function($scope){

 $scope.selRequest = 1;

  $scope.Requests = [
    {id: 1, Title: 'Make a web page', Duration: 0, TOR: 0},
    {id: 2, Title: 'Make a web service', Duration: 0, TOR: 0},
    {id: 3, Title: 'Make a web application', Duration: 0, TOR: 0}  
  ];
  $scope.Tasks = [
    {id: 1, Req_ID: 1, Title: 'Graphic Prototype', Duration: .5, TOT: 0},
    {id: 2, Req_ID: 1, Title: 'Develop CSS', Duration: 3.5, TOT: 0},
    {id: 3, Req_ID: 1, Title: 'Code in Editor', Duration: 6, TOT: 0},
    {id: 4, Req_ID: 2, Title: 'Write Stored Procedures', Duration: 10, TOT: 0},
    {id: 5, Req_ID: 2, Title: 'Build API', Duration: 6, TOT: 0},
    {id: 6, Req_ID: 3, Title: 'Build Static App', Duration: 12, TOT: 0},
    {id: 7, Req_ID: 3, Title: 'Build Data Store', Duration: 4, TOT: 0},
    {id: 8, Req_ID: 3, Title: 'Add Functionality to Static App', Duration: 6, TOT: 0}  
  ];

  $scope.showKids = function(id){
    $scope.selRequest = id;
  } // end fn

}); // end MainController

I created a simple view to show related tasks to test the assignment of Requests Duration.

<!DOCTYPE html>
<html ng-app="app">

  <head>
    <link data-require="bootstrap-css@3.1.1" data-semver="3.1.1" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
    <script data-require="jquery@*" data-semver="2.0.3" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
    <script data-require="angular.js@*" data-semver="1.3.0-beta.5" src="https://code.angularjs.org/1.3.0-beta.5/angular.js"></script>
    <script data-require="bootstrap@*" data-semver="3.1.1" src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
    <script data-require="ui-bootstrap@*" data-semver="0.10.0" src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.10.0.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body ng-controller="MainController">
    <table class="table table-striped">
    <tr>
      <th>ID</th>
      <th>Title</th>
      <th>Duration</th>
      <th>TOR</th>
    </tr>
      <tr ng-repeat="req in Requests">
        <td>{{req.id}}</td>
        <td><a href="" ng-click="showKids(req.id)">{{req.Title}}</a></td>
        <td>{{req.Duration}}</td>
        <td>{{req.TOR}}</td>
      </tr>
    </table>
    <br /><br />
    <table class="table table-striped">
    <tr>
      <th>ID</th>
      <th>REQ</th>
      <th>Title</th>
      <th>Duration</th>
      <th>TOT</th>
    </tr>
      <tr ng-repeat="t in Tasks | filter: {Req_ID: selRequest}">
        <td>{{t.id}}</td>
        <td>{{t.Req_ID}}</td>
        <td>{{t.Title}}</td>
        <td><input type="text" style="width:50px;" name="Duration" data-ng-model="t.Duration" /></td>
        <td><input type="text" style="width:50px;" name="TOT" data-ng-model="t.TOT" /></td>
      </tr>
    </table>
  </body>

</html>

A Plunkr is here without the math functionality

Was it helpful?

Solution

I made a few assumptions of what you are looking for. Basically the key here is you can add an ng-change to the form variables that you want to track, then call a function to recompute the totals when that change event runs. In steps that looks like:

Add ng-change to relevant fields

<td><input type="text" style="width:50px;" name="Duration" data-ng-model="t.Duration" data-ng-change="updateDuration(t.Req_ID)"/></td>
<td><input type="text" style="width:50px;" name="TOT" data-ng-model="t.TOT" data-ng-change="updateTotals(t.Req_ID)" /></td>

Add the routines to update totals

I am only showing one for brevity. They are both in the plunker below but are basically identical.

$scope.updateDuration = function (sumId) {
  var sum = 0;
  for (var idx = 0; idx < $scope.Tasks.length; idx++) {
    if ($scope.Tasks[idx].Req_ID === sumId){
      sum += $scope.Tasks[idx].Duration * 1; // simple cast as int
    }
  }

  for (idx = 0; idx < $scope.Requests.length; idx++) {
    if ($scope.Requests[idx].id == sumId) {
      $scope.Requests[idx].Duration = sum;
    }
  }
};

See The Updated Plunker

http://plnkr.co/edit/UqWoxojnXCiJHdpYBcj5?p=info

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top