Skip to content

Commit

Permalink
feat(pagination): Add basic pagination directive
Browse files Browse the repository at this point in the history
  • Loading branch information
petebacondarwin committed Dec 18, 2012
1 parent f3a7608 commit 7c552ca
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 0 deletions.
52 changes: 52 additions & 0 deletions src/pagination/pagination.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
angular.module('ui.bootstrap.pagination', [])

.directive('pagination', function() {
return {
restrict: 'E',
scope: {
numPages: '=',
currentPage: '=',
onSelectPage: '&'
},
templateUrl: 'template/pagination/pagination.html',
replace: true,
link: function(scope) {
scope.$watch('numPages', function(value) {
scope.pages = [];
for(var i=1;i<=value;i++) {
scope.pages.push(i);
}
if ( scope.currentPage > value ) {
scope.selectPage(value);
}
});
scope.noPrevious = function() {
return scope.currentPage === 1;
};
scope.noNext = function() {
return scope.currentPage === scope.numPages;
};
scope.isActive = function(page) {
return scope.currentPage === page;
};

scope.selectPage = function(page) {
if ( ! scope.isActive(page) ) {
scope.currentPage = page;
scope.onSelectPage({ page: page });
}
};

scope.selectPrevious = function() {
if ( !scope.noPrevious() ) {
scope.selectPage(scope.currentPage-1);
}
};
scope.selectNext = function() {
if ( !scope.noNext() ) {
scope.selectPage(scope.currentPage+1);
}
};
}
};
});
118 changes: 118 additions & 0 deletions src/pagination/test/pagination.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
describe('pagination directive', function () {
var $rootScope, element;
beforeEach(module('ui.bootstrap.pagination'));
beforeEach(module('template/pagination/pagination.html'));
beforeEach(inject(function(_$compile_, _$rootScope_) {
$compile = _$compile_;
$rootScope = _$rootScope_;
$rootScope.numPages = 5;
$rootScope.currentPage = 3;
element = $compile('<pagination num-pages="numPages" current-page="currentPage"></pagination>')($rootScope);
$rootScope.$digest();
}));

it('has a "pagination" css class', function() {
expect(element.hasClass('pagination')).toBe(true);
});

it('contains one ul and num-pages + 2 li elements', function() {
expect(element.find('ul').length).toBe(1);
expect(element.find('li').length).toBe(7);
expect(element.find('li').eq(0).text()).toBe('Previous');
expect(element.find('li').eq(-1).text()).toBe('Next');
});

it('has the number of the page as text in each page item', function() {
var lis = element.find('li');
for(var i=1; i<=$rootScope.numPages;i++) {
expect(lis.eq(i).text()).toEqual(''+i);
}
});

it('sets the current-page to be active', function() {
var currentPageItem = element.find('li').eq($rootScope.currentPage);
expect(currentPageItem.hasClass('active')).toBe(true);
});

it('disables the "previous" link if current-page is 1', function() {
$rootScope.currentPage = 1;
$rootScope.$digest();
var previousPageItem = element.find('li').eq(0);
expect(previousPageItem.hasClass('disabled')).toBe(true);
});

it('disables the "next" link if current-page is num-pages', function() {
$rootScope.currentPage = 5;
$rootScope.$digest();
var nextPageItem = element.find('li').eq(-1);
expect(nextPageItem.hasClass('disabled')).toBe(true);
});

it('changes currentPage if a page link is clicked', function() {
var page2 = element.find('li').eq(2).find('a');
page2.click();
$rootScope.$digest();
expect($rootScope.currentPage).toBe(2);
});

it('changes currentPage if the "previous" link is clicked', function() {
var previous = element.find('li').eq(0).find('a').eq(0);
previous.click();
$rootScope.$digest();
expect($rootScope.currentPage).toBe(2);
});

it('changes currentPage if the "next" link is clicked', function() {
var next = element.find('li').eq(-1).find('a').eq(0);
next.click();
$rootScope.$digest();
expect($rootScope.currentPage).toBe(4);
});

it('does not change the current page on "previous" click if already at first page', function() {
var previous = element.find('li').eq(0).find('a').eq(0);
$rootScope.currentPage = 1;
$rootScope.$digest();
previous.click();
$rootScope.$digest();
expect($rootScope.currentPage).toBe(1);
});

it('does not change the current page on "next" click if already at last page', function() {
var next = element.find('li').eq(-1).find('a').eq(0);
$rootScope.currentPage = 5;
$rootScope.$digest();
next.click();
$rootScope.$digest();
expect($rootScope.currentPage).toBe(5);
});

it('executes the onSelectPage expression when the current page changes', function() {
$rootScope.selectPageHandler = jasmine.createSpy('selectPageHandler');
element = $compile('<pagination num-pages="numPages" current-page="currentPage" on-select-page="selectPageHandler(page)"></pagination>')($rootScope);
$rootScope.$digest();
var page2 = element.find('li').eq(2).find('a').eq(0);
page2.click();
$rootScope.$digest();
expect($rootScope.selectPageHandler).toHaveBeenCalledWith(2);
});

it('changes the number of items when numPages changes', function() {
$rootScope.numPages = 8;
$rootScope.$digest();
expect(element.find('li').length).toBe(10);
expect(element.find('li').eq(0).text()).toBe('Previous');
expect(element.find('li').eq(-1).text()).toBe('Next');
});

it('sets the current page to the last page if the numPages is changed to less than the current page', function() {
$rootScope.selectPageHandler = jasmine.createSpy('selectPageHandler');
element = $compile('<pagination num-pages="numPages" current-page="currentPage" on-select-page="selectPageHandler(page)"></pagination>')($rootScope);
$rootScope.$digest();
$rootScope.numPages = 2;
$rootScope.$digest();
expect(element.find('li').length).toBe(4);
expect($rootScope.currentPage).toBe(2);
expect($rootScope.selectPageHandler).toHaveBeenCalledWith(2);
});
});
6 changes: 6 additions & 0 deletions template/pagination/pagination.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<div class="pagination"><ul>
<li ng-class="{disabled: noPrevious()}"><a ng-click="selectPrevious()">Previous</a></li>
<li ng-repeat="page in pages" ng-class="{active: isActive(page)}"><a ng-click="selectPage(page)">{{page}}</a></li>
<li ng-class="{disabled: noNext()}"><a ng-click="selectNext()">Next</a></li>
</ul>
</div

0 comments on commit 7c552ca

Please sign in to comment.