Count items with value in angularjs scope per row

Andrew

I have a site that uses angular ng-repeat to show data from my scope and all works fine, but I need to count items to show a percentage complete, but can't seem to find a solution online. I am still very new to Angular and JS, so apologies if its an easy solution.

The below is a simplified and generalized example of what I am looking to achieve:

$scope.devices = [
{Detail_A:'ShowA1',Detail_B:'ShowB1',Status_A:'',Status_B:'OK',Status_C:'',Status_D:'OK',ENG_A:'OK',ENG_B:'OK',ENG_C:'OK'},
{Detail_A:'ShowA2',Detail_B:'ShowB2',Status_A:'OK',Status_B:'OK',Status_C:'OK',Status_D:'OK',ENG_A:'',ENG_B:'',ENG_C:''},
{Detail_A:'ShowA3',Detail_B:'ShowB3',Status_A:'OK',Status_B:'OK',Status_C:'OK',Status_D:'OK',ENG_A:'OK',ENG_B:'OK',ENG_C:'OK'}
]

I would like to show a percentage of items that state 'OK' within the two pre-fixed items: Status_* and ENG_*. This can be either by having to loop each one or better to be able to use the prefix to calculate over a group.

<div ng-repeat="device in devices">
<div class="col-md-2">{{StatusPercentComplete}}</div>
<div class="col-md-1">{{ENGPercentComplete}}</div>
<div class="col-md-1">{{device.Detail_A}}</div>
<div class="col-md-1">{{device.Detail_B}}</div>
</div>

So for row 1, StatusPercentComplete would be 50% and ENGPercentComplete would be 100%.

Any direction would be much appreciated.

Bennett Adams

I just put together a little proof of concept with a refactored percent calculation function, so that you can reuse it for either Status_x or ENG_x keys. You can also use a percentage filter on the bound html element if you don't want to construct the number% string in the controller function.

Note: this solution uses lodash for the filtering (which tends to be a standard dependency in angular applications, but just so you know...)

angular.module('app', [])
  .controller('MainCtrl', function() {
    var ctrl = this;
    
    ctrl.devices = [
      {Detail_A:'ShowA1',Detail_B:'ShowB1',Status_A:'',Status_B:'OK',Status_C:'',Status_D:'OK',ENG_A:'OK',ENG_B:'OK',ENG_C:'OK'},
      {Detail_A:'ShowA2',Detail_B:'ShowB2',Status_A:'OK',Status_B:'OK',Status_C:'OK',Status_D:'OK',ENG_A:'',ENG_B:'',ENG_C:''},
      {Detail_A:'ShowA3',Detail_B:'ShowB3',Status_A:'OK',Status_B:'OK',Status_C:'OK',Status_D:'OK',ENG_A:'OK',ENG_B:'OK',ENG_C:'OK'}
    ];
    
    ctrl.percentComplete = function(keyString, item) {
      var statuses = _.filter(_.keys(item), function(key) {
        return key.substring(0, keyString.length) === keyString;
      });
      var okStatuses = _.filter(statuses, function(status) {
        return item[status] === 'OK';
      });
        
      return okStatuses.length / statuses.length * 100 + '%';
    };

  });
<!DOCTYPE html>
<html ng-app="app">

  <head>
    <script data-require="[email protected]" data-semver="1.5.0" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script>
    <script data-require="[email protected]" data-semver="4.6.1" src="https://cdn.jsdelivr.net/lodash/4.6.1/lodash.js"></script>
    <link data-require="[email protected]" data-semver="3.3.6" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" />
    <script src="script.js"></script>
  </head>

  <body ng-controller="MainCtrl as main">
    <div ng-repeat="device in main.devices" class="row">
      <div class="col-md-2 col-sm-2 col-xs-2">{{main.percentComplete('Status', device)}}</div>
      <div class="col-md-1 col-sm-1 col-xs-2">{{main.percentComplete('ENG', device)}}</div>
      <div class="col-md-1 col-sm-1 col-xs-2">{{device.Detail_A}}</div>
      <div class="col-md-1 col-sm-1 col-xs-2">{{device.Detail_B}}</div>
    </div>
  </body>

</html>

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related