To display data in a HTML document we do use table. While presenting data in a table to make this more user friendly we need some minimum operations like Sorting & Pagination. In this article I am using a HTML5 table to bind data using AngularJS. Including data bind here I implemented sorting & pagination features. Look at the example below.
index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html ng-app="tblModule"> <head> <meta charset="utf-8"> <title>HTML5 Table Sorting & Pagination using AngularJS</title> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.0/angular.min.js" ng:autobind></script> <link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.1.1/css/bootstrap.no-icons.min.css" rel="stylesheet"> <link href="http://netdna.bootstrapcdn.com/font-awesome/2.0/css/font-awesome.css" rel="stylesheet"> <link rel="stylesheet" href="bootstrap/css/bootstrap.min.css" type="text/css"> <link rel="stylesheet" href="bootstrap/css/bootstrap-theme.min.css" type="text/css"> <script type="text/javascript" src="app.js"></script> <link rel="stylesheet" href="app-style.css" type="text/css"> <script src="http://code.jquery.com/jquery-1.11.0.min.js">,</script> </head> <body> <script type="text/javascript"> var sortingOrder = 'name'; </script> <my-customer tbl-width="900"></my-customer> </body> </html>
my-customer.html
<div class="input-append"> <input type="text" ng-model="query" ng-change="search()" class="input-large search-query" placeholder="Search"> <span class="add-on"><i class="icon-search"></i></span> </div> <table class="table table-striped table-condensed table-hover"> <thead> <tr> <th class="id">Id <a ng-click="sort_by('id')"><i class="icon-sort"></i></a></th> <th class="name">Name <a ng-click="sort_by('name')"><i class="icon-sort"></i></a></th> <th class="designation">Designation <a ng-click="sort_by('designation')"><i class="icon-sort"></i></a></th> <th class="employeeid">Employee ID <a ng-click="sort_by('employeeid')"><i class="icon-sort"></i></a></th> <th class="email">Email <a ng-click="sort_by('email')"><i class="icon-sort"></i></a></th> <th class="location">Location <a ng-click="sort_by('location')"><i class="icon-sort"></i></a></th> </tr> </thead> <tfoot> <td colspan="6"> <div class="pagination pull-right"> <ul> <li ng-class="{disabled: currentPage == 0}"> <a href ng-click="prevPage()">« Prev</a> </li> <li ng-repeat="n in range(pagedItems.length)" ng-class="{active: n == currentPage}" ng-click="setPage()"> <a href ng-bind="n + 1">1</a> </li> <li ng-class="{disabled: currentPage == pagedItems.length - 1}"> <a href ng-click="nextPage()">Next »</a> </li> </ul> </div> </td> </tfoot> <tbody> <tr ng-repeat="item in pagedItems[currentPage] | orderBy:sortingOrder:reverse"> <td>{{ item.id }}</td> <td>{{ item.name }}</td> <td>{{ item.designation }}</td> <td>{{ item.employeeid }}</td> <td><a href="mailto:{{ item.email }}">{{ item.email }}</a></td> <td>{{ item.location }}</td> </tr> </tbody> </table>
app.js
angular.module('tblModule', []) .directive('myCustomer', function() { return { restrict: 'E', transclude: true, scope: { "tblWidth": '=' }, link: function (scope, element) { scope.$watch("tblWidth", function (value) { $("#tbltemp").css({"width": value + "px"}); }, false); }, controller: function($scope, $filter) { $scope.sortingOrder = sortingOrder; $scope.reverse = false; $scope.filteredItems = []; $scope.groupedItems = []; $scope.itemsPerPage = 5; $scope.pagedItems = []; $scope.currentPage = 0; $scope.items = [ {"id":"1","name":"Biswabhusan","designation":"Sr. UI Developer","employeeid":"012801","email":"biswabhusan@gmail.com","location":"INDIA"}, {"id":"2","name":"Rakesh Srivastab","designation":"Software Engineer","employeeid":"013882","email":"rakesh@gmail.com","location":"GERMANY"}, {"id":"3","name":"John Fernandez","designation":"Sr. Team Lead","employeeid":"055620","email":"john@gmail.com","location":"ITALY"}, {"id":"4","name":"Kumar Abhishek","designation":"Project Manager","employeeid":"032451","email":"ku.abhishek@gmail.com","location":"INDIA"}, {"id":"5","name":"Swati Rao","designation":"UI Developer","employeeid":"001235","email":"rao@gmail.com","location":"HONG KONG"}, {"id":"6","name":"Monika Roy","designation":"SEO","employeeid":"076565","email":"monika@gmail.com","location":"INDIA"}, {"id":"7","name":"Monalisha Pradhan","designation":"Sr. Software Engineer","employeeid":"012302","email":"monalisha@gmail.com","location":"US"} ]; var searchMatch = function (haystack, needle) { if (!needle) { return true; } return haystack.toLowerCase().indexOf(needle.toLowerCase()) !== -1; }; // initializing the filtered items $scope.search = function () { $scope.filteredItems = $filter('filter')($scope.items, function (item) { for(var attr in item) { if (searchMatch(item[attr], $scope.query)) return true; } return false; }); // taking care of the sorting order if ($scope.sortingOrder !== '') { $scope.filteredItems = $filter('orderBy')($scope.filteredItems, $scope.sortingOrder, $scope.reverse); } $scope.currentPage = 0; // now group by pages $scope.groupToPages(); }; // calculate page in place $scope.groupToPages = function () { $scope.pagedItems = []; for (var i = 0; i < $scope.filteredItems.length; i++) { if (i % $scope.itemsPerPage === 0) { $scope.pagedItems[Math.floor(i / $scope.itemsPerPage)] = [ $scope.filteredItems[i] ]; } else { $scope.pagedItems[Math.floor(i / $scope.itemsPerPage)].push($scope.filteredItems[i]); } } }; $scope.range = function (start, end) { var ret = []; if (!end) { end = start; start = 0; } for (var i = start; i < end; i++) { ret.push(i); } return ret; }; $scope.prevPage = function () { if ($scope.currentPage > 0) { $scope.currentPage--; } }; $scope.nextPage = function () { if ($scope.currentPage < $scope.pagedItems.length - 1) { $scope.currentPage++; } }; $scope.setPage = function () { $scope.currentPage = this.n; }; // functions have been describe process the data for display $scope.search(); // change sorting order $scope.sort_by = function(newSortingOrder) { if ($scope.sortingOrder == newSortingOrder) $scope.reverse = !$scope.reverse; $scope.sortingOrder = newSortingOrder; // icon setup $('th i').each(function(){ // icon reset $(this).removeClass().addClass('icon-sort'); }); if ($scope.reverse) $('th.'+new_sorting_order+' i').removeClass().addClass('icon-chevron-up'); else $('th.'+new_sorting_order+' i').removeClass().addClass('icon-chevron-down'); }; }, templateUrl: 'my-customer.html' }; });
app-style.css
thead { background-color: lightblue; border-bottom: 2px solid black; cursor: pointer; } .paradiv { float: left; width: 50%; } .pagination { margin: 0px 0px !important; } .borderdiv { padding: 8px; } .ralign { width:100%; text-align:right; }