-
-
Save kmaida/06d01f6b878777e2ea34 to your computer and use it in GitHub Desktop.
<!DOCTYPE HTML> | |
<html lang="en" ng-app="myApp"> | |
<head> | |
<meta charset="utf-8"> | |
<title>Dynamic Pagination w/ Filtering</title> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<meta name="description" content=""> | |
<meta name="author" content="Kim Maida"> | |
<!-- JS Libraries --> | |
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js" type="text/javascript"></script> | |
<script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.10.0.js" type="text/javascript"></script> | |
<!-- Angular Scripts --> | |
<script src="script.js" type="text/javascript"></script> | |
<!-- Bootstrap --> | |
<link rel="stylesheet" type="text/css" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" /> | |
</head> | |
<body> | |
<div ng-controller="PageCtrl"> | |
<div ng-controller="PageCtrl"> | |
<label>Search:</label> <input type="text" ng-model="search.name" placeholder="Search" /> | |
<br /> | |
<label>Filter by Category:</label> | |
<ul> | |
<li><a href="" ng-click="search.category='engineering'">Engineering</a></li> | |
<li><a href="" ng-click="search.category='management'">Management</a></li> | |
<li><a href="" ng-click="search.category='business'">Business</a></li> | |
</ul> | |
<label>Filter by Branch:</label> | |
<ul> | |
<li><a href="" ng-click="search.branch='West'">West</a></li> | |
<li><a href="" ng-click="search.branch='East'">East</a></li> | |
</ul> | |
<p><strong><a href="" ng-click="resetFilters()">Show All</a></strong></p> | |
<h1>Items</h1> | |
<ul> | |
<li ng-repeat="item in filtered = items | filter:search | startFrom:(currentPage-1)*entryLimit | limitTo:entryLimit">{{item.name}}</li> | |
</ul> | |
<pagination page="currentPage" max-size="noOfPages" total-items="totalItems" items-per-page="entryLimit"></pagination> | |
</div> | |
</body> | |
</html> |
var app = angular.module('myApp', ['ui.bootstrap']); | |
app.filter('startFrom', function () { | |
return function (input, start) { | |
if (input) { | |
start = +start; | |
return input.slice(start); | |
} | |
return []; | |
}; | |
}); | |
app.controller('PageCtrl', ['$scope', 'filterFilter', function ($scope, filterFilter) { | |
$scope.items = [{ | |
"name": "name 1", | |
"category": [{ | |
"category": "management" | |
}, { | |
"category": "business" | |
}], | |
"branch": "West" | |
}, { | |
"name": "name 2", | |
"category": [{ | |
"category": "engineering" | |
}], | |
"branch": "West" | |
}, { | |
"name": "name 3", | |
"category": [{ | |
"category": "management" | |
}, { | |
"category": "engineering" | |
}], | |
"branch": "West" | |
}, { | |
"name": "name 4", | |
"category": [{ | |
"category": "management" | |
}, { | |
"category": "business" | |
}], | |
"branch": "West" | |
}, { | |
"name": "name 5", | |
"category": [{ | |
"category": "management" | |
}, { | |
"category": "business" | |
}], | |
"branch": "East" | |
}, { | |
"name": "name 6", | |
"category": [{ | |
"category": "management" | |
}, { | |
"category": "business" | |
}], | |
"branch": "East" | |
}, { | |
"name": "name 7", | |
"category": [{ | |
"category": "management" | |
}, { | |
"category": "business" | |
}], | |
"branch": "East" | |
}, { | |
"name": "name 8", | |
"category": [{ | |
"category": "business" | |
}], | |
"branch": "West" | |
}, { | |
"name": "name 9", | |
"category": [{ | |
"category": "management" | |
}, { | |
"category": "business" | |
}], | |
"branch": "East" | |
}, { | |
"name": "name 10", | |
"category": [{ | |
"category": "management" | |
}], | |
"branch": "East" | |
}, { | |
"name": "name 11", | |
"category": [{ | |
"category": "management" | |
}, { | |
"category": "business" | |
}], | |
"branch": "East" | |
}, { | |
"name": "name 12", | |
"category": [{ | |
"category": "engineering" | |
}], | |
"branch": "West" | |
}, { | |
"name": "name 13", | |
"category": [{ | |
"category": "management" | |
}, { | |
"category": "business" | |
}], | |
"branch": "West" | |
}, { | |
"name": "name 14", | |
"category": [{ | |
"category": "engineering" | |
}], | |
"branch": "East" | |
}, { | |
"name": "name 15", | |
"category": [{ | |
"category": "management" | |
}, { | |
"category": "engineering" | |
}], | |
"branch": "East" | |
}, { | |
"name": "name 16", | |
"category": [{ | |
"category": "management" | |
}], | |
"branch": "West" | |
}, { | |
"name": "name 17", | |
"category": [{ | |
"category": "management" | |
}], | |
"branch": "East" | |
}, { | |
"name": "name 18", | |
"category": [{ | |
"category": "business" | |
}], | |
"branch": "West" | |
}, { | |
"name": "name 19", | |
"category": [{ | |
"category": "business" | |
}], | |
"branch": "West" | |
}, { | |
"name": "name 20", | |
"category": [{ | |
"category": "engineering" | |
}], | |
"branch": "East" | |
}, { | |
"name": "Peter", | |
"category": [{ | |
"category": "business" | |
}], | |
"branch": "East" | |
}, { | |
"name": "Frank", | |
"category": [{ | |
"category": "management" | |
}], | |
"branch": "East" | |
}, { | |
"name": "Joe", | |
"category": [{ | |
"category": "business" | |
}], | |
"branch": "East" | |
}, { | |
"name": "Ralph", | |
"category": [{ | |
"category": "management" | |
}, { | |
"category": "business" | |
}], | |
"branch": "East" | |
}, { | |
"name": "Gina", | |
"category": [{ | |
"category": "business" | |
}], | |
"branch": "East" | |
}, { | |
"name": "Sam", | |
"category": [{ | |
"category": "management" | |
}, { | |
"category": "engineering" | |
}], | |
"branch": "East" | |
}, { | |
"name": "Britney", | |
"category": [{ | |
"category": "business" | |
}], | |
"branch": "West" | |
}]; | |
// create empty search model (object) to trigger $watch on update | |
$scope.search = {}; | |
$scope.resetFilters = function () { | |
// needs to be a function or it won't trigger a $watch | |
$scope.search = {}; | |
}; | |
// pagination controls | |
$scope.currentPage = 1; | |
$scope.totalItems = $scope.items.length; | |
$scope.entryLimit = 8; // items per page | |
$scope.noOfPages = Math.ceil($scope.totalItems / $scope.entryLimit); | |
// $watch search to update pagination | |
$scope.$watch('search', function (newVal, oldVal) { | |
$scope.filtered = filterFilter($scope.items, newVal); | |
$scope.totalItems = $scope.filtered.length; | |
$scope.noOfPages = Math.ceil($scope.totalItems / $scope.entryLimit); | |
$scope.currentPage = 1; | |
}, true); | |
}]); |
Hello,
I know you answered about "filterFilter" above on Feb 2, but I still don't understand it.
I downloaded your code and changed $filter('startFrom')($scope.items, newVal) instead of "filterFilter".
Then search works but pagination doesn't updated. I thought "filterFilter" calls app.filter('startFrom', function (){}. Would you explain what function "filterFilter" is calling?
Thank you,
Awesome way to do it! Thanks a lot! +star
For live testing: http://plnkr.co/edit/Q26WPjLqcOtS8p0mGF6b?p=preview
don't need startFrom, just use limitTo: perPage : (currentPage-1)*perPage
why if type on input search "HelloWorldNotFonud"
when clear input, not show records.
ty
Instead of building object $scope.items in controller I am fetching as json using ajax from server. So how can we implement this ?
@abhilive, it's essentially the same way except you'd have the items loaded from the server. This is the way I did it. Note that I use ControllerAs syntax as opposed to $scope. I do that with the angular.bind call in $watch (of course, some of my names differ but you should be able to figure it out.
$scope.$watch(angular.bind(this, function () {
return this.search;
}), function (newVal, oldVal) {
self.pagedClients = filterFilter(self.clients, newVal);
self.totalClients = self.pagedClients.length;
self.numPages = Math.ceil(self.totalClients / self.perPage);
self.currentPage = 1;
}, true);
You'll also need to set the initial values for these when the data is first loaded and force the $watch to run.
... // ajax
.then(
function (data) {
self.clients = data;
self.totalClients = self.clients.length;
self.numPages = Math.ceil(self.totalClients / self.perPage);
self.currentPage = 1;
self.search = '';
},
...// more ajax
Thanks for this, helped me out a lot.
OrderBy field?
Good example. thanks
Thank you so much for this, This helps me with my current roadblock!
Currently having issues getting this to work inside Ajax call... I'd appreciate any help.. Spent a few hours on this :(
Main issue:
- Pagination works fine but the filter doesnt. When I tried to filter an item(about 3000 items), it was only able to filter the page its currently on. For instance, if I'm on page 1, and searched for an item on page 8, it will return nothing, but if the item I'm searching for is on page 1, it will return the result.
I know I'm missing something...
Fixed the above! thanks all!
what the hell ? pagination tag...
@manjunath10073 i think to limit the buttons, we need to change the max-size
value
<pagination page="currentPage" max-size="5" total-items="totalItems" items-per-page="entryLimit"></pagination>
hi,
Same condition. but not working in my project. only change <script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.10.0.js" type="text/javascript"></script> to <script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-1.3.3.js" type="text/javascript"></script>
plunker example code here,
http://plnkr.co/edit/9a8heE1eWLMA0FgR6reG?p=preview
please help me [email protected]
Hi, I get input is not defined in startForm filter, any idea?