diff --git a/src/pagination/pagination.js b/src/pagination/pagination.js
index b66bab5aba..25cad7f524 100644
--- a/src/pagination/pagination.js
+++ b/src/pagination/pagination.js
@@ -1,19 +1,33 @@
angular.module('ui.bootstrap.pagination', [])
-.directive('pagination', function() {
+.constant('paginationConfig', {
+ boundary: false,
+ firstText: 'First',
+ previousText: 'Previous',
+ nextText: 'Next',
+ lastText: 'Last'
+})
+
+.directive('pagination', ['paginationConfig', function(paginationConfig) {
return {
restrict: 'EA',
scope: {
numPages: '=',
currentPage: '=',
maxSize: '=',
- onSelectPage: '&',
- nextText: '@',
- previousText: '@'
+ onSelectPage: '&'
},
templateUrl: 'template/pagination/pagination.html',
replace: true,
- link: function(scope) {
+ link: function(scope, element, attrs) {
+
+ // Set configuration parameters in scope
+ scope.boundary = angular.isDefined(attrs.boundary) ? scope.$eval(attrs.boundary) : paginationConfig.boundary;
+ scope.firstText = angular.isDefined(attrs.firstText) ? attrs.firstText : paginationConfig.firstText;
+ scope.previousText = angular.isDefined(attrs.previousText) ? attrs.previousText : paginationConfig.previousText;
+ scope.nextText = angular.isDefined(attrs.nextText) ? attrs.nextText : paginationConfig.nextText;
+ scope.lastText = angular.isDefined(attrs.lastText) ? attrs.lastText : paginationConfig.lastText;
+
scope.$watch('numPages + currentPage + maxSize', function() {
scope.pages = [];
@@ -63,6 +77,13 @@ angular.module('ui.bootstrap.pagination', [])
scope.selectPage(scope.currentPage+1);
}
};
+
+ scope.selectFirst = function() {
+ scope.selectPage(1);
+ };
+ scope.selectLast = function() {
+ scope.selectPage(scope.numPages);
+ };
}
};
-});
\ No newline at end of file
+}]);
\ No newline at end of file
diff --git a/src/pagination/test/pagination.spec.js b/src/pagination/test/pagination.spec.js
index 356168432a..98b37998f0 100644
--- a/src/pagination/test/pagination.spec.js
+++ b/src/pagination/test/pagination.spec.js
@@ -1,5 +1,5 @@
describe('pagination directive', function () {
- var $rootScope, element;
+ var $rootScope, element, position;
beforeEach(module('ui.bootstrap.pagination'));
beforeEach(module('template/pagination/pagination.html'));
beforeEach(inject(function(_$compile_, _$rootScope_) {
@@ -9,28 +9,44 @@ describe('pagination directive', function () {
$rootScope.currentPage = 3;
element = $compile('')($rootScope);
$rootScope.$digest();
+ position = {
+ first: 0,
+ previous: 1,
+ next: -2,
+ last: -1
+ };
}));
it('has a "pagination" css class', function() {
expect(element.hasClass('pagination')).toBe(true);
});
- it('contains one ul and num-pages + 2 li elements', function() {
+ it('contains one ul and num-pages + 4 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');
+ expect(element.find('li').length).toBe(9);
+ expect(element.find('li').eq(position.previous).text()).toBe('Previous');
+ expect(element.find('li').eq(position.next).text()).toBe('Next');
+ });
+
+ it('has first and last li hidden', function() {
+ var firstLiEl = element.find('li').eq(position.first);
+ var lastLiEl = element.find('li').eq(position.last);
+
+ expect(firstLiEl.text()).toBe('First');
+ expect(firstLiEl.css('display')).toBe('none');
+ expect(lastLiEl.text()).toBe('Last');
+ expect(lastLiEl.css('display')).toBe('none');
});
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);
+ for(var i=position.previous + 1; i<=$rootScope.numPages;i++) {
+ expect(lis.eq(i).text()).toEqual(''+(i-1));
}
});
it('sets the current-page to be active', function() {
- var currentPageItem = element.find('li').eq($rootScope.currentPage);
+ var currentPageItem = element.find('li').eq($rootScope.currentPage + 1);
expect(currentPageItem.hasClass('active')).toBe(true);
});
@@ -49,28 +65,28 @@ describe('pagination directive', function () {
});
it('changes currentPage if a page link is clicked', function() {
- var page2 = element.find('li').eq(2).find('a');
+ var page2 = element.find('li').eq(3).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);
+ var previous = element.find('li').eq(position.previous).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);
+ var next = element.find('li').eq(position.next).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);
+ var previous = element.find('li').eq(position.previous).find('a').eq(0);
$rootScope.currentPage = 1;
$rootScope.$digest();
previous.click();
@@ -91,7 +107,7 @@ describe('pagination directive', function () {
$rootScope.selectPageHandler = jasmine.createSpy('selectPageHandler');
element = $compile('')($rootScope);
$rootScope.$digest();
- var page2 = element.find('li').eq(2).find('a').eq(0);
+ var page2 = element.find('li').eq(3).find('a').eq(0);
page2.click();
$rootScope.$digest();
expect($rootScope.selectPageHandler).toHaveBeenCalledWith(2);
@@ -100,9 +116,9 @@ describe('pagination directive', function () {
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');
+ expect(element.find('li').length).toBe(12);
+ expect(element.find('li').eq(position.previous).text()).toBe('Previous');
+ expect(element.find('li').eq(position.next).text()).toBe('Next');
});
it('sets the current page to the last page if the numPages is changed to less than the current page', function() {
@@ -111,14 +127,14 @@ describe('pagination directive', function () {
$rootScope.$digest();
$rootScope.numPages = 2;
$rootScope.$digest();
- expect(element.find('li').length).toBe(4);
+ expect(element.find('li').length).toBe(6);
expect($rootScope.currentPage).toBe(2);
expect($rootScope.selectPageHandler).toHaveBeenCalledWith(2);
});
});
describe('pagination directive with max size option', function () {
- var $rootScope, element;
+ var $rootScope, element, position;
beforeEach(module('ui.bootstrap.pagination'));
beforeEach(module('template/pagination/pagination.html'));
beforeEach(inject(function(_$compile_, _$rootScope_) {
@@ -129,34 +145,40 @@ describe('pagination directive with max size option', function () {
$rootScope.maxSize = 5;
element = $compile('')($rootScope);
$rootScope.$digest();
+ position = {
+ first: 0,
+ previous: 1,
+ next: -2,
+ last: -1
+ };
}));
- it('contains one ul and maxsize + 2 li elements', function() {
+ it('contains one ul and maxsize + 4 li elements', function() {
expect(element.find('ul').length).toBe(1);
- expect(element.find('li').length).toBe($rootScope.maxSize + 2);
- expect(element.find('li').eq(0).text()).toBe('Previous');
- expect(element.find('li').eq(-1).text()).toBe('Next');
+ expect(element.find('li').length).toBe($rootScope.maxSize + 4);
+ expect(element.find('li').eq(position.previous).text()).toBe('Previous');
+ expect(element.find('li').eq(position.next).text()).toBe('Next');
});
it('shows the page number even if it can\'t be shown in the middle', function() {
$rootScope.currentPage = 1;
$rootScope.$digest();
- var currentPageItem = element.find('li').eq(1);
+ var currentPageItem = element.find('li').eq(2);
expect(currentPageItem.hasClass('active')).toBe(true);
$rootScope.currentPage = 10;
$rootScope.$digest();
- currentPageItem = element.find('li').eq(-2);
+ currentPageItem = element.find('li').eq(-3);
expect(currentPageItem.hasClass('active')).toBe(true);
});
it('shows the page number in middle after the next link is clicked', function() {
$rootScope.currentPage = 6;
$rootScope.$digest();
- var next = element.find('li').eq(-1).find('a').eq(0);
+ var next = element.find('li').eq(position.next).find('a').eq(0);
next.click();
expect($rootScope.currentPage).toBe(7);
- var currentPageItem = element.find('li').eq(3);
+ var currentPageItem = element.find('li').eq(4);
expect(currentPageItem.hasClass('active')).toBe(true);
expect(parseInt(currentPageItem.text(), 10)).toBe($rootScope.currentPage);
});
@@ -164,10 +186,10 @@ describe('pagination directive with max size option', function () {
it('shows the page number in middle after the prev link is clicked', function() {
$rootScope.currentPage = 7;
$rootScope.$digest();
- var prev = element.find('li').eq(0).find('a').eq(0);
+ var prev = element.find('li').eq(position.previous).find('a').eq(0);
prev.click();
expect($rootScope.currentPage).toBe(6);
- var currentPageItem = element.find('li').eq(3);
+ var currentPageItem = element.find('li').eq(4);
expect(currentPageItem.hasClass('active')).toBe(true);
expect(parseInt(currentPageItem.text(), 10)).toBe($rootScope.currentPage);
});
@@ -175,13 +197,13 @@ describe('pagination directive with max size option', function () {
it('changes pagination bar size when max-size value changed', function() {
$rootScope.maxSize = 7;
$rootScope.$digest();
- expect(element.find('li').length).toBe(9);
+ expect(element.find('li').length).toBe(11);
});
it('sets the pagination bar size to num-pages, if max-size is greater than num-pages ', function() {
$rootScope.maxSize = 15;
$rootScope.$digest();
- expect(element.find('li').length).toBe(12);
+ expect(element.find('li').length).toBe(14);
});
it('should not change value of max-size expression, if max-size is greater than num-pages ', function() {
@@ -192,8 +214,86 @@ describe('pagination directive with max size option', function () {
});
-describe('pagination custom', function () {
- var $rootScope, element;
+describe('pagination bypass default configuration', function () {
+ var $rootScope, element, position;
+ 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('')($rootScope);
+ $rootScope.$digest();
+ position = {
+ first: 0,
+ previous: 1,
+ next: -2,
+ last: -1
+ };
+ }));
+
+ it('should change paging text from attributes', function () {
+ expect(element.find('li').eq(position.first).text()).toBe('<<');
+ expect(element.find('li').eq(position.previous).text()).toBe('<');
+ expect(element.find('li').eq(position.next).text()).toBe('>');
+ expect(element.find('li').eq(position.last).text()).toBe('>>');
+ });
+
+ it('should display first & last button', function () {
+ expect(element.find('li').eq(position.first).css('display')).not.toBe('none');
+ expect(element.find('li').eq(position.last).css('display')).not.toBe('none');
+ });
+
+});
+
+
+describe('setting paginationConfig', function() {
+ var $rootScope, element, position;
+ var originalConfig = {};
+ beforeEach(module('ui.bootstrap.pagination'));
+ beforeEach(module('template/pagination/pagination.html'));
+ beforeEach(inject(function(_$compile_, _$rootScope_, paginationConfig) {
+ $compile = _$compile_;
+ $rootScope = _$rootScope_;
+ $rootScope.numPages = 5;
+ $rootScope.currentPage = 3;
+ angular.extend(originalConfig, paginationConfig);
+ paginationConfig.boundary = true;
+ paginationConfig.firstText = 'FI';
+ paginationConfig.previousText = 'PR';
+ paginationConfig.nextText = 'NE';
+ paginationConfig.lastText = 'LA';
+ element = $compile('')($rootScope);
+ $rootScope.$digest();
+ position = {
+ first: 0,
+ previous: 1,
+ next: -2,
+ last: -1
+ };
+ }));
+ afterEach(inject(function(paginationConfig) {
+ // return it to the original state
+ angular.extend(paginationConfig, originalConfig);
+ }));
+
+ it('should change paging text', function () {
+ expect(element.find('li').eq(position.first).text()).toBe('FI');
+ expect(element.find('li').eq(position.previous).text()).toBe('PR');
+ expect(element.find('li').eq(position.next).text()).toBe('NE');
+ expect(element.find('li').eq(position.last).text()).toBe('LA');
+ });
+
+ it('should display first & last button', function () {
+ expect(element.find('li').eq(position.first).css('display')).not.toBe('none');
+ expect(element.find('li').eq(position.last).css('display')).not.toBe('none');
+ });
+});
+
+
+describe('pagination with first & last elements', function () {
+ var $rootScope, element, position;
beforeEach(module('ui.bootstrap.pagination'));
beforeEach(module('template/pagination/pagination.html'));
beforeEach(inject(function(_$compile_, _$rootScope_) {
@@ -201,13 +301,90 @@ describe('pagination custom', function () {
$rootScope = _$rootScope_;
$rootScope.numPages = 5;
$rootScope.currentPage = 3;
- element = $compile('')($rootScope);
+ element = $compile('')($rootScope);
$rootScope.$digest();
+ position = {
+ first: 0,
+ previous: 1,
+ next: -2,
+ last: -1
+ };
}));
- it('should change paging text from attribute', function () {
- expect(element.find('li').eq(0).text()).toBe('<<');
- expect(element.find('li').eq(-1).text()).toBe('>>');
+
+ it('contains one ul and num-pages + 4 li elements', function() {
+ expect(element.find('ul').length).toBe(1);
+ expect(element.find('li').length).toBe(9);
+ expect(element.find('li').eq(position.previous).text()).toBe('Previous');
+ expect(element.find('li').eq(position.next).text()).toBe('Next');
+ expect(element.find('li').eq(position.first).text()).toBe('First');
+ expect(element.find('li').eq(position.last).text()).toBe('Last');
+ });
+
+ it('has first and last li visible', function() {
+ var firstLiEl = element.find('li').eq(position.first);
+ var lastLiEl = element.find('li').eq(position.last);
+
+ expect(firstLiEl.text()).toBe('First');
+ expect(firstLiEl.css('display')).not.toBe('none');
+ expect(lastLiEl.text()).toBe('Last');
+ expect(lastLiEl.css('display')).not.toBe('none');
+ });
+
+
+ it('disables the "first" link if current-page is 1', function() {
+ $rootScope.currentPage = 1;
+ $rootScope.$digest();
+ var firstPageItem = element.find('li').eq(position.first);
+ expect(firstPageItem.hasClass('disabled')).toBe(true);
+ });
+
+ it('disables the "last" link if current-page is num-pages', function() {
+ $rootScope.currentPage = 5;
+ $rootScope.$digest();
+ var lastPageItem = element.find('li').eq(position.last);
+ expect(lastPageItem.hasClass('disabled')).toBe(true);
+ });
+
+
+ it('changes currentPage if the "first" link is clicked', function() {
+ var first = element.find('li').eq(position.first).find('a').eq(0);
+ first.click();
+ $rootScope.$digest();
+ expect($rootScope.currentPage).toBe(1);
+ });
+
+ it('changes currentPage if the "last" link is clicked', function() {
+ var last = element.find('li').eq(position.last).find('a').eq(0);
+ last.click();
+ $rootScope.$digest();
+ expect($rootScope.currentPage).toBe($rootScope.numPages);
+ });
+
+ it('does not change the current page on "first" click if already at first page', function() {
+ var first = element.find('li').eq(position.first).find('a').eq(0);
+ $rootScope.currentPage = 1;
+ $rootScope.$digest();
+ first.click();
+ $rootScope.$digest();
+ expect($rootScope.currentPage).toBe(1);
+ });
+
+ it('does not change the current page on "last" click if already at last page', function() {
+ var last = element.find('li').eq(position.last).find('a').eq(0);
+ $rootScope.currentPage = $rootScope.numPages;
+ $rootScope.$digest();
+ last.click();
+ $rootScope.$digest();
+ expect($rootScope.currentPage).toBe($rootScope.numPages);
+ });
+
+ it('changes text from attributes', function() {
+ element = $compile('')($rootScope);
+ $rootScope.$digest();
+
+ expect(element.find('li').eq(position.first).text()).toBe('<<<');
+ expect(element.find('li').eq(position.last).text()).toBe('>>>');
});
});
diff --git a/template/pagination/pagination.html b/template/pagination/pagination.html
index 4c0d40baac..8aba3fe10c 100644
--- a/template/pagination/pagination.html
+++ b/template/pagination/pagination.html
@@ -1,6 +1,8 @@