After some work, this is the final implementation:
app.directive('pager', function() {
return {
restrict: 'EA',
scope: {
onChange: '&',
items: '=',
itemsPerPage: '@'
},
replace: true,
templateUrl: '/scripts/js/app/pager.html',
link: function(scope, el, attrs) {
scope.currentPage = 1;
scope.isFirstPage = function() {
return scope.currentPage === 1;
}
scope.decPage = function() {
if(scope.currentPage > 1) --scope.currentPage;
}
scope.isLastPage = function() {
return scope.currentPage >= scope.totalPages();
}
scope.totalPages = function() {
return Math.ceil(scope.items.total / scope.itemsPerPage);
}
scope.incPage = function() {
if(!scope.isLastPage()) ++scope.currentPage;
}
scope.$watch("currentPage", function(value) {
scope.onChange({page: value, itemsPerPage: scope.itemsPerPage});
});
}
};
});
markup
<div id="content" ng-app="subscriptionsManager">
<div ng-controller="subscriptionHolderController">
<div class="row">
<div class="columns medium-6 large-6">
<div class="searchbar">
<div class="searchbar-inner">
<input ng-model="searchTerm" type="text" />
<button ng-click="search(1, 35)" class="tiny">search</button>
</div>
</div>
<div pager items-per-page="35" items="data" on-change="respondToChanges(page, itemsPerPage)"></div>
</div>
<div class="columns medium-6 large-6">
<div class="button-group filter-sample">
<button ng-click="toggleState1()" ng-class="{true: 'selected', false: 'secondary'}[state1]" class="tiny">filter1</button>
<button ng-click="toggleState2()" ng-class="{true: 'selected', false: 'secondary'}[state2]" class="tiny">filter2</button>
<button ng-click="toggleState3()" ng-class="{true: 'selected', false: 'secondary'}[state3]" class="tiny">filter3</button>
<button ng-click="search2(1, 35)" class="tiny">search</button>
</div>
<div pager items-per-page="35" items="data2" on-change="respondToChanges2(page, itemsPerPage)"></div>
</div>
</div>
</div>
</div>
controller
// search by input term
$scope.data = { items: [], total: 0 };
$scope.searchTerm = '';
$scope.state1 = false;
$scope.state2 = false;
$scope.state3 = false;
$scope.toggleState1 = function() {
$scope.state1 = !$scope.state1;
}
$scope.toggleState2 = function() {
$scope.state2 = !$scope.state2;
}
$scope.toggleState3 = function() {
$scope.state3 = !$scope.state3;
}
$scope.search = function(page, itemsPerPage) {
if($scope.searchTerm === '') return;
if(!angular.isDefined(page) || page == null) page = 1;
if(!angular.isDefined(itemsPerPage) || itemsPerPage == null) itemsPerPage = 35;
$http({
url: '/subscriptions/GetSubscribersByNamePaged',
method: 'GET',
params: { term: $scope.searchTerm, page: page, itemsPerPage: itemsPerPage }
})
.success(function(data, status, headers, config) {
$scope.data = data;
}).error(function(data, status, headers, config) {
console.log('error: ' + data);
});
}
// search using other criteria
$scope.search2 = function(page, itemsPerPage) {
if(!angular.isDefined(page) || page == null) page = 1;
if(!angular.isDefined(itemsPerPage) || itemsPerPage == null) itemsPerPage = 35;
$http({
url: '/subscriptions/GetSubscribersByFilters',
method: 'GET',
params: { state1: $scope.state1, state2: $scope.state2, state3: $scope.state3, page: page, itemsPerPage: itemsPerPage }
})
.success(function(data, status, headers, config) {
$scope.data2 = data;
}).error(function(data, status, headers, config) {
console.log('error: ' + data);
});
}
// handle search events
$scope.respondToChanges = function(page, itemsPerPage) {
$scope.search(page, itemsPerPage);
}
$scope.respondToChanges2 = function(page, itemsPerPage) {
$scope.search2(page, itemsPerPage);
}