0

I have a large number of items loaded into a "tickets" object and I am trying to put several tables on the page -- one for each division so I am filtering the tickets object. I can get the total number of tickets with .length but I also need the number of tickets in each division (so that I can use ng-show to show "No Tickets Found!" if there are no tickets in a specific department.

I have a plunkr that is "almost" working. As you can see, there is 1 HR ticket but the "No Tickets Found!" is still showing

Here's the HTML:

<h3>Human Resources</h3>
    <table class="table table-striped">
      <tbody>
        <tr>
          <th>ID</th>
          <th>Title</th>
          <th>Department</th>
          <th>Status</th>
        </tr>
        <tr ng-repeat="t in tickets | filter:{ Department:'HR' }">
          <td>{{t.ID}}</td>
          <td>{{t.Title}}</td>
          <td>{{t.Department}}</td>
          <td>{{t.Status}}</td>
        </tr>
        <tr ng-show="countDepartment('HR') == 0">
          <td colspan="4"><b>No Tickets Found!</b></td>
        </tr>
      </tbody>
    </table>
    Human Resources: {{countDepartment('HR')}}
    <br />
    Total: {{tickets.length}}
    <br /><br />
    <hr />

And the JS file:

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

app.controller('MainController', function($scope){
  $scope.tickets = [
    {ID:'1', Title:'Kick Off Summer Campaign', Department:'Marketing', Status:'In Progress'},
    {ID:'2', Title:'Attend SummerConn', Department:'Sales', Status:'In Progress'},
    {ID:'3', Title:'Replace Ticketing Software', Department:'Support', Status:'In Progress'},
    {ID:'4', Title:'Read "The Salesman Within"', Department:'Sales', Status:'In Progress'},
    {ID:'5', Title:'Send Email 020', Department:'Marketing', Status:'In Progress'},
    {ID:'6', Title:'Refactor Training', Department:'Support', Status:'In Progress'},
    {ID:'7', Title:'Hire Call Center Coordinator', Department:'Support', Status:'In Progress'},
    {ID:'8', Title:'Send Email 044', Department:'Marketing', Status:'In Progress'},
    {ID:'9', Title:'Organize Convention Booths', Department:'Sales', Status:'In Progress'},
    {ID:'10', Title:'Send Email 123', Department:'Marketing', Status:'In Progress'},
    // Test entries for the 'Other'
    {ID:'11', Title:'Network is very slow', Department:'Other', Status:'Pending'},
    {ID:'12', Title:'Night Attendant has my extension wrong', Department:'HR', Status:'Pending'},
    {ID:'13', Title:'Idea: We could use Twitter to advertise', Department:'Other', Status:'Pending'},
  ];

  // Default checked state.
  $scope.Department = {
    Marketing: false,
    Sales: false,
    Support: false,
    Management: false
  };

  $scope.checked = function(val) {
    return $scope.Department[val.Department] || val.Department === 'Other';
  };

  $scope.countDepartment = function(val){
    var cnt = 0;
    for(c=0; c< $scope.tickets.length; c++){
      if($scope.tickets.Department == val){
        cnt = cnt+1;
      } // end if
    } // end for
    return cnt;
  };
}); // end main controller

2 Answers 2

1

You have a bug in your countDepartment function. It should be

$scope.countDepartment = function(val){
    var cnt = 0;
    for(c=0; c< $scope.tickets.length; c++){
      if($scope.tickets[c].Department == val){
        cnt = cnt+1;
      } // end if
    } // end for
    return cnt;
  };

Note that the 4th line should reference $scope.tickets[c].Department instead of $scope.tickets.Department.

Here's a slightly more compact and less error-prone way to write the same function:

$scope.countDepartment = function(val){
    var cnt = 0;
    angular.forEach($scope.tickets, function(value, key){
      if(value.Department == val)
        cnt++;
    });
    return cnt;
  };
Sign up to request clarification or add additional context in comments.

Comments

1

Going down another route, you can assign filtered results to a scope variable within the ng-repeat expression, as so...

<tr ng-repeat="t in HRtickets = (tickets | filter:{ Department:'HR' })">

This variable can then be used elsewhere in your html so you can change the ng-show expression simply to...

<tr ng-show="HRtickets.length == 0">

2 Comments

Is it possible to have more than one criterion in the filter this way? <tr ng-repeat="t in HRtickets = (tickets | filter:{ Department:'HR' && Requestor: loggedInUser.Title })">?
Yep sure can. You just need to supply the filter with a js object (ie comma separated rather than &&.) Take a look at the docs for ngFilter - you can even pass functions into it. All its doing is assigning the filtered array produced by the process within the brackets to the HRtickets var. You can therefore even chain filters... T in a = (b | filter:{c: d, e: f} | orderBy:g)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.