1

I have the following directive which uses two lists: listGroup and listAll. They are JSON objects like this:

$scope.usersGroup = [
  { id: '1', name: 'User 1' },
  { id: '2', name: 'User 2' },
  { id: '3', name: 'User 3' }
]

I want to add a class to each item if item is already in userGroup:

JS:

  .directive('tableList', function() {
    return {
      restrict: 'EA',
      template: '<--SOME CODE' + 
        '<tr class="ADD CLASS IF ITEM IS IN LISTGROUP" ng-repeat="item in listAll">' +
          '<th scope="row"><input type="checkbox" value="0" ng-model="item.selected"></th>' + 
          '<td><a href="#/groups/{{item.id}}">{{item.name}}</a></td>
        'MORE CODE-->',
      scope: {
        listName: "@",
        listGroup: "=",
        listAll: "=",
        submit: "&"
      },
      controller: function() {},
      link: function(scope, elem, attr, ctrl) {
        scope.checkAll = function() {
          if (scope.selectedAll) {
            scope.selectedAll = false
          } else {
            scope.selectedAll = true
          }
          angular.forEach(scope.listAll, function(item) {
            item.selected = scope.selectedAll
          })
        }
      }
    };
  })

HTML:

  <table-list
list-name="users"
list-group="usersGroup"
list-all="usersAll"
submit="submit()">
  </table-list

What's the AngularJS-way of doing this?

alexchenco
  • 53,565
  • 76
  • 241
  • 413
  • Possible duplicate of [using ng-repeat and ng-class on rows inside a table](http://stackoverflow.com/questions/15410652/using-ng-repeat-and-ng-class-on-rows-inside-a-table) – krl Jan 06 '16 at 09:56
  • Use `ng-class` on `tr` tag – krl Jan 06 '16 at 09:57

3 Answers3

1

I don't think there is a specific angular way. I would simply set a flag in listAll

link: function(scope, elem, attr, ctrl) {
        ...
        var listGroupIds = {};
        angular.forEach(scope.listGroup, function(item) {
          listGroupIds[item.id] = true;
        });
        angular.forEach(scope.listAll, function(item) {
          item.inListGroup = item.id in listGroupIds;
        });

Then in the template

template: '<--SOME CODE' + 
        '<tr ng-class="{'myClass': item.inListGroup}" ng-repeat="item in listAll">' +
          '<th scope="row"><input type="checkbox" value="0" ng-model="item.selected"></th>' + 
          '<td><a href="#/groups/{{item.id}}">{{item.name}}</a></td>
        'MORE CODE-->',
Simone Zandara
  • 9,401
  • 2
  • 19
  • 26
1

Use ng-class in tr tag:

<tr ng-repeat="item in listAll" ng-class="getRowClass(item)">
krl
  • 5,087
  • 4
  • 36
  • 53
0

You don't even need to write anything in controller or link function. Just use Array.prototype.indexOf method, super fast and convenient:

<tr class="{selected: listGroup.indexOf(item) > -1}" ng-repeat="item in listAll">

Important: listGroup must contain references to the same objects listAll has (which is how it should be anyway).

dfsq
  • 191,768
  • 25
  • 236
  • 258
  • that assumes that the same element is contained both in listGroup and listAll, the comparison could be on the id only. Moreover this might not scale with the number of elements, could be worth pointing that out. – Simone Zandara Jan 06 '16 at 10:01
  • @SimoneZandara Of course, listGroup should have same references. But I believe this is how it should be in 90% of cases. Not, sure what you mean by "not scale" though - scales perfectly. – dfsq Jan 06 '16 at 10:04
  • it's an O(N^2) approach, i meant this – Simone Zandara Jan 06 '16 at 10:05