logo

NJP

Easily paginate, sort and filter within your widget for ng-repeat

Import · Oct 23, 2020 · article

So I had the need to paginate, sort and filter on a table which used ng-repeat.

There were many iterations I played around with until I eventually came up with a working solution that could handle everything I needed.

Here's some example code that you can pick apart and use as you see fit:

CSS:

.pagination-buttons-td {
  border: none !important;
  text-align: right;
  background-color: #f0f3f4;
}
.sortorder:after {
  content: '\25b2';   // BLACK UP-POINTING TRIANGLE
}
.sortorder.reverse:after {
  content: '\25bc';   // BLACK DOWN-POINTING TRIANGLE
}

HTML Template:

<!-- Pagination buttons:  https://hi.service-now.com/styles/retina_icons/retina_icons.html -->
  <table class="table table-striped table-responsive">
    <tr>
      <td colspan="3" class="pagination-buttons-td">
        <div style="float: left;">
          <input ng-model="siteSearchFilter" ng-change="currentPage = 0" placeholder="Search..." type="text" />
        </div>
        <div>
          <button ng-disabled="currentPage == 0" ng-click="currentPage=0"><i class="icon-first"></i></button>
          <button ng-disabled="currentPage == 0" ng-click="currentPage=currentPage-1"><i class="icon-chevron-left"></i></button>
          {{currentPage+1}}/{{numberOfPages()}}
          <button ng-disabled="currentPage >= filteredList.length/rowsPerPage - 1" ng-click="currentPage=currentPage+1"><i class="icon-chevron-right"></i></button>
          <button ng-disabled="currentPage >= numberOfPages()-1" ng-click="currentPage=numberOfPages()-1"><i class="icon-last"></i></button>
        </div>
      </td>
    </tr>
    <tr style="background-color: #ddd;">
      <th class="text-nowrap" ng-click="sortBy('name')">
        <div class="th-title">Site</div>
        <span class="sortorder" ng-show="propertyName === 'name'" ng-class="{reverse: reverse}"></span>
      </th>

      <th class="text-nowrap" ng-click="sortBy('person1')">
        <div class="th-title">Person 1</div>
        <span class="sortorder" ng-show="propertyName === 'person1'" ng-class="{reverse: reverse}"></span></th>

      <th class="text-nowrap" ng-click="sortBy('person2')">
        <div class="th-title">Person 2</div>
        <span class="sortorder" ng-show="propertyName === 'person2'" ng-class="{reverse: reverse}"></span></th>
    </tr>

    <tr ng-repeat="site in data.sites | orderBy:propertyName:reverse | filter:siteSearchFilter as filteredList" 
        ng-if="($index < ((currentPage+1) * rowsPerPage)) && ($index >= (((currentPage+1) * rowsPerPage)-rowsPerPage))">

        <td>{{site.name}}</td>
        <td>{{site.person1}}</td>
        <td>{{site.person2}}</td>

    </tr>
</table>

Client script:

// Pagination stuff
$scope.currentPage = 0;
$scope.rowsPerPage = 10;
$scope.siteSearchFilter = '';
$scope.filteredList = [];
$scope.numberOfPages = function() {
        return Math.ceil($scope.filteredList.length/$scope.rowsPerPage);
};

// Sorting stuff
$scope.propertyName = '';
$scope.reverse = false;
$scope.data.sorting = {
    'by' : $scope.propertyName,
    'dir' : $scope.reverse ? 'desc':'asc'
}
$scope.sortBy = function(propertyName) {
    $scope.reverse = ($scope.propertyName === propertyName) ? !$scope.reverse : false;
    $scope.propertyName = propertyName;
    $scope.data.sorting = {
        'by' : $scope.propertyName,
        'dir' : $scope.reverse ? 'desc':'asc'
    }
};

And here's an example of it in action:

image

I hope this can help someone.

View original source

https://www.servicenow.com/community/developer-articles/easily-paginate-sort-and-filter-within-your-widget-for-ng-repeat/ta-p/2320533