Cethy
Cethy

Reputation: 551

Sorting only certain arrays in nested ngRepeat

I currently have a nested ngRepeat, where the inner loop iterates over a collection of items from its parent. An excerpt:

<div ng-repeat="person in persons">

 (Irrelevant code here.)

  <table>
    <tr>
      <th ng-click="setItemOrder('name')">Item name</th>
      <th ng-click="setItemOrder('number')">Item number</th>
    </tr>
    <tr ng-repeat="item in person.items | orderBy:itemOrder">
      <td>{{item.name}}
      <td>{{item.number}}
    </tr>
  </table>

</div>

By clicking the table headers, I set the itemOrder-property in my controller to the name of the property I want orderBy to use:

$scope.setItemOrder = function(order){
  $scope.itemOrder = order;
}

This all works fine, except that if I click the headers in one person-div, the item-tables in all person-divs get sorted on that property.

Is there a way to make ngRepeat only apply orderBy to entries that match a certain criteria - for instance a certain index? Or should I use a different approach?

Upvotes: 1

Views: 459

Answers (3)

VijayVishnu
VijayVishnu

Reputation: 537

angular.module('test', []).controller('testController', function($scope) {
 $scope.ordersort=true;
  $scope.orderfield='number';
  $scope.persons = {
    "items": [{
      "name": 'test',
      "number": 2
    }, {
      "name": 'test1',
      "number": 1
    }],
  
    "item1": [{
      "name": 'test3',
      "number": 5
    }, {
      "name": 'test4',
      "number": 4
    }]
  };

  $scope.setItemOrder = function(person, order) {
     $scope.orderfield=order;
    person.itemOrder = order;
    $scope.ordersort= !$scope.ordersort;
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<form ng-app="test" ng-controller="testController">
 
  <div ng-repeat="person in persons">
    
    <table>
      <tr>
        <th ng-click="setItemOrder(person,'name')">Item name</th>
        <th ng-click="setItemOrder(person,'number')">Item number</th>
      </tr>
      <tr ng-repeat="item in person | orderBy:orderfield:ordersort">
        <td>{{item.name}}
          <td>{{item.number}}
      </tr>
    </table>

  </div>

I have modified your example. In this example table sorting is working perfectly. But It is not sorted the particular table when I click on that table header. Anyway to sort columns by specific table?

angular.module('test', []).controller('testController', function($scope) {

  $scope.persons = [{
    items: [{
      name: 'test',
      number: 2
    }, {
      name: 'test1',
      number: 1
    }]
  }, {
    items: [{
      name: 'test3',
      number: 5
    }, {
      name: 'test4',
      number: 4
    }]
  }];

  $scope.setItemOrder = function(person, order) {
    person.itemOrder = order;
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<form ng-app="test" ng-controller="testController">
  <div ng-repeat="person in persons">
    <table>
      <tr>
        <th ng-click="setItemOrder(person,'name')">Item name</th>
        <th ng-click="setItemOrder(person,'number')">Item number</th>
      </tr>
      <tr ng-repeat="item in person.items | orderBy:person.itemOrder">
        <td>{{item.name}}
          <td>{{item.number}}
      </tr>
    </table>

  </div>

Upvotes: 0

T J
T J

Reputation: 43156

Try setting the property to respective person instance as follows:

angular.module('test', []).controller('testController', function($scope) {

  $scope.persons = [{
    items: [{
      name: 'test',
      number: 2
    }, {
      name: 'test1',
      number: 1
    }]
  }, {
    items: [{
      name: 'test3',
      number: 5
    }, {
      name: 'test4',
      number: 4
    }]
  }];

  $scope.setItemOrder = function(person, order) {
    person.itemOrder = order;
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<form ng-app="test" ng-controller="testController">
  <div ng-repeat="person in persons">
    <table>
      <tr>
        <th ng-click="setItemOrder(person,'name')">Item name</th>
        <th ng-click="setItemOrder(person,'number')">Item number</th>
      </tr>
      <tr ng-repeat="item in person.items | orderBy:person.itemOrder">
        <td>{{item.name}}
          <td>{{item.number}}
      </tr>
    </table>

  </div>

Upvotes: 3

Reverend Sfinks
Reverend Sfinks

Reputation: 161

You could add a ordering variable for each person and extend setItemOrder with the person object. Then you can call:

setItemOrder(person, 'name');

and then use it in the ngRepeat:

orderBy:person.itemOrder

Upvotes: 1

Related Questions