3

I'm using pagination for my data set and now I'm trying to sort it but the sort function sorts only the current page's records. I want to sort the entire data set not only the current page. Is there any possible way to do it? Thanks.

Here is my controller.js

angular.module("app").controller("billetController", function($scope, billetService) {
  var self = this;
  self.billets = [];
  $scope.allCandidates = [];
  $scope.aCandidates = [];
  $scope.totalItems = 0;
  $scope.sortType = 'statutBillet'; // set the default sort type
  $scope.sortReverse = false; // set the default sort order

  getBillets();

  function getBillets() {
    billetService.getBillets()
      .then(
        function(d) {

          console.log(d);
          self.billets = d;
          $scope.totalItems = self.billets.length;
          $scope.$watch("currentPage", function() {
            console.log($scope.currentPage);

            $scope.aCandidates = self.billets.slice(
              ($scope.currentPage - 1) * $scope.itemsPerPage,
              $scope.currentPage * $scope.itemsPerPage
            );
          });

        },
        function(errResponse) {
          console.error('Error while fetching ');
        }
      );
  }

  $scope.currentPage = 1;
  $scope.itemsPerPage = 50;


  function setPagingData(page, allCandidates) {
    var pagedData = allCandidates.toString().slice(
      (page - 1) * $scope.itemsPerPage,
      page * $scope.itemsPerPage
    );
    $scope.aCandidates = pagedData;
  }

  console.log($scope.allCandidates);

});

and my table in view.jsp :

<div ng-controller="billetController">
  <table class="table table-hover">
    <thead>
      <th>ID</th>
      <th>
        <a href="#" ng-click="sortType = 'statutBillet'; sortReverse = !sortReverse">
                                            Statut
                                            <span ng-show="sortType == 'statutBillet' && !sortReverse" class="fa fa-caret-down"></span>
                                            <span ng-show="sortType == 'statutBillet' && sortReverse" class="fa fa-caret-up"></span>
                                            </a></th>
      <th>Priorité</th>
      <th>Impact</th>
      <th>Resumé</th>
      <th>Date de création</th>
    </thead>
    <tbody>
      <tr ng-repeat="billet in aCandidates | orderBy:sortType:sortReverse">
        <td>{{ billet.idBillet }}</td>
        <td>{{ billet.statutBillet }}</td>
        <td>{{ billet.prioriteBillet }}</td>
        <td>{{ billet.impactBillet }}</td>
        <td>{{ billet.resumeBillet }}</td>
        <td>{{ billet.dateCreation | date:'yyyy-MM-dd HH:mm:ss' }}</td>
      </tr>

    </tbody>

  </table>
  <uib-pagination total-items="totalItems" ng-model="currentPage" items-per-page="itemsPerPage"></uib-pagination>
</div>
jbrown
  • 3,025
  • 1
  • 15
  • 22
Jiji
  • 103
  • 1
  • 2
  • 11

2 Answers2

1

I would highly consider looking into angular-tablesort. This library will save you tons of time and prevent you from writing your own sorting code. It also works very well with UI-Bootstrap.

Here's an example using angular-tablesort with uib-pagination:

                <table class="table table-striped" ts-wrapper>
                    <thead>
                        <tr>
                            <th ts-criteria="policyNumber">Policy Number</th>
                            <th ts-criteria="email">Email</th>
                            <th ts-criteria="isLinked">Linked</th>
                            <th ts-criteria="createdAt" ts-default="descending">Created At</th>
                            <th>Details</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr ng-repeat="user in adminLegacyUsersCtrl.filteredUsers = adminLegacyUsersCtrl.users
        | tablesort
        | searchLegacyUsers:adminLegacyUsersCtrl.query
        | filterLegacyUsersByLinked:adminLegacyUsersCtrl.selectedLinkOption.id
        | startFrom:(adminLegacyUsersCtrl.currentPage-1)*adminLegacyUsersCtrl.itemsPerPage
        | limitTo:adminLegacyUsersCtrl.itemsPerPage" ts-repeat>
                            <td>
                                <a ng-click="adminLegacyUsersCtrl.openPolicyDetailsModal(user, adminLegacyUsersCtrl.getPolicy(user.policyNumber))">{{user.policyNumber}}</a>
                            </td>
                            <td>{{user.email}}</td>
                            <td>{{user.isLinked}}</td>
                            <td>{{user.createdAt | date : "MMMM dd, yyyy H:mm"}}</td>
                            <td ng-click="adminLegacyUsersCtrl.openLegacyUserDetailsModal(user)"><a>View</a></td>
                        </tr>
                    </tbody>
                </table>
                <div class="col-lg-12 col-lg-offset-4">
                    <ul uib-pagination items-per-page="adminLegacyUsersCtrl.itemsPerPage" total-items="adminLegacyUsersCtrl.totalItems" ng-model="adminLegacyUsersCtrl.currentPage" max-size="5" class="pagination-sm" boundary-links="true"></ul>
                </div>

To get angular-tablesort working:

1) Apply a ts-wrapper attribute directive to your table.

2) Apply a ts-criteria='nameOfProperty to each <th> you want to sort. (i.e. in your example ts-criteria="idBillet")

3) Apply a tablesort filter (MAKE SURE THIS FILTER IS BEFORE YOUR OTHER FILTERS!)

4) Finally, apply a ts-repeat attribute directive to your ng-repeat statement.

5) (Optionally) You can apply a ts-default attribute to one of your <th> tags to state you want that common to be the default sorted column in the table.

Ben
  • 2,441
  • 1
  • 12
  • 16
  • I was already using an older version of angular-tablesort, so I upgraded to 1.6.1 and this worked great (The `tablesort` filter was ignored in 1.0.4) . The only quirk I noticed was having to apply the `tablesorter` class to the table manually in order to get the styling to match what I was used to. – Danny Jul 11 '19 at 15:56
0

I recognized your code as coming from an answer I gave to this post on pagination. So I went ahead and updated that plunk to include column sorting. Essentially you need to sort all data and then call setPagingData again to only return a page's worth of data.

// column collection to persist sort order to allow for ASC/DESC switch
var cols = [{
  name: 'firstName',
  orderDesc: false
}, {
  name: 'lastName',
  orderDesc: false
}];

$scope.sortData = function(sortCol) {
  // make sure it a valid column
  var column = cols.find(function(col) {
    return col.name === sortCol;
  });

  if (!column) return;

  column.orderDesc = !column.orderDesc;

  var order = !column.orderDesc ? 1 : -1;
  allCandidates.sort(function(a, b) {
    if (a[column.name] < b[column.name])
      return -1 * order;
    if (a[column.name] > b[column.name])
      return 1 * order;
    return 0;
  });

  setPagingData($scope.currentPage);
};
Community
  • 1
  • 1
jbrown
  • 3,025
  • 1
  • 15
  • 22