2

I am a mediocre in Angularjs and need help on the same. I have two tables with the same headers and data in the table may or may not be different. I need to sort the data based on the click on header. I am using same sort function for both tables. The problem is when I click on one header the data on both the tables are getting sorted. I need only that table to be sorted whose header I click. Please help.

Heres the code.

<body ng-app="orderByExample">
  <div ng-controller="ExampleController">
    <pre>Sorting predicate = {{predicate}}; reverse = {{reverse}}</pre>
    <hr/>
    <button ng-click="predicate=''">Set to unsorted</button>
    <table class="friend">
      <tr>
        <th>
          <button ng-click="order('name')">Name</button>
          <span ng-show="predicate === 'name'" ng-class="{reverse:reverse}"></span>
        </th>
        <th>
          <button ng-click="order('phone')">Phone Number</button>
          <span class="sortorder" ng-show="predicate === 'phone'" ng-class="{reverse:reverse}"></span>
        </th>
        <th>
          <button ng-click="order('age')">Age</button>
          <span class="sortorder" ng-show="predicate === 'age'" ng-class="{reverse:reverse}"></span>
        </th>
      </tr>
      <tr ng-repeat="friend in friends | orderBy:predicate:reverse">
        <td>{{friend.name}}</td>
        <td>{{friend.phone}}</td>
        <td>{{friend.age}}</td>
      </tr>
    </table>


      <table class="friend">
      <tr>
        <th>
          <button ng-click="order('name')">Name</button>
          <span ng-show="predicate === 'name'" ng-class="{reverse:reverse}"></span>
        </th>
        <th>
          <button ng-click="order('phone')">Phone Number</button>
          <span class="sortorder" ng-show="predicate === 'phone'" ng-class="{reverse:reverse}"></span>
        </th>
        <th>
          <button ng-click="order('age')">Age</button>
          <span class="sortorder" ng-show="predicate === 'age'" ng-class="{reverse:reverse}"></span>
        </th>
      </tr>
      <tr ng-repeat="friend in friends | orderBy:predicate:reverse">
        <td>{{friend.name}}</td>
        <td>{{friend.phone}}</td>
        <td>{{friend.age}}</td>
      </tr>
    </table>
  </div>
</body>


(function(angular) {
  'use strict';
angular.module('orderByExample', [])
  .controller('ExampleController', ['$scope', function($scope) {
    $scope.friends =
        [{name:'John', phone:'555-1212', age:10},
         {name:'Mary', phone:'555-9876', age:19},
         {name:'Mike', phone:'555-4321', age:21},
         {name:'Adam', phone:'555-5678', age:35},
         {name:'Julie', phone:'555-8765', age:29}];
    $scope.predicate = 'age';
    $scope.reverse = true;
    $scope.order = function(predicate) {
      $scope.reverse = ($scope.predicate === predicate) ? !$scope.reverse : false;
      $scope.predicate = predicate;
    };
  }])
.factory("")
})(window.angular);

1 Answer 1

2

Both tables are sorting on the same variables, so their display will naturally be identical.

I would make the order and predicate children of a table identifier - we'll use t1 and t2 here, but please use something more identifiable in your own code.

$scope.t1 = { predicate: 'age', reverse: true};
$scope.t2 = { predicate: 'age', reverse: true};

Now the order function needs to take that identifier:

$scope.order = function(predicate, tableId) {
  $scope[tableId].reverse = ($scope[tableId].predicate === predicate) ? !$scope[tableId].reverse : false;
  $scope[tableId].predicate = predicate;
};

And finally the order functions and repeaters need to use their table ids:

<table class="friend">
  <tr>
    <th>
      <button ng-click="order('name','t1')">Name</button>
      <span ng-show="t1.predicate === 'name'" ng-class="{reverse:t1.reverse}"></span>
    </th>
    <th>
      <button ng-click="order('phone','t1')">Phone Number</button>
      <span class="sortorder" ng-show="t1.predicate === 'phone'" ng-class="{reverse:t1.reverse}"></span>
    </th>
    <th>
      <button ng-click="order('age','t1')">Age</button>
      <span class="sortorder" ng-show="t1.predicate === 'age'" ng-class="{reverse:t1.reverse}"></span>
    </th>
  </tr>
  <tr ng-repeat="friend in friends | orderBy:t1.predicate:t1.reverse">
    <td>{{friend.name}}</td>
    <td>{{friend.phone}}</td>
    <td>{{friend.age}}</td>
  </tr>
</table>

Same idea for table 2

If you needed to scale larger, you would probably want to use some kind of a repeater instead of what I just did. I'll leave that exercise to you.

Sign up to request clarification or add additional context in comments.

3 Comments

Solution with directive that would isolate scope would be much sexy tho.
A full solution would have the friends collection coming from a service or factory so that isolated scope in the presentation would actually work correctly. We're not trying to confuse new Angular developers :)
Thanks Lathejockey81 :)

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.