Pagination, Searching and Sorting of Data Table using AngularJS

We have already discussed “Basics of AngularJS” and “Simple Searching and Sorting“. In this article, we will add Pagination feature also to our previous example. What makes difficult is Sorting result when values are returned from Search and pagination is enabled. Unlike previous post we cannot use standard “OrderBy” filter provided by AngularJs framework, this time we have to create Javascript function inside Controller for Sorting purpose.

Prerequisite Libraries :

  1. UnderscoreJs
  2. Bootstrap CSS
  3. AngularJs

This post used “Custom Service”, so please read this article to understand Dependency Injection in AngularJs.

Searching Sorting and Pagination in Table using AngularJS
Searching Sorting and Pagination in Table using AngularJS

Live Demo :

Complete HTML Code :

<br />
<br />
<div ng-app="myApp">
    <div ng-controller="TableCtrl">
        <div class="input-group">
            <input class="form-control" ng-model="searchText" placeholder="Search" type="search" ng-change="search()" /> <span class="input-group-addon">
      <span class="glyphicon glyphicon-search"></span>
</span>
        </div>
        <table class="table  table-hover data-table myTable">
            <thead>
                <tr>
                    <th class="EmpId"> <a href="#" ng-click="sort('EmpId',$event)">EmpId
                         <span class="{{Header[0]}}"></span>
                         </a>

                    </th>
                    <th class="name"> <a ng-click="sort('name')" href="#"> Name
                         <span class="{{Header[1]}}"></span></a>
                    </th>
                    <th class="Email"> <a ng-click="sort('Email')" href="#"> Email
                     <span class="{{Header[2]}}"></span></a>
                    </th>
                </tr>
            </thead>
            <tbody>
                <tr ng-repeat="item in ItemsByPage[currentPage] | orderBy:columnToOrder:reverse">
                    <td>{{item.EmpId}}</td>
                    <td>{{item.name}}</td>
                    <td>{{item.Email}}</td>
                </tr>
            </tbody>
        </table>
        <ul class="pagination pagination-sm">
            <li ng-class="{active:0}"><a href="#" ng-click="firstPage()">First</a>

            </li>
            <li ng-repeat="n in range(ItemsByPage.length)"> <a href="#" ng-click="setPage()" ng-bind="n+1">1</a>

            </li>
            <li><a href="#" ng-click="lastPage()">Last</a>

            </li>
        </ul>
        <div class="row">
            <div class="col-xs-3">
                <input type="text" ng-model="newEmpId" class="form-control" placeholder="EmpId">
            </div>
            <div class="col-xs-3">
                <input type="text" ng-model="newName" class="form-control" placeholder="Name">
            </div>
            <div class="col-xs-4">
                <input type="email" ng-model="newEmail" class="form-control" placeholder="Email">
            </div>
            <div class="col-xs-1">
                <button ng-click="add()" type="button" class="btn btn-primary"> <span class="glyphicon glyphicon-plus"></span>

                </button>
            </div>
        </div>
    </div>
    <!-- Ends Controller -->
</div>

Complete JavaScript Code :

//Demo of Searching Sorting and Pagination of Table with AngularJS - Advance Example

var myApp = angular.module('myApp', []);

//Not Necessary to Create Service, Same can be done in COntroller also as method like add() method
myApp.service('filteredListService', function () {

    this.searched = function (valLists, toSearch) {
        return _.filter(valLists,

        function (i) {
            /* Search Text in all 3 fields */
            return searchUtil(i, toSearch);
        });
    };

    this.paged = function (valLists, pageSize) {
        retVal = [];
        for (var i = 0; i < valLists.length; i++) {
            if (i % pageSize === 0) {
                retVal[Math.floor(i / pageSize)] = [valLists[i]];
            } else {
                retVal[Math.floor(i / pageSize)].push(valLists[i]);
            }
        }
        return retVal;
    };

});

//Inject Custom Service Created by us and Global service $filter. This is one way of specifying dependency Injection
var TableCtrl = myApp.controller('TableCtrl', function ($scope, $filter, filteredListService) {

    $scope.pageSize = 4;
    $scope.allItems = getDummyData();
    $scope.reverse = false;

    $scope.resetAll = function () {
        $scope.filteredList = $scope.allItems;
        $scope.newEmpId = '';
        $scope.newName = '';
        $scope.newEmail = '';
        $scope.searchText = '';
        $scope.currentPage = 0;
        $scope.Header = ['', '', ''];
    }

    $scope.add = function () {
        $scope.allItems.push({
            EmpId: $scope.newEmpId,
            name: $scope.newName,
            Email: $scope.newEmail
        });
        $scope.resetAll();
    }

    $scope.search = function () {
        $scope.filteredList = filteredListService.searched($scope.allItems, $scope.searchText);

        if ($scope.searchText == '') {
            $scope.filteredList = $scope.allItems;
        }
        $scope.pagination();
    }

    // Calculate Total Number of Pages based on Search Result
    $scope.pagination = function () {
        $scope.ItemsByPage = filteredListService.paged($scope.filteredList, $scope.pageSize);
    };

    $scope.setPage = function () {
        $scope.currentPage = this.n;
    };

    $scope.firstPage = function () {
        $scope.currentPage = 0;
    };

    $scope.lastPage = function () {
        $scope.currentPage = $scope.ItemsByPage.length - 1;
    };

    $scope.range = function (input, total) {
        var ret = [];
        if (!total) {
            total = input;
            input = 0;
        }
        for (var i = input; i < total; i++) {
            if (i != 0 && i != total - 1) {
                ret.push(i);
            }
        }
        return ret;
    };

    $scope.sort = function (sortBy) {
        $scope.resetAll();

        $scope.columnToOrder = sortBy;

        //$Filter - Standard Service
        $scope.filteredList = $filter('orderBy')($scope.filteredList, $scope.columnToOrder, $scope.reverse);

        if ($scope.reverse) iconName = 'glyphicon glyphicon-chevron-up';
        else iconName = 'glyphicon glyphicon-chevron-down';

        if (sortBy === 'EmpId') {
            $scope.Header[0] = iconName;
        } else if (sortBy === 'name') {
            $scope.Header[1] = iconName;
        } else {
            $scope.Header[2] = iconName;
        }

        $scope.reverse = !$scope.reverse;

        $scope.pagination();
    };

    //By Default sort ny Name
    $scope.sort('name');

});

function searchUtil(item, toSearch) {
    /* Search Text in all 3 fields */
    return (item.name.toLowerCase().indexOf(toSearch.toLowerCase()) > -1 || item.Email.toLowerCase().indexOf(toSearch.toLowerCase()) > -1 || item.EmpId == toSearch) ? true : false;
}

/*Get Dummy Data for Example*/
function getDummyData() {
    return [{
        EmpId: 2,
        name: 'Jitendra',
        Email: 'jz@gmail.com'
    }, {
        EmpId: 1,
        name: 'Minal',
        Email: 'amz@gmail.com'
    }, {
        EmpId: 3,
        name: 'Rudra',
        Email: 'ruz@gmail.com'
    }, {
        EmpId: 21,
        name: 'Jitendra1',
        Email: 'jz@gmail.com'
    }, {
        EmpId: 11,
        name: 'Minal1',
        Email: 'amz@gmail.com'
    }, {
        EmpId: 31,
        name: 'Rudra1',
        Email: 'ruz@gmail.com'
    }, {
        EmpId: 22,
        name: 'Jitendra2',
        Email: 'jz@gmail.com'
    }, {
        EmpId: 12,
        name: 'Minal2',
        Email: 'amz@gmail.com'
    }, {
        EmpId: 32,
        name: 'Rudra2',
        Email: 'ruz@gmail.com'
    }, {
        EmpId: 23,
        name: 'Jitendra3',
        Email: 'jz@gmail.com'
    }, {
        EmpId: 13,
        name: 'Minal3',
        Email: 'amz@gmail.com'
    }, {
        EmpId: 33,
        name: 'Rudra3',
        Email: 'ruz@gmail.com'
    }];
}

JSON data is input to table, which can be replaced by any server side JSON response. So, in case if you need to use this example in Salesforce, You simply have to change “getDummyData()“ method and get response using REST API. This article will be helpful if you are looking on how to generate JSON output in Visualforce page.

Why do we need Service in above example ?

It is always better to separate concern from Controller. So instead of writing methods or logics inside Controller, we have created Service and passed service as a parameter while declaring controller.

Now we just have to call methods declared in service from Controller.

If you are looking for same kind of Example in Salesforce then this is very Good Article written by Harshit and Mohit Srivastav.

Live Demo of this example

Related posts

  • I made an page pointing the repository of visualforce pages for examples in Salesforce using Angular.js – fork it and push it if you have something cool to share or you feel like http://mailtoharshit.github.io/Angular/

  • Kapil Tilwani

    I ahve pasted my code here.. http://stackoverflow.com/questions/27205243/sorting-on-page/27206583#27206583

    Sorting does not work in Correct way . Please help ..
    Thanks in Advance

  • vikrant

    Hello Jitendra sir,
    I have used the above code given by you.It is displaying the table structure but,my problem is: it is not displaying the dummy data into table.
    I have included all the pre-requisite files that you mentioned.Hope for reply
    Thanks i advance..!!

  • Dev

    Sorry but sorting is not working for numbers for whole data. Sorting for numbers is working for the respective page only. why complete data is not sorted when clicking on number format.

    • Hi Dev, Can you give example in JSfiddle ? you can clone this example in Jsfiddle and provide URL which replicates issue.

  • bidisha

    Hi the sorting is not happening across the pages.I tried changing the names starting with A,B,S,Z across the page so when I sort it shud be sorted across the page but its sorting on per page basis.For e.g. if my names are Zitendra,Sudra,Kinal on page 1 and Jitendra,Minal,Rudra on page 2 and Bitendra,Dinal,Tudra on page 3 when I sort asc order page 1 shud display names -Bitendra,Dinal,Jitendra; page2- Kinal , Minal,Rudra ,Page3- Sudra,Tudra ,Zitendra. But currenlty its sorting only on currentPage. Any idea how to fix this?

    • Can you give example in JSfiddle ? you can clone this example in Jsfiddle and provide URL which replicates issue.

  • abhi

    If i have to refresh this datatable with new data how i can do this.

  • Arun

    hi ,
    I don’t anything about angularjs. Will this supports to display 50k rows without freezing.
    Thanks.

    • Not recommended , Angular uses your browser. So, if you are trying to show 50k record, chances are high that it will freeze.