├── .gitignore
├── Gruntfile.js
├── README.md
├── angular-pagination.js
├── angular-pagination.min.js
├── bower.json
├── examples
├── base
│ ├── index.html
│ ├── scripts.js
│ ├── tpl-1.html
│ ├── tpl-2.html
│ ├── tpl-3.html
│ └── tpl-4.html
├── directive-1
│ ├── index.html
│ ├── scripts.js
│ └── tpl-4.html
└── directive-2
│ ├── index.html
│ ├── scripts.js
│ └── tpl-4.html
├── license.txt
├── package.json
└── src
└── pagination.js
/.gitignore:
--------------------------------------------------------------------------------
1 | .temp
2 | .idea
3 | node_modules
4 | bower_components
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function(grunt) {
2 |
3 | grunt.initConfig({
4 | pkg: grunt.file.readJSON('package.json'),
5 |
6 | banner: '/*\n' +
7 | ' <%= pkg.name %> v<%= pkg.version %>\n' +
8 | ' <%= pkg.homepage %>\n' +
9 | '*/\n',
10 |
11 | clean: {
12 | working: {
13 | src: ['angular-pagination.*']
14 | }
15 | },
16 |
17 | uglify: {
18 | js: {
19 | src: ['src/pagination.js'],
20 | dest: 'angular-pagination.min.js',
21 | options: {
22 | banner: '<%= banner %>'
23 | }
24 | }
25 | },
26 |
27 | concat: {
28 | js: {
29 | options: {
30 | banner: '<%= banner %>',
31 | stripBanners: true
32 | },
33 | src: ['src/pagination.js'],
34 | dest: 'angular-pagination.js'
35 | }
36 | }
37 | });
38 |
39 | grunt.loadNpmTasks('grunt-contrib-clean');
40 | grunt.loadNpmTasks('grunt-contrib-copy');
41 | grunt.loadNpmTasks('grunt-contrib-uglify');
42 | grunt.loadNpmTasks('grunt-contrib-concat');
43 |
44 | grunt.registerTask('default', ['clean', 'concat', 'uglify']);
45 | };
46 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #Angular Pagination
2 |
3 | ## About
4 |
5 | **Angular Pagination** is a module for the [AngularJS](http://angularjs.org/) framework.
6 |
7 | ## Usage
8 | Simple example:
9 | ```js
10 | angular
11 |
12 | .module('app', ['angularPagination'])
13 |
14 | .controller('AppController', function($scope, Pagination) {
15 | var pagination = $scope.pagination = Pagination.create({
16 | itemsPerPage: 10,
17 | itemsCount: 100,
18 | maxNumbers: 5
19 | });
20 |
21 | pagination.onChange = function(page) {
22 | console.info('page=', page);
23 | };
24 | });
25 | ```
26 | ```html
27 |
28 |
33 |
34 | ```
35 | See [demo](http://nervgh.github.io/pages/angular-pagination/examples/base) of full functionality
36 |
37 |
38 | ## Demos
39 | 1. [Example of full functionality](http://nervgh.github.io/pages/angular-pagination/examples/base)
40 | 2. [Example of directive 1](http://nervgh.github.io/pages/angular-pagination/examples/directive-1)
41 | 3. [Example of directive 2](http://nervgh.github.io/pages/angular-pagination/examples/directive-2)
42 |
--------------------------------------------------------------------------------
/angular-pagination.js:
--------------------------------------------------------------------------------
1 | /*
2 | angular-pagination v0.2.2
3 | https://github.com/nervgh/angular-pagination
4 | */
5 |
6 |
7 | angular
8 |
9 |
10 | .module('angularPagination', [])
11 |
12 |
13 | .value('paginationOptions', {
14 | itemsPerPage: 10,
15 | itemsCount: 100,
16 | maxNumbers: 5,
17 | startPage: 1,
18 | currentPage: 1
19 | })
20 |
21 |
22 | .factory('Pagination', ['paginationOptions', function(paginationOptions) {
23 | /**
24 | * Creates new pagination object
25 | * @param {Object} options
26 | * @constructor
27 | */
28 | function Pagination(options) {
29 | var defaults = angular.copy(paginationOptions);
30 | angular.extend(this, defaults, options);
31 | this.endPage = null;
32 | this.pages = [];
33 | this._lastPage = null;
34 | this.setCurrent(this.currentPage);
35 | }
36 |
37 | /**
38 | * Sets current page
39 | * @param {Number} page
40 | */
41 | Pagination.prototype.setCurrent = function(page) {
42 | this.endPage = Math.ceil(this.itemsCount / this.itemsPerPage);
43 | this.currentPage = this._fixPage(Math.floor(page));
44 | this._change(this.currentPage);
45 | this._updatePages();
46 | };
47 | /**
48 | * Returns "true" if page is current
49 | * @param {Number} page
50 | * @returns {Boolean}
51 | */
52 | Pagination.prototype.isCurrent = function(page) {
53 | return this.currentPage === page;
54 | };
55 | /**
56 | * Returns "true" if page inside of range
57 | * @param {Number} page
58 | * @returns {boolean}
59 | */
60 | Pagination.prototype.inRange = function(page) {
61 | return this.startPage <= page && this.endPage >= page;
62 | };
63 | /**
64 | * Returns "true" if page is first
65 | * @param {Number} page
66 | * @returns {Boolean}
67 | */
68 | Pagination.prototype.isFirst = function(page) {
69 | return this.startPage === page;
70 | };
71 | /**
72 | * Returns "true" if page is last
73 | * @param {Number} page
74 | * @returns {Boolean}
75 | */
76 | Pagination.prototype.isLast = function(page) {
77 | return this.endPage === page;
78 | };
79 | /**
80 | * Callback. Called when page changed
81 | * @param {Number} page
82 | */
83 | Pagination.prototype.onChange = function(page) {
84 | };
85 | /**
86 | * Fixes number of page if it outside range
87 | * @param {Number} page
88 | * @returns {number}
89 | * @private
90 | */
91 | Pagination.prototype._fixPage = function(page) {
92 | page = Math.min(page, this.endPage);
93 | page = Math.max(page, this.startPage);
94 | return page;
95 | };
96 | /**
97 | * Calls "onChange" if number of page was changed
98 | * @param {Number} page
99 | * @private
100 | */
101 | Pagination.prototype._change = function(page) {
102 | if (this._lastPage !== page) {
103 | this._lastPage = page;
104 | this.onChange(page);
105 | }
106 | };
107 | /**
108 | * Updates array of pages
109 | * @private
110 | */
111 | Pagination.prototype._updatePages = function() {
112 | var delta = Math.floor(this.maxNumbers / 2);
113 | var start = Math.max(this.currentPage - delta, this.startPage);
114 | var end = Math.min(start + this.maxNumbers - 1, this.endPage);
115 |
116 | start = this.endPage === end ? end - (this.maxNumbers - 1) : start;
117 | start = Math.max(start, this.startPage);
118 | this.pages.length = 0;
119 |
120 | for(var i = start; i <= end; i++) {
121 | this.pages.push(i);
122 | }
123 | };
124 | /**
125 | * Creates and returns a pagination object
126 | * @param {Object} options
127 | * @returns {Pagination}
128 | */
129 | Pagination.create = function(options) {
130 | return new Pagination(options);
131 | };
132 |
133 | return Pagination;
134 | }]);
135 |
--------------------------------------------------------------------------------
/angular-pagination.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | angular-pagination v0.2.2
3 | https://github.com/nervgh/angular-pagination
4 | */
5 | angular.module("angularPagination",[]).value("paginationOptions",{itemsPerPage:10,itemsCount:100,maxNumbers:5,startPage:1,currentPage:1}).factory("Pagination",["paginationOptions",function(a){function b(b){var c=angular.copy(a);angular.extend(this,c,b),this.endPage=null,this.pages=[],this._lastPage=null,this.setCurrent(this.currentPage)}return b.prototype.setCurrent=function(a){this.endPage=Math.ceil(this.itemsCount/this.itemsPerPage),this.currentPage=this._fixPage(Math.floor(a)),this._change(this.currentPage),this._updatePages()},b.prototype.isCurrent=function(a){return this.currentPage===a},b.prototype.inRange=function(a){return this.startPage<=a&&this.endPage>=a},b.prototype.isFirst=function(a){return this.startPage===a},b.prototype.isLast=function(a){return this.endPage===a},b.prototype.onChange=function(){},b.prototype._fixPage=function(a){return a=Math.min(a,this.endPage),a=Math.max(a,this.startPage)},b.prototype._change=function(a){this._lastPage!==a&&(this._lastPage=a,this.onChange(a))},b.prototype._updatePages=function(){var a=Math.floor(this.maxNumbers/2),b=Math.max(this.currentPage-a,this.startPage),c=Math.min(b+this.maxNumbers-1,this.endPage);b=this.endPage===c?c-(this.maxNumbers-1):b,b=Math.max(b,this.startPage),this.pages.length=0;for(var d=b;c>=d;d++)this.pages.push(d)},b.create=function(a){return new b(a)},b}]);
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-pagination",
3 | "version": "0.2.2",
4 | "main": "angular-pagination.js",
5 | "homepage": "https://github.com/nervgh/angular-pagination",
6 | "ignore": ["examples"],
7 | "dependencies": {
8 | "angular": ">=1.1.5"
9 | },
10 | "keywords": [
11 | "angular",
12 | "pagination"
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/examples/base/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Angular Pagination
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
36 |
37 |
38 |
Pagination
39 |
40 |
41 | itemsPerPage
:
42 | itemsCount
:
43 | maxNumbers
:
44 | startPage
:
45 |
46 |
47 |
Page: /
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/examples/base/scripts.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | angular
4 |
5 |
6 | .module('app', ['angularPagination'])
7 |
8 |
9 | .controller('AppController', function($scope, Pagination) {
10 | var pagination = $scope.pagination = Pagination.create({
11 | itemsPerPage: 10,
12 | itemsCount: 100,
13 | maxNumbers: 5
14 | });
15 |
16 | pagination.onChange = function(page) {
17 | console.info('page=', page);
18 | };
19 |
20 | pagination.setCurrent(1);
21 |
22 | $scope.$watchCollection('[pagination.startPage, pagination.maxNumbers, pagination.itemsCount, pagination.itemsPerPage]', function() {
23 | pagination.setCurrent(pagination.currentPage);
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/examples/base/tpl-1.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/base/tpl-2.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/base/tpl-3.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/base/tpl-4.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/directive-1/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Angular Pagination
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
53 |
54 |
--------------------------------------------------------------------------------
/examples/directive-1/scripts.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | angular
4 |
5 |
6 | .module('app', ['angularPagination'])
7 |
8 |
9 | .controller('AppController', function($scope, Pagination) {
10 | var pagination = $scope.pagination = Pagination.create({
11 | itemsPerPage: 10,
12 | itemsCount: 100,
13 | maxNumbers: 5
14 | });
15 |
16 | pagination.onChange = function(page) {
17 | console.info('page=', page);
18 | };
19 | })
20 |
21 |
22 | .directive('ngPagination', function() {
23 | return {
24 | templateUrl: 'tpl-4.html',
25 | link: function(scope, element, attributes) {
26 | var p = scope.$eval(attributes.ngPagination);
27 |
28 | function watcher() {
29 | return [p.startPage, p.maxNumbers, p.itemsCount, p.itemsPerPage].toString();
30 | }
31 | function handler() {
32 | p.setCurrent(p.currentPage);
33 | }
34 |
35 | scope.$watch(watcher, handler);
36 | }
37 | };
38 | });
--------------------------------------------------------------------------------
/examples/directive-1/tpl-4.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/directive-2/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Angular Pagination
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
36 |
37 |
38 |
Pagination
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/examples/directive-2/scripts.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | angular
4 |
5 |
6 | .module('app', ['angularPagination'])
7 |
8 |
9 | .controller('AppController', function($scope) {
10 | $scope.onPageChange = function(page) {
11 | console.info('page=', page);
12 | };
13 | })
14 |
15 |
16 | .directive('ngPagination', ['Pagination', function(Pagination) {
17 | return {
18 | templateUrl: 'tpl-4.html',
19 | link: function(scope, element, attributes) {
20 | var cb = scope.$eval(attributes.ngPagination) || angular.noop;
21 | var pagination = scope.pagination = Pagination.create({
22 | itemsPerPage: 10,
23 | itemsCount: 100,
24 | maxNumbers: 5,
25 | onChange: cb
26 | });
27 | pagination.setCurrent(1);
28 | }
29 | };
30 | }]);
--------------------------------------------------------------------------------
/examples/directive-2/tpl-4.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/license.txt:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2013 nerv. https://github.com/nervgh
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-pagination",
3 | "version": "0.2.2",
4 | "homepage": "https://github.com/nervgh/angular-pagination",
5 | "description": "Angular Pagination is a module for the AngularJS framework",
6 | "author": {
7 | "name": "nerv",
8 | "url": "https://github.com/nervgh"
9 | },
10 | "dependencies": {
11 | "coffee-script": "~1.6.2",
12 | "grunt-contrib-copy": "~0.4.1",
13 | "grunt-contrib-clean": "~0.4.0",
14 | "grunt-contrib-concat": "~0.3.0",
15 | "grunt-contrib-uglify": "~0.2.1",
16 | "grunt": "~0.4.1"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/pagination.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | angular
4 |
5 |
6 | .module('angularPagination', [])
7 |
8 |
9 | .value('paginationOptions', {
10 | itemsPerPage: 10,
11 | itemsCount: 100,
12 | maxNumbers: 5,
13 | startPage: 1,
14 | currentPage: 1
15 | })
16 |
17 |
18 | .factory('Pagination', ['paginationOptions', function(paginationOptions) {
19 | /**
20 | * Creates new pagination object
21 | * @param {Object} options
22 | * @constructor
23 | */
24 | function Pagination(options) {
25 | var defaults = angular.copy(paginationOptions);
26 | angular.extend(this, defaults, options);
27 | this.endPage = null;
28 | this.pages = [];
29 | this._lastPage = null;
30 | this.setCurrent(this.currentPage);
31 | }
32 |
33 | /**
34 | * Sets current page
35 | * @param {Number} page
36 | */
37 | Pagination.prototype.setCurrent = function(page) {
38 | this.endPage = Math.ceil(this.itemsCount / this.itemsPerPage);
39 | this.currentPage = this._fixPage(Math.floor(page));
40 | this._change(this.currentPage);
41 | this._updatePages();
42 | };
43 | /**
44 | * Returns "true" if page is current
45 | * @param {Number} page
46 | * @returns {Boolean}
47 | */
48 | Pagination.prototype.isCurrent = function(page) {
49 | return this.currentPage === page;
50 | };
51 | /**
52 | * Returns "true" if page inside of range
53 | * @param {Number} page
54 | * @returns {boolean}
55 | */
56 | Pagination.prototype.inRange = function(page) {
57 | return this.startPage <= page && this.endPage >= page;
58 | };
59 | /**
60 | * Returns "true" if page is first
61 | * @param {Number} page
62 | * @returns {Boolean}
63 | */
64 | Pagination.prototype.isFirst = function(page) {
65 | return this.startPage === page;
66 | };
67 | /**
68 | * Returns "true" if page is last
69 | * @param {Number} page
70 | * @returns {Boolean}
71 | */
72 | Pagination.prototype.isLast = function(page) {
73 | return this.endPage === page;
74 | };
75 | /**
76 | * Callback. Called when page changed
77 | * @param {Number} page
78 | */
79 | Pagination.prototype.onChange = function(page) {
80 | };
81 | /**
82 | * Fixes number of page if it outside range
83 | * @param {Number} page
84 | * @returns {number}
85 | * @private
86 | */
87 | Pagination.prototype._fixPage = function(page) {
88 | page = Math.min(page, this.endPage);
89 | page = Math.max(page, this.startPage);
90 | return page;
91 | };
92 | /**
93 | * Calls "onChange" if number of page was changed
94 | * @param {Number} page
95 | * @private
96 | */
97 | Pagination.prototype._change = function(page) {
98 | if (this._lastPage !== page) {
99 | this._lastPage = page;
100 | this.onChange(page);
101 | }
102 | };
103 | /**
104 | * Updates array of pages
105 | * @private
106 | */
107 | Pagination.prototype._updatePages = function() {
108 | var delta = Math.floor(this.maxNumbers / 2);
109 | var start = Math.max(this.currentPage - delta, this.startPage);
110 | var end = Math.min(start + this.maxNumbers - 1, this.endPage);
111 |
112 | start = this.endPage === end ? end - (this.maxNumbers - 1) : start;
113 | start = Math.max(start, this.startPage);
114 | this.pages.length = 0;
115 |
116 | for(var i = start; i <= end; i++) {
117 | this.pages.push(i);
118 | }
119 | };
120 | /**
121 | * Creates and returns a pagination object
122 | * @param {Object} options
123 | * @returns {Pagination}
124 | */
125 | Pagination.create = function(options) {
126 | return new Pagination(options);
127 | };
128 |
129 | return Pagination;
130 | }]);
131 |
--------------------------------------------------------------------------------