diff --git a/src/pagination/docs/demo.html b/src/pagination/docs/demo.html index c21d066822..16ec3ac447 100644 --- a/src/pagination/docs/demo.html +++ b/src/pagination/docs/demo.html @@ -1,19 +1,19 @@

Default

- - - - + + + +
The selected page no: {{currentPage}}

Pager

- +

Limit the maximum visible buttons

- - + +
Page: {{bigCurrentPage}} / {{numPages}}
diff --git a/src/pagination/docs/readme.md b/src/pagination/docs/readme.md index bdab246c67..07c89d5ed3 100644 --- a/src/pagination/docs/readme.md +++ b/src/pagination/docs/readme.md @@ -3,7 +3,7 @@ A lightweight pagination directive that is focused on ... providing pagination & ### Pagination Settings ### -Settings can be provided as attributes in the `` or globally configured through the `paginationConfig`. +Settings can be provided as attributes in the `` or globally configured through the `uibPaginationConfig`. * `ng-change` : @@ -67,7 +67,7 @@ Settings can be provided as attributes in the `` or globally configu ### Pager Settings ### -Settings can be provided as attributes in the `` or globally configured through the `pagerConfig`. +Settings can be provided as attributes in the `` or globally configured through the `uibPagerConfig`. For `ng-model`, `total-items`, `items-per-page` and `num-pages` see pagination settings. Other settings are: * `align` diff --git a/src/pagination/pagination.js b/src/pagination/pagination.js index e7fcfae273..ed7678d5e2 100644 --- a/src/pagination/pagination.js +++ b/src/pagination/pagination.js @@ -1,5 +1,5 @@ angular.module('ui.bootstrap.pagination', []) -.controller('PaginationController', ['$scope', '$attrs', '$parse', function($scope, $attrs, $parse) { +.controller('UibPaginationController', ['$scope', '$attrs', '$parse', function($scope, $attrs, $parse) { var self = this, ngModelCtrl = { $setViewValue: angular.noop }, // nullModelCtrl setNumPages = $attrs.numPages ? $parse($attrs.numPages).assign : angular.noop; @@ -73,7 +73,7 @@ angular.module('ui.bootstrap.pagination', []) }; }]) -.constant('paginationConfig', { +.constant('uibPaginationConfig', { itemsPerPage: 10, boundaryLinks: false, directionLinks: true, @@ -84,7 +84,7 @@ angular.module('ui.bootstrap.pagination', []) rotate: true }) -.directive('pagination', ['$parse', 'paginationConfig', function($parse, paginationConfig) { +.directive('uibPagination', ['$parse', 'uibPaginationConfig', function($parse, paginationConfig) { return { restrict: 'EA', scope: { @@ -95,8 +95,8 @@ angular.module('ui.bootstrap.pagination', []) lastText: '@', ngDisabled:'=' }, - require: ['pagination', '?ngModel'], - controller: 'PaginationController', + require: ['uibPagination', '?ngModel'], + controller: 'UibPaginationController', controllerAs: 'pagination', templateUrl: function(element, attrs) { return attrs.templateUrl || 'template/pagination/pagination.html'; @@ -194,14 +194,170 @@ angular.module('ui.bootstrap.pagination', []) }; }]) -.constant('pagerConfig', { +.constant('uibPagerConfig', { itemsPerPage: 10, previousText: '« Previous', nextText: 'Next »', align: true }) -.directive('pager', ['pagerConfig', function(pagerConfig) { +.directive('uibPager', ['uibPagerConfig', function(pagerConfig) { + return { + restrict: 'EA', + scope: { + totalItems: '=', + previousText: '@', + nextText: '@', + ngDisabled: '=' + }, + require: ['uibPager', '?ngModel'], + controller: 'UibPaginationController', + controllerAs: 'pagination', + templateUrl: function(element, attrs) { + return attrs.templateUrl || 'template/pagination/pager.html'; + }, + replace: true, + link: function(scope, element, attrs, ctrls) { + var paginationCtrl = ctrls[0], ngModelCtrl = ctrls[1]; + + if (!ngModelCtrl) { + return; // do nothing if no ng-model + } + + scope.align = angular.isDefined(attrs.align) ? scope.$parent.$eval(attrs.align) : pagerConfig.align; + paginationCtrl.init(ngModelCtrl, pagerConfig); + } + }; +}]); + +/* Deprecated Pagination Below */ + +angular.module('ui.bootstrap.pagination') +.value('$paginationSuppressWarning', false) +.controller('PaginationController', ['$scope', '$attrs', '$parse', '$controller', '$element', '$log', '$paginationSuppressWarning', function($scope, $attrs, $parse, $controller, $element, $log, $paginationSuppressWarning) { + if (!$paginationSuppressWarning) { + $log.warn('PaginationController is now deprecated. Use UibPaginationController instead.'); + } + return $controller('UibPaginationController', { + $scope: $scope, + $element: $element, + $attrs: $attrs + }); +}]) +.directive('pagination', ['$parse', 'uibPaginationConfig', '$log', '$paginationSuppressWarning', function($parse, paginationConfig, $log, $paginationSuppressWarning) { + return { + restrict: 'EA', + scope: { + totalItems: '=', + firstText: '@', + previousText: '@', + nextText: '@', + lastText: '@', + ngDisabled:'=' + }, + require: ['pagination', '?ngModel'], + controller: 'PaginationController', + controllerAs: 'pagination', + templateUrl: function(element, attrs) { + return attrs.templateUrl || 'template/pagination/pagination.html'; + }, + replace: true, + link: function(scope, element, attrs, ctrls) { + if (!$paginationSuppressWarning) { + $log.warn('pagination is now deprecated. Use uib-pagination instead.'); + } + var paginationCtrl = ctrls[0], ngModelCtrl = ctrls[1]; + + if (!ngModelCtrl) { + return; // do nothing if no ng-model + } + + // Setup configuration parameters + var maxSize = angular.isDefined(attrs.maxSize) ? scope.$parent.$eval(attrs.maxSize) : paginationConfig.maxSize, + rotate = angular.isDefined(attrs.rotate) ? scope.$parent.$eval(attrs.rotate) : paginationConfig.rotate; + scope.boundaryLinks = angular.isDefined(attrs.boundaryLinks) ? scope.$parent.$eval(attrs.boundaryLinks) : paginationConfig.boundaryLinks; + scope.directionLinks = angular.isDefined(attrs.directionLinks) ? scope.$parent.$eval(attrs.directionLinks) : paginationConfig.directionLinks; + + paginationCtrl.init(ngModelCtrl, paginationConfig); + + if (attrs.maxSize) { + scope.$parent.$watch($parse(attrs.maxSize), function(value) { + maxSize = parseInt(value, 10); + paginationCtrl.render(); + }); + } + + // Create page object used in template + function makePage(number, text, isActive) { + return { + number: number, + text: text, + active: isActive + }; + } + + function getPages(currentPage, totalPages) { + var pages = []; + + // Default page limits + var startPage = 1, endPage = totalPages; + var isMaxSized = angular.isDefined(maxSize) && maxSize < totalPages; + + // recompute if maxSize + if (isMaxSized) { + if (rotate) { + // Current page is displayed in the middle of the visible ones + startPage = Math.max(currentPage - Math.floor(maxSize/2), 1); + endPage = startPage + maxSize - 1; + + // Adjust if limit is exceeded + if (endPage > totalPages) { + endPage = totalPages; + startPage = endPage - maxSize + 1; + } + } else { + // Visible pages are paginated with maxSize + startPage = ((Math.ceil(currentPage / maxSize) - 1) * maxSize) + 1; + + // Adjust last page if limit is exceeded + endPage = Math.min(startPage + maxSize - 1, totalPages); + } + } + + // Add page number links + for (var number = startPage; number <= endPage; number++) { + var page = makePage(number, number, number === currentPage); + pages.push(page); + } + + // Add links to move between page sets + if (isMaxSized && ! rotate) { + if (startPage > 1) { + var previousPageSet = makePage(startPage - 1, '...', false); + pages.unshift(previousPageSet); + } + + if (endPage < totalPages) { + var nextPageSet = makePage(endPage + 1, '...', false); + pages.push(nextPageSet); + } + } + + return pages; + } + + var originalRender = paginationCtrl.render; + paginationCtrl.render = function() { + originalRender(); + if (scope.page > 0 && scope.page <= scope.totalPages) { + scope.pages = getPages(scope.page, scope.totalPages); + } + }; + } + }; +}]) + +.directive('pager', ['uibPagerConfig', '$log', '$paginationSuppressWarning', function(pagerConfig, $log, $paginationSuppressWarning) { return { restrict: 'EA', scope: { @@ -218,6 +374,9 @@ angular.module('ui.bootstrap.pagination', []) }, replace: true, link: function(scope, element, attrs, ctrls) { + if (!$paginationSuppressWarning) { + $log.warn('pager is now deprecated. Use uib-pager instead.'); + } var paginationCtrl = ctrls[0], ngModelCtrl = ctrls[1]; if (!ngModelCtrl) { diff --git a/src/pagination/test/pager.spec.js b/src/pagination/test/pager.spec.js index 7527e83a76..3756d7062a 100644 --- a/src/pagination/test/pager.spec.js +++ b/src/pagination/test/pager.spec.js @@ -10,7 +10,7 @@ describe('pager directive', function() { $document = _$document_; $templateCache = _$templateCache_; body = $document.find('body'); - element = $compile('')($rootScope); + element = $compile('')($rootScope); $rootScope.$digest(); })); @@ -56,10 +56,10 @@ describe('pager directive', function() { it('exposes the controller on the template', function() { $templateCache.put('template/pagination/pager.html', '
{{pagination.text}}
'); - element = $compile('')($rootScope); + element = $compile('')($rootScope); $rootScope.$digest(); - var ctrl = element.controller('pager'); + var ctrl = element.controller('uibPager'); expect(ctrl).toBeDefined(); ctrl.text = 'foo'; @@ -102,7 +102,7 @@ describe('pager directive', function() { it('executes the `ng-change` expression when an element is clicked', function() { $rootScope.selectPageHandler = jasmine.createSpy('selectPageHandler'); - element = $compile('')($rootScope); + element = $compile('')($rootScope); $rootScope.$digest(); clickPaginationEl(-1); @@ -156,7 +156,7 @@ describe('pager directive', function() { describe('`items-per-page`', function() { beforeEach(function() { $rootScope.perpage = 5; - element = $compile('')($rootScope); + element = $compile('')($rootScope); $rootScope.$digest(); }); @@ -190,7 +190,7 @@ describe('pager directive', function() { describe('`num-pages`', function() { beforeEach(function() { $rootScope.numpg = null; - element = $compile('')($rootScope); + element = $compile('')($rootScope); $rootScope.$digest(); }); @@ -201,17 +201,17 @@ describe('pager directive', function() { describe('setting `pagerConfig`', function() { var originalConfig = {}; - beforeEach(inject(function(pagerConfig) { - angular.extend(originalConfig, pagerConfig); - pagerConfig.previousText = 'PR'; - pagerConfig.nextText = 'NE'; - pagerConfig.align = false; - element = $compile('')($rootScope); + beforeEach(inject(function(uibPagerConfig) { + angular.extend(originalConfig, uibPagerConfig); + uibPagerConfig.previousText = 'PR'; + uibPagerConfig.nextText = 'NE'; + uibPagerConfig.align = false; + element = $compile('')($rootScope); $rootScope.$digest(); })); - afterEach(inject(function(pagerConfig) { + afterEach(inject(function(uibPagerConfig) { // return it to the original state - angular.extend(pagerConfig, originalConfig); + angular.extend(uibPagerConfig, originalConfig); })); it('should change paging text', function() { @@ -227,7 +227,7 @@ describe('pager directive', function() { describe('override configuration from attributes', function() { beforeEach(function() { - element = $compile('')($rootScope); + element = $compile('')($rootScope); $rootScope.$digest(); }); @@ -248,7 +248,7 @@ describe('pager directive', function() { it('changes "previous" & "next" text from interpolated attributes', function() { $rootScope.previousText = '<<'; $rootScope.nextText = '>>'; - element = $compile('')($rootScope); + element = $compile('')($rootScope); $rootScope.$digest(); expect(getPaginationEl(0).text()).toBe('<<'); @@ -259,7 +259,7 @@ describe('pager directive', function() { it('disables the component when ng-disabled is true', function() { $rootScope.disable = true; - element = $compile('')($rootScope); + element = $compile('')($rootScope); $rootScope.$digest(); updateCurrentPage(2); @@ -279,3 +279,33 @@ describe('pager directive', function() { expect(getPaginationEl(-1)).toHaveClass('disabled'); }); }); + +describe('pager deprecation', function() { + beforeEach(module('ui.bootstrap.pagination')); + beforeEach(module('template/pagination/pager.html')); + + it('should suppress warning', function() { + module(function($provide) { + $provide.value('$paginationSuppressWarning', true); + }); + + inject(function($compile, $log, $rootScope) { + spyOn($log, 'warn'); + + var element = $compile('')($rootScope); + $rootScope.$digest(); + expect($log.warn.calls.count()).toBe(0); + }); + }); + + it('should give warning by default', inject(function($compile, $log, $rootScope) { + spyOn($log, 'warn'); + + var element = $compile('')($rootScope); + $rootScope.$digest(); + + expect($log.warn.calls.count()).toBe(2); + expect($log.warn.calls.argsFor(0)).toEqual(['PaginationController is now deprecated. Use UibPaginationController instead.']); + expect($log.warn.calls.argsFor(1)).toEqual(['pager is now deprecated. Use uib-pager instead.']); + })); +}); \ No newline at end of file diff --git a/src/pagination/test/pagination.spec.js b/src/pagination/test/pagination.spec.js index ee748e46bf..a3ef25097f 100644 --- a/src/pagination/test/pagination.spec.js +++ b/src/pagination/test/pagination.spec.js @@ -11,7 +11,7 @@ describe('pagination directive', function() { $document = _$document_; $templateCache = _$templateCache_; body = $document.find('body'); - element = $compile('')($rootScope); + element = $compile('')($rootScope); $rootScope.$digest(); })); @@ -49,10 +49,10 @@ describe('pagination directive', function() { $templateCache.put('template/pagination/pagination.html', '
{{pagination.randomText}}
'); var scope = $rootScope.$new(); - element = $compile('')(scope); + element = $compile('')(scope); $rootScope.$digest(); - var ctrl = element.controller('pagination'); + var ctrl = element.controller('uibPagination'); expect(ctrl).toBeDefined(); @@ -66,7 +66,7 @@ describe('pagination directive', function() { $templateCache.put('foo/bar.html', '
baz
'); var scope = $rootScope.$new(); - element = $compile('')(scope); + element = $compile('')(scope); $rootScope.$digest(); expect(element.html()).toBe('baz'); @@ -204,7 +204,7 @@ describe('pagination directive', function() { describe('`items-per-page`', function() { beforeEach(function() { $rootScope.perpage = 5; - element = $compile('')($rootScope); + element = $compile('')($rootScope); $rootScope.$digest(); }); @@ -247,7 +247,7 @@ describe('pagination directive', function() { describe('executes `ng-change` expression', function() { beforeEach(function() { $rootScope.selectPageHandler = jasmine.createSpy('selectPageHandler'); - element = $compile('')($rootScope); + element = $compile('')($rootScope); $rootScope.$digest(); }); @@ -277,7 +277,7 @@ describe('pagination directive', function() { $rootScope.total = 98; // 10 pages $rootScope.currentPage = 3; $rootScope.maxSize = 5; - element = $compile('')($rootScope); + element = $compile('')($rootScope); $rootScope.$digest(); }); @@ -359,7 +359,7 @@ describe('pagination directive', function() { $rootScope.currentPage = 7; $rootScope.maxSize = 5; $rootScope.rotate = false; - element = $compile('')($rootScope); + element = $compile('')($rootScope); $rootScope.$digest(); }); @@ -418,7 +418,7 @@ describe('pagination directive', function() { describe('pagination directive with `boundary-links`', function() { beforeEach(function() { - element = $compile('')($rootScope); + element = $compile('')($rootScope); $rootScope.$digest(); }); @@ -473,7 +473,7 @@ describe('pagination directive', function() { }); it('changes "first" & "last" text from attributes', function() { - element = $compile('')($rootScope); + element = $compile('')($rootScope); $rootScope.$digest(); expect(getPaginationEl(0).text()).toBe('<<<'); @@ -481,7 +481,7 @@ describe('pagination directive', function() { }); it('changes "previous" & "next" text from attributes', function() { - element = $compile('')($rootScope); + element = $compile('')($rootScope); $rootScope.$digest(); expect(getPaginationEl(1).text()).toBe('<<'); @@ -491,7 +491,7 @@ describe('pagination directive', function() { it('changes "first" & "last" text from interpolated attributes', function() { $rootScope.myfirstText = '<<<'; $rootScope.mylastText = '>>>'; - element = $compile('')($rootScope); + element = $compile('')($rootScope); $rootScope.$digest(); expect(getPaginationEl(0).text()).toBe('<<<'); @@ -501,7 +501,7 @@ describe('pagination directive', function() { it('changes "previous" & "next" text from interpolated attributes', function() { $rootScope.previousText = '<<'; $rootScope.nextText = '>>'; - element = $compile('')($rootScope); + element = $compile('')($rootScope); $rootScope.$digest(); expect(getPaginationEl(1).text()).toBe('<<'); @@ -537,7 +537,7 @@ describe('pagination directive', function() { describe('pagination directive with just number links', function() { beforeEach(function() { - element = $compile('')($rootScope); + element = $compile('')($rootScope); $rootScope.$digest(); }); @@ -589,7 +589,7 @@ describe('pagination directive', function() { describe('with just boundary & number links', function() { beforeEach(function() { $rootScope.directions = false; - element = $compile('')($rootScope); + element = $compile('')($rootScope); $rootScope.$digest(); }); @@ -621,7 +621,7 @@ describe('pagination directive', function() { describe('`num-pages`', function () { beforeEach(function() { $rootScope.numpg = null; - element = $compile('')($rootScope); + element = $compile('')($rootScope); $rootScope.$digest(); }); @@ -648,13 +648,13 @@ describe('pagination directive', function() { describe('setting `paginationConfig`', function() { var originalConfig, paginationConfig; - beforeEach(inject(function(_paginationConfig_) { - originalConfig = angular.copy(_paginationConfig_); - paginationConfig = _paginationConfig_; + beforeEach(inject(function(_uibPaginationConfig_) { + originalConfig = angular.copy(_uibPaginationConfig_); + paginationConfig = _uibPaginationConfig_; })); - afterEach(inject(function(paginationConfig) { + afterEach(inject(function(_uibPaginationConfig_) { // return it to the original stat - angular.copy(originalConfig, paginationConfig); + angular.copy(originalConfig, _uibPaginationConfig_); })); it('should change paging text', function() { @@ -664,7 +664,7 @@ describe('pagination directive', function() { paginationConfig.previousText = 'PR'; paginationConfig.nextText = 'NE'; paginationConfig.lastText = 'LA'; - element = $compile('')($rootScope); + element = $compile('')($rootScope); $rootScope.$digest(); expect(getPaginationEl(0).text()).toBe('FI'); @@ -675,7 +675,7 @@ describe('pagination directive', function() { it('contains number of pages + 2 li elements', function() { paginationConfig.itemsPerPage = 5; - element = $compile('')($rootScope); + element = $compile('')($rootScope); $rootScope.$digest(); expect(getPaginationBarSize()).toBe(12); @@ -683,7 +683,7 @@ describe('pagination directive', function() { it('should take maxSize defaults into account', function() { paginationConfig.maxSize = 2; - element = $compile('')($rootScope); + element = $compile('')($rootScope); $rootScope.$digest(); expect(getPaginationBarSize()).toBe(4); @@ -692,7 +692,7 @@ describe('pagination directive', function() { describe('override configuration from attributes', function() { beforeEach(function() { - element = $compile('')($rootScope); + element = $compile('')($rootScope); $rootScope.$digest(); }); @@ -710,7 +710,7 @@ describe('pagination directive', function() { describe('disabled with ngDisable', function() { beforeEach(function() { - element = $compile('')($rootScope); + element = $compile('')($rootScope); $rootScope.currentPage = 3; $rootScope.$digest(); }); @@ -734,3 +734,33 @@ describe('pagination directive', function() { }); }); }); + +describe('pagination deprecation', function() { + beforeEach(module('ui.bootstrap.pagination')); + beforeEach(module('template/pagination/pagination.html')); + + it('should suppress warning', function() { + module(function($provide) { + $provide.value('$paginationSuppressWarning', true); + }); + + inject(function($compile, $log, $rootScope) { + spyOn($log, 'warn'); + + var element = $compile('')($rootScope); + $rootScope.$digest(); + expect($log.warn.calls.count()).toBe(0); + }); + }); + + it('should give warning by default', inject(function($compile, $log, $rootScope) { + spyOn($log, 'warn'); + + var element = $compile('')($rootScope); + $rootScope.$digest(); + + expect($log.warn.calls.count()).toBe(2); + expect($log.warn.calls.argsFor(0)).toEqual(['PaginationController is now deprecated. Use UibPaginationController instead.']); + expect($log.warn.calls.argsFor(1)).toEqual(['pagination is now deprecated. Use uib-pagination instead.']); + })); +});