├── .github
└── ISSUE_TEMPLATE
│ └── bug_report.md
├── .gitignore
├── .npmignore
├── .npmrc
├── Gruntfile.js
├── LICENSE
├── README.md
├── bower.json
├── component.json
├── dist
├── pagination.css
├── pagination.js
├── pagination.less
└── pagination.min.js
├── docs
├── cn.md
└── en.md
├── examples
├── images
│ └── paginationjs_record.gif
└── pagination.html
├── package.json
└── src
├── pagination.js
└── pagination.less
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Provide a re-produciable demo: http://codepen.io/superRaytin/pen/RRoZBz
15 |
16 | **Expected behavior**
17 | A clear and concise description of what you expected to happen.
18 |
19 | **Versions:**
20 | - Pagination: [e.g. 2.1.5]
21 | - jQuery [e.g. 1.8.3]
22 | - Browser [e.g. Chrome]
23 |
24 | **Additional context**
25 | Add any other context about the problem here.
26 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Build and Release Folders
2 | bin/
3 | bin-debug/
4 | bin-release/
5 |
6 | # Other files and folders
7 | .settings/
8 | node_modules/
9 | .idea/
10 | .DS_Store
11 | npm-debug.log
12 | yarn.lock
13 |
14 | # Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties`
15 | # should NOT be excluded as they contain compiler settings and other important
16 | # information for Eclipse / Flash Builder.
17 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | docs
2 | examples
3 | component.json
4 | bower.json
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | registry=https://registry.npmjs.org
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function(grunt) {
2 | grunt.initConfig({
3 | pkg: grunt.file.readJSON('package.json'),
4 |
5 | uglify: {
6 | options: {
7 | banner: '/*\n' +
8 | ' * pagination.js <%= pkg.version %>\n' +
9 | ' * <%= pkg.description %>\n' +
10 | ' * <%= pkg.repository.url %>\n\n' +
11 | ' * Homepage: <%= pkg.homepage %>\n' +
12 | ' *\n' +
13 | ' * Copyright 2014-2100, <%= pkg.author %>\n' +
14 | ' * Released under the <%= pkg.license %> license.\n' +
15 | '*/\n'
16 | },
17 | main: {
18 | files: [
19 | {
20 | src: ['src/pagination.js'],
21 | dest: 'dist/pagination.min.js'
22 | }
23 | ]
24 | }
25 | },
26 |
27 | copy: {
28 | main: {
29 | files: [
30 | {
31 | src: 'src/pagination.js',
32 | dest: 'dist/pagination.js'
33 | },
34 | {
35 | src: 'src/pagination.less',
36 | dest: 'dist/pagination.less'
37 | }
38 | ]
39 | }
40 | },
41 |
42 | less: {
43 | main: {
44 | src: 'src/pagination.less',
45 | dest: 'dist/pagination.css'
46 | }
47 | },
48 |
49 | cssmin: {
50 | main: {
51 | src: 'dist/pagination.css',
52 | dest: 'dist/pagination.css'
53 | }
54 | }
55 | });
56 |
57 | grunt.loadNpmTasks('grunt-contrib-uglify');
58 | grunt.loadNpmTasks('grunt-contrib-less');
59 | grunt.loadNpmTasks('grunt-contrib-cssmin');
60 | grunt.loadNpmTasks('grunt-contrib-copy');
61 |
62 | grunt.registerTask('default', [
63 | 'uglify',
64 | 'copy',
65 | 'less',
66 | 'cssmin'
67 | ]);
68 | };
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014-2048 SuperRaytin 柳裟 <superRaytin@163.com>
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 all
13 | 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 THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Pagination.js
2 |
3 | > A jQuery plugin to provide simple yet fully customisable pagination.
4 |
5 | [![NPM version][npm-image]][npm-url]
6 | [![Bower version][bower-image]][bower-url]
7 | [](https://cdnjs.com/libraries/paginationjs)
8 |
9 | [npm-url]: https://npmjs.org/package/paginationjs
10 | [npm-image]: http://img.shields.io/npm/v/paginationjs.svg
11 | [bower-url]:http://badge.fury.io/bo/paginationjs
12 | [bower-image]: https://badge.fury.io/bo/paginationjs.svg
13 |
14 |
15 |
16 | See demos and full documentation at official site: [http://pagination.js.org](http://pagination.js.org)
17 |
18 | # Installation / Download
19 |
20 | `npm install paginationjs` or `bower install paginationjs` or just download [pagination.js](dist/pagination.js) from the git repo.
21 |
22 | # Quick Start
23 |
24 | ```html
25 |
26 |
27 | ```
28 |
29 | ```js
30 | $('#pagination-container').pagination({
31 | dataSource: [1, 2, 3, 4, 5, 6, 7, ... , 195],
32 | callback: function(data, pagination) {
33 | // template method of yourself
34 | var html = template(data);
35 | $('#data-container').html(html);
36 | }
37 | })
38 | ```
39 |
40 | # Rendering data
41 |
42 | Below is a minimal rendering method:
43 |
44 | ```js
45 | function simpleTemplating(data) {
46 | var html = '';
47 | $.each(data, function(index, item){
48 | html += '- '+ item +'
';
49 | });
50 | html += '
';
51 | return html;
52 | }
53 | ```
54 |
55 | Call:
56 |
57 | ```js
58 | $('#pagination-container').pagination({
59 | dataSource: [1, 2, 3, 4, 5, 6, 7, ... , 195],
60 | callback: function(data, pagination) {
61 | var html = simpleTemplating(data);
62 | $('#data-container').html(html);
63 | }
64 | })
65 | ```
66 |
67 | To make it easier to maintain, you'd better to use specialized templating engine to do that. Such as [Handlebars](http://handlebarsjs.com/) and [Undercore.template](http://underscorejs.org/#template).
68 |
69 | ### Handlebars
70 |
71 | ```html
72 |
79 | ```
80 |
81 | ```js
82 | $('#pagination-container').pagination({
83 | dataSource: [1, 2, 3, 4, 5, 6, 7, ... , 195],
84 | callback: function(data, pagination) {
85 | var html = Handlebars.compile($('#template-demo').html(), {
86 | data: data
87 | });
88 | $('#data-container').html(html);
89 | }
90 | })
91 | ```
92 |
93 | ### Underscore
94 |
95 | ```html
96 |
103 | ```
104 |
105 | ```js
106 | $('#pagination-container').pagination({
107 | dataSource: [1, 2, 3, 4, 5, 6, 7, ... , 195],
108 | callback: function(data, pagination) {
109 | var html = _.template($('#template-demo').html(), {
110 | data: data
111 | });
112 | $('#data-container').html(html);
113 | }
114 | })
115 | ```
116 |
117 | Or any other templating engine you prefer.
118 |
119 | # License
120 |
121 | Released under the MIT license.
122 |
123 | MIT: [http://rem.mit-license.org](http://rem.mit-license.org/), See [LICENSE](/LICENSE)
124 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "paginationjs",
3 | "version": "2.6.0",
4 | "main": "dist/pagination.min.js",
5 | "keywords": [
6 | "paginationjs",
7 | "pagination.js",
8 | "pagination",
9 | "jquery.pagination",
10 | "jquery pagination"
11 | ],
12 | "ignore": [
13 | "**/.*",
14 | "src",
15 | "docs",
16 | "examples",
17 | "node_modules",
18 | "LICENSE",
19 | "component.json",
20 | "bower.json",
21 | "package.json",
22 | "README*.md",
23 | "example.js",
24 | "Gruntfile.js"
25 | ],
26 | "dependencies": {
27 | "jquery": "git://github.com/components/jquery.git#~3"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/component.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "paginationjs",
3 | "version": "2.6.0",
4 | "repo": "superRaytin/paginationjs",
5 | "description": "A jQuery plugin to provide simple yet fully customisable pagination",
6 | "keywords": [
7 | "paginationjs",
8 | "pagination.js",
9 | "pagination",
10 | "jquery.pagination",
11 | "jquery pagination"
12 | ],
13 | "main": "dist/pagination.min.js",
14 | "scripts": [
15 | "dist/pagination.min.js",
16 | "dist/pagination.js",
17 | "dist/pagination.css",
18 | "dist/pagination.less"
19 | ],
20 | "license": "MIT"
21 | }
22 |
--------------------------------------------------------------------------------
/dist/pagination.css:
--------------------------------------------------------------------------------
1 | .paginationjs{display:flex;line-height:1.6;font-family:Marmelad,"Lucida Grande",Arial,"Hiragino Sans GB",Georgia,sans-serif;font-size:14px;box-sizing:initial}.paginationjs:after{display:table;content:" ";clear:both}.paginationjs .paginationjs-pages{float:left;margin-left:10px}.paginationjs .paginationjs-pages ul{float:left;margin:0;padding:0}.paginationjs .paginationjs-go-button,.paginationjs .paginationjs-go-input,.paginationjs .paginationjs-size-changer{margin-left:10px;float:left;font-size:14px}.paginationjs .paginationjs-pages li{float:left;border:1px solid #aaa;border-right:none;list-style:none}.paginationjs .paginationjs-pages li>a{min-width:30px;height:28px;line-height:28px;display:block;background:#fff;font-size:14px;color:#333;text-decoration:none;text-align:center;cursor:pointer}.paginationjs .paginationjs-pages li>a:hover{background:#eee}.paginationjs .paginationjs-pages li.active{border:none}.paginationjs .paginationjs-pages li.active>a{height:30px;line-height:30px;background:#aaa;color:#fff;cursor:default}.paginationjs .paginationjs-pages li.disabled>a{opacity:.3;cursor:default}.paginationjs .paginationjs-pages li.disabled>a:hover{background:0 0}.paginationjs .paginationjs-pages li:first-child,.paginationjs .paginationjs-pages li:first-child>a{border-radius:3px 0 0 3px}.paginationjs .paginationjs-pages li:last-child{border-right:1px solid #aaa;border-radius:0 3px 3px 0}.paginationjs .paginationjs-pages li:last-child>a{border-radius:0 3px 3px 0}.paginationjs .paginationjs-size-changer>select{height:28px;background:#fff;border-radius:3px;border:1px solid #aaa;padding:0;font-size:14px;text-align:center;vertical-align:baseline;outline:0;box-shadow:none;box-sizing:initial}.paginationjs .paginationjs-go-input>input[type=text]{width:30px;height:28px;background:#fff;border-radius:3px;border:1px solid #aaa;padding:0;font-size:14px;text-align:center;vertical-align:baseline;outline:0;box-shadow:none;box-sizing:initial}.paginationjs .paginationjs-go-button>input[type=button]{min-width:40px;height:30px;line-height:28px;background:#fff;border-radius:3px;border:1px solid #aaa;text-align:center;padding:0 8px;font-size:14px;vertical-align:baseline;outline:0;box-shadow:none;color:#333;cursor:pointer;vertical-align:middle\9}.paginationjs .paginationjs-go-button>input[type=button]:hover{background-color:#f8f8f8}.paginationjs .paginationjs-nav{float:left;height:30px;line-height:30px;font-size:14px}.paginationjs.paginationjs-small{font-size:12px}.paginationjs.paginationjs-small .paginationjs-pages li>a{min-width:26px;height:24px;line-height:24px;font-size:12px}.paginationjs.paginationjs-small .paginationjs-pages li.active>a{height:26px;line-height:26px}.paginationjs.paginationjs-small .paginationjs-size-changer{font-size:12px}.paginationjs.paginationjs-small .paginationjs-size-changer>select{height:24px;font-size:12px}.paginationjs.paginationjs-small .paginationjs-go-input{font-size:12px}.paginationjs.paginationjs-small .paginationjs-go-input>input[type=text]{width:26px;height:24px;font-size:12px}.paginationjs.paginationjs-small .paginationjs-go-button{font-size:12px}.paginationjs.paginationjs-small .paginationjs-go-button>input[type=button]{min-width:30px;height:26px;line-height:24px;padding:0 6px;font-size:12px}.paginationjs.paginationjs-small .paginationjs-nav{height:26px;line-height:26px;font-size:12px}.paginationjs.paginationjs-big{font-size:16px}.paginationjs.paginationjs-big .paginationjs-pages li>a{min-width:36px;height:34px;line-height:34px;font-size:16px}.paginationjs.paginationjs-big .paginationjs-pages li.active>a{height:36px;line-height:36px}.paginationjs.paginationjs-big .paginationjs-size-changer{font-size:16px}.paginationjs.paginationjs-big .paginationjs-size-changer>select{height:34px;font-size:16px}.paginationjs.paginationjs-big .paginationjs-go-input{font-size:16px}.paginationjs.paginationjs-big .paginationjs-go-input>input[type=text]{width:36px;height:34px;font-size:16px}.paginationjs.paginationjs-big .paginationjs-go-button{font-size:16px}.paginationjs.paginationjs-big .paginationjs-go-button>input[type=button]{min-width:50px;height:36px;line-height:34px;padding:0 12px;font-size:16px}.paginationjs.paginationjs-big .paginationjs-nav{height:36px;line-height:36px;font-size:16px}.paginationjs>:first-child{margin-left:0}.paginationjs.paginationjs-theme-blue .paginationjs-pages li{border-color:#289de9}.paginationjs.paginationjs-theme-blue .paginationjs-pages li>a{color:#289de9}.paginationjs.paginationjs-theme-blue .paginationjs-pages li>a:hover{background:#e9f4fc}.paginationjs.paginationjs-theme-blue .paginationjs-pages li.active>a{background:#289de9;color:#fff}.paginationjs.paginationjs-theme-blue .paginationjs-pages li.disabled>a:hover{background:0 0}.paginationjs.paginationjs-theme-blue .paginationjs-go-input>input[type=text],.paginationjs.paginationjs-theme-blue .paginationjs-size-changer>select{border-color:#289de9}.paginationjs.paginationjs-theme-blue .paginationjs-go-button>input[type=button]{background:#289de9;border-color:#289de9;color:#fff}.paginationjs.paginationjs-theme-blue .paginationjs-go-button>input[type=button]:hover{background-color:#3ca5ea}.paginationjs.paginationjs-theme-green .paginationjs-pages li{border-color:#449d44}.paginationjs.paginationjs-theme-green .paginationjs-pages li>a{color:#449d44}.paginationjs.paginationjs-theme-green .paginationjs-pages li>a:hover{background:#ebf4eb}.paginationjs.paginationjs-theme-green .paginationjs-pages li.active>a{background:#449d44;color:#fff}.paginationjs.paginationjs-theme-green .paginationjs-pages li.disabled>a:hover{background:0 0}.paginationjs.paginationjs-theme-green .paginationjs-go-input>input[type=text],.paginationjs.paginationjs-theme-green .paginationjs-size-changer>select{border-color:#449d44}.paginationjs.paginationjs-theme-green .paginationjs-go-button>input[type=button]{background:#449d44;border-color:#449d44;color:#fff}.paginationjs.paginationjs-theme-green .paginationjs-go-button>input[type=button]:hover{background-color:#55a555}.paginationjs.paginationjs-theme-yellow .paginationjs-pages li{border-color:#ec971f}.paginationjs.paginationjs-theme-yellow .paginationjs-pages li>a{color:#ec971f}.paginationjs.paginationjs-theme-yellow .paginationjs-pages li>a:hover{background:#fdf5e9}.paginationjs.paginationjs-theme-yellow .paginationjs-pages li.active>a{background:#ec971f;color:#fff}.paginationjs.paginationjs-theme-yellow .paginationjs-pages li.disabled>a:hover{background:0 0}.paginationjs.paginationjs-theme-yellow .paginationjs-go-input>input[type=text],.paginationjs.paginationjs-theme-yellow .paginationjs-size-changer>select{border-color:#ec971f}.paginationjs.paginationjs-theme-yellow .paginationjs-go-button>input[type=button]{background:#ec971f;border-color:#ec971f;color:#fff}.paginationjs.paginationjs-theme-yellow .paginationjs-go-button>input[type=button]:hover{background-color:#eea135}.paginationjs.paginationjs-theme-red .paginationjs-pages li{border-color:#c9302c}.paginationjs.paginationjs-theme-red .paginationjs-pages li>a{color:#c9302c}.paginationjs.paginationjs-theme-red .paginationjs-pages li>a:hover{background:#faeaea}.paginationjs.paginationjs-theme-red .paginationjs-pages li.active>a{background:#c9302c;color:#fff}.paginationjs.paginationjs-theme-red .paginationjs-pages li.disabled>a:hover{background:0 0}.paginationjs.paginationjs-theme-red .paginationjs-go-input>input[type=text],.paginationjs.paginationjs-theme-red .paginationjs-size-changer>select{border-color:#c9302c}.paginationjs.paginationjs-theme-red .paginationjs-go-button>input[type=button]{background:#c9302c;border-color:#c9302c;color:#fff}.paginationjs.paginationjs-theme-red .paginationjs-go-button>input[type=button]:hover{background-color:#ce4541}.paginationjs .paginationjs-pages li.paginationjs-next{border-right:1px solid #aaa\9}.paginationjs .paginationjs-size-changer{margin-left:5px\9}.paginationjs .paginationjs-size-changer>select{line-height:28px\9;vertical-align:middle\9}.paginationjs .paginationjs-go-input{margin-left:5px\9}.paginationjs .paginationjs-go-input>input[type=text]{line-height:28px\9;vertical-align:middle\9}.paginationjs .paginationjs-go-button{margin-left:5px\9}.paginationjs.paginationjs-big .paginationjs-pages li>a{line-height:36px\9}.paginationjs.paginationjs-big .paginationjs-go-input>input[type=text]{height:36px\9;line-height:36px\9}
--------------------------------------------------------------------------------
/dist/pagination.js:
--------------------------------------------------------------------------------
1 | /*
2 | * pagination.js 2.6.0
3 | * A jQuery plugin to provide simple yet fully customisable pagination.
4 | * https://github.com/superRaytin/paginationjs
5 | *
6 | * Homepage: http://pagination.js.org
7 | *
8 | * Copyright 2014-2100, superRaytin
9 | * Released under the MIT license.
10 | */
11 |
12 | (function(global, $) {
13 |
14 | if (typeof $ === 'undefined') {
15 | throwError('Pagination requires jQuery.');
16 | }
17 |
18 | var pluginName = 'pagination';
19 |
20 | var pluginHookMethod = 'addHook';
21 |
22 | var eventPrefix = '__pagination-';
23 |
24 | if ($.fn.pagination) {
25 | throwError('plugin conflicted, the name "pagination" has been taken by another jQuery plugin.');
26 | }
27 |
28 | $.fn[pluginName] = function(options) {
29 |
30 | if (typeof options === 'undefined') {
31 | return this;
32 | }
33 |
34 | var container = $(this);
35 |
36 | var attributes = $.extend({}, $.fn[pluginName].defaults, options);
37 |
38 | var pagination = {
39 |
40 | initialize: function() {
41 | var self = this;
42 |
43 | // Cache data for current instance
44 | if (!container.data('pagination')) {
45 | container.data('pagination', {});
46 | }
47 |
48 | if (self.callHook('beforeInit') === false) return;
49 |
50 | // Pagination has been initialized, destroy it
51 | if (container.data('pagination').initialized) {
52 | $('.paginationjs', container).remove();
53 | }
54 |
55 | // Whether to disable Pagination at the initialization
56 | self.disabled = !!attributes.disabled;
57 |
58 | // Model will be passed to the callback function
59 | var model = self.model = {
60 | pageRange: attributes.pageRange,
61 | pageSize: attributes.pageSize
62 | };
63 |
64 | // Parse dataSource to find available paging data
65 | self.parseDataSource(attributes.dataSource, function(dataSource) {
66 |
67 | // Asynchronous mode
68 | self.isAsync = Helpers.isString(dataSource);
69 | if (Helpers.isArray(dataSource)) {
70 | model.totalNumber = attributes.totalNumber = dataSource.length;
71 | }
72 |
73 | // Asynchronous mode and a 'totalNumberLocator' has been specified
74 | self.isDynamicTotalNumber = self.isAsync && attributes.totalNumberLocator;
75 |
76 | var el = self.render(true);
77 |
78 | // Add extra className to the pagination element
79 | if (attributes.className) {
80 | el.addClass(attributes.className);
81 | }
82 |
83 | model.el = el;
84 |
85 | // Append / prepend pagination element to the container
86 | container[attributes.position === 'bottom' ? 'append' : 'prepend'](el);
87 |
88 | // Bind events
89 | self.observer();
90 |
91 | // Mark pagination has been initialized
92 | container.data('pagination').initialized = true;
93 |
94 | // Call hook after initialization
95 | self.callHook('afterInit', el);
96 | });
97 | },
98 |
99 | render: function(isBoot) {
100 | var self = this;
101 | var model = self.model;
102 | var el = model.el || $('');
103 | var isForced = isBoot !== true;
104 |
105 | self.callHook('beforeRender', isForced);
106 |
107 | var currentPage = model.pageNumber || attributes.pageNumber;
108 | var pageRange = attributes.pageRange || 0;
109 | var totalPage = self.getTotalPage();
110 |
111 | var rangeStart = currentPage - pageRange;
112 | var rangeEnd = currentPage + pageRange;
113 |
114 | if (rangeEnd > totalPage) {
115 | rangeEnd = totalPage;
116 | rangeStart = totalPage - pageRange * 2;
117 | rangeStart = rangeStart < 1 ? 1 : rangeStart;
118 | }
119 |
120 | if (rangeStart <= 1) {
121 | rangeStart = 1;
122 | rangeEnd = Math.min(pageRange * 2 + 1, totalPage);
123 | }
124 |
125 | el.html(self.generateHTML({
126 | currentPage: currentPage,
127 | pageRange: pageRange,
128 | rangeStart: rangeStart,
129 | rangeEnd: rangeEnd
130 | }));
131 |
132 | // Whether to hide pagination when there is only one page
133 | if (attributes.hideOnlyOnePage) {
134 | el[totalPage <= 1 ? 'hide' : 'show']();
135 | }
136 |
137 | self.callHook('afterRender', isForced);
138 |
139 | return el;
140 | },
141 |
142 | getPageLinkTag: function(index) {
143 | var pageLink = attributes.pageLink;
144 | return pageLink ? `${index}` : `${index}`;
145 | },
146 |
147 | // Generate HTML for page numbers
148 | generatePageNumbersHTML: function(args) {
149 | var self = this;
150 | var currentPage = args.currentPage;
151 | var totalPage = self.getTotalPage();
152 | var getPageLinkTag = self.getPageLinkTag;
153 | var rangeStart = args.rangeStart;
154 | var rangeEnd = args.rangeEnd;
155 | var html = '';
156 | var i;
157 |
158 | var ellipsisText = attributes.ellipsisText;
159 |
160 | var classPrefix = attributes.classPrefix;
161 | var pageClassName = attributes.pageClassName || '';
162 | var activeClassName = attributes.activeClassName || '';
163 | var disableClassName = attributes.disableClassName || '';
164 |
165 | // Display all page numbers if page range disabled
166 | if (attributes.pageRange === null) {
167 | for (i = 1; i <= totalPage; i++) {
168 | if (i == currentPage) {
169 | html += ``;
170 | } else {
171 | html += ``;
172 | }
173 | }
174 | return html;
175 | }
176 |
177 | if (rangeStart <= 3) {
178 | for (i = 1; i < rangeStart; i++) {
179 | if (i == currentPage) {
180 | html += ``;
181 | } else {
182 | html += ``;
183 | }
184 | }
185 | } else {
186 | if (!attributes.hideFirstOnEllipsisShow) {
187 | html += ``;
188 | }
189 | html += `${ellipsisText}`;
190 | }
191 |
192 | for (i = rangeStart; i <= rangeEnd; i++) {
193 | if (i == currentPage) {
194 | html += ``;
195 | } else {
196 | html += ``;
197 | }
198 | }
199 |
200 | if (rangeEnd >= totalPage - 2) {
201 | for (i = rangeEnd + 1; i <= totalPage; i++) {
202 | html += ``;
203 | }
204 | } else {
205 | html += `${ellipsisText}`;
206 |
207 | if (!attributes.hideLastOnEllipsisShow) {
208 | html += ``;
209 | }
210 | }
211 |
212 | return html;
213 | },
214 |
215 | // Generate HTML content
216 | generateHTML: function(args) {
217 | var self = this;
218 | var currentPage = args.currentPage;
219 | var totalPage = self.getTotalPage();
220 | var getPageLinkTag = self.getPageLinkTag;
221 |
222 | var totalNumber = self.getTotalNumber();
223 |
224 | var pageSize = attributes.pageSize;
225 | var showPrevious = attributes.showPrevious;
226 | var showNext = attributes.showNext;
227 | var showPageNumbers = attributes.showPageNumbers;
228 | var showNavigator = attributes.showNavigator;
229 | var showSizeChanger = attributes.showSizeChanger;
230 | var sizeChangerOptions = attributes.sizeChangerOptions;
231 | var showGoInput = attributes.showGoInput;
232 | var showGoButton = attributes.showGoButton;
233 |
234 | var prevText = attributes.prevText;
235 | var nextText = attributes.nextText;
236 | var goButtonText = attributes.goButtonText;
237 |
238 | var classPrefix = attributes.classPrefix;
239 | var disableClassName = attributes.disableClassName || '';
240 | var ulClassName = attributes.ulClassName || '';
241 | var prevClassName = attributes.prevClassName || '';
242 | var nextClassName = attributes.nextClassName || '';
243 |
244 | var html = '';
245 | var sizeSelect = ``;
333 | formattedString = sizeSelect;
334 |
335 | if (formatSizeChanger) {
336 | formattedString = self.replaceVariables(formatSizeChanger, {
337 | length: sizeSelect,
338 | total: totalNumber
339 | });
340 | }
341 | html += ``;
342 | }
343 | }
344 |
345 | // Whether to display Go input
346 | if (showGoInput) {
347 | if (formatGoInput) {
348 | formattedString = self.replaceVariables(formatGoInput, {
349 | currentPage: currentPage,
350 | totalPage: totalPage,
351 | totalNumber: totalNumber,
352 | input: goInput
353 | });
354 | html += `${formattedString}
`;
355 | }
356 | }
357 |
358 | // Whether to display Go button
359 | if (showGoButton) {
360 | if (formatGoButton) {
361 | formattedString = self.replaceVariables(formatGoButton, {
362 | currentPage: currentPage,
363 | totalPage: totalPage,
364 | totalNumber: totalNumber,
365 | button: goButton
366 | });
367 | html += `${formattedString}
`;
368 | }
369 | }
370 |
371 | // Append extra contents to the pagination buttons
372 | if (footer) {
373 | formattedString = self.replaceVariables(footer, {
374 | currentPage: currentPage,
375 | totalPage: totalPage,
376 | totalNumber: totalNumber
377 | });
378 | html += formattedString;
379 | }
380 |
381 | return html;
382 | },
383 |
384 | // dataSource is a request URL and a 'totalNumberLocator' function specified
385 | // execute it to find out 'totalNumber' from the response
386 | findTotalNumberFromRemoteResponse: function(response) {
387 | var self = this;
388 | self.model.totalNumber = attributes.totalNumberLocator(response);
389 | },
390 |
391 | // Go to the specified page
392 | go: function(number, callback) {
393 | var self = this;
394 | var model = self.model;
395 |
396 | if (self.disabled) return;
397 |
398 | var pageNumber = number;
399 | pageNumber = parseInt(pageNumber);
400 |
401 | if (!pageNumber || pageNumber < 1) return;
402 |
403 | var pageSize = attributes.pageSize;
404 | var totalNumber = self.getTotalNumber();
405 | var totalPage = self.getTotalPage();
406 |
407 | if (totalNumber > 0 && pageNumber > totalPage) return;
408 |
409 | // Pick paging data in synchronous mode
410 | if (!self.isAsync) {
411 | render(self.getPagingData(pageNumber));
412 | return;
413 | }
414 |
415 | var postData = {};
416 | var alias = attributes.alias || {};
417 | var pageSizeName = alias.pageSize ? alias.pageSize : 'pageSize';
418 | var pageNumberName = alias.pageNumber ? alias.pageNumber : 'pageNumber';
419 | postData[pageSizeName] = pageSize;
420 | postData[pageNumberName] = pageNumber;
421 |
422 | var ajaxParams = typeof attributes.ajax === 'function' ? attributes.ajax() : attributes.ajax;
423 |
424 | // If the pageNumber's value starts with 0 via Ajax
425 | if (ajaxParams && ajaxParams.pageNumberStartWithZero) {
426 | postData[pageNumberName] = pageNumber - 1;
427 | }
428 |
429 | var formatAjaxParams = {
430 | type: 'get',
431 | cache: false,
432 | data: {},
433 | contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
434 | dataType: 'json',
435 | async: true
436 | };
437 |
438 | $.extend(true, formatAjaxParams, ajaxParams);
439 | $.extend(formatAjaxParams.data, postData);
440 |
441 | formatAjaxParams.url = attributes.dataSource;
442 | formatAjaxParams.success = function(response) {
443 | try {
444 | self.model.originalResponse = response;
445 | if (self.isDynamicTotalNumber) {
446 | self.findTotalNumberFromRemoteResponse(response);
447 | } else {
448 | self.model.totalNumber = attributes.totalNumber;
449 | }
450 |
451 | var finalData = self.filterDataWithLocator(response);
452 | render(finalData);
453 | } catch (e) {
454 | if(typeof attributes.onError === 'function') {
455 | attributes.onError(e, 'ajaxSuccessHandlerError');
456 | } else {
457 | throw e;
458 | }
459 | }
460 | };
461 | formatAjaxParams.error = function(jqXHR, textStatus, errorThrown) {
462 | attributes.formatAjaxError && attributes.formatAjaxError(jqXHR, textStatus, errorThrown);
463 | self.enable();
464 | };
465 |
466 | self.disable();
467 |
468 | if (attributes.ajaxFunction) {
469 | attributes.ajaxFunction(formatAjaxParams);
470 | } else {
471 | $.ajax(formatAjaxParams);
472 | }
473 |
474 | function render(data) {
475 | if (self.callHook('beforePaging', pageNumber) === false) return false;
476 |
477 | // Pagination direction
478 | model.direction = typeof model.pageNumber === 'undefined' ? 0 : (pageNumber > model.pageNumber ? 1 : -1);
479 |
480 | model.pageNumber = pageNumber;
481 |
482 | self.render();
483 |
484 | if (self.disabled && self.isAsync) {
485 | // enable pagination
486 | self.enable();
487 | }
488 |
489 | // cache model data
490 | container.data('pagination').model = model;
491 |
492 | // format result data before callback invoked
493 | if (attributes.formatResult) {
494 | var cloneData = $.extend(true, [], data);
495 | if (!Helpers.isArray(data = attributes.formatResult(cloneData))) {
496 | data = cloneData;
497 | }
498 | }
499 |
500 | container.data('pagination').currentPageData = data;
501 |
502 | self.doCallback(data, callback);
503 |
504 | self.callHook('afterPaging', pageNumber);
505 |
506 | if (pageNumber == 1) {
507 | self.callHook('afterIsFirstPage');
508 | } else if (pageNumber == self.getTotalPage()) {
509 | self.callHook('afterIsLastPage');
510 | }
511 | }
512 | },
513 |
514 | doCallback: function(data, customCallback) {
515 | var self = this;
516 | var model = self.model;
517 |
518 | if (typeof customCallback === 'function') {
519 | customCallback(data, model);
520 | } else if (typeof attributes.callback === 'function') {
521 | attributes.callback(data, model);
522 | }
523 | },
524 |
525 | destroy: function() {
526 | if (this.callHook('beforeDestroy') === false) return;
527 |
528 | this.model.el.remove();
529 | container.off();
530 |
531 | // Remove style element
532 | $('#paginationjs-style').remove();
533 |
534 | this.callHook('afterDestroy');
535 | },
536 |
537 | previous: function(callback) {
538 | this.go(this.model.pageNumber - 1, callback);
539 | },
540 |
541 | next: function(callback) {
542 | this.go(this.model.pageNumber + 1, callback);
543 | },
544 |
545 | disable: function() {
546 | var self = this;
547 | var source = self.isAsync ? 'async' : 'sync';
548 |
549 | if (self.callHook('beforeDisable', source) === false) return;
550 |
551 | self.disabled = true;
552 | self.model.disabled = true;
553 |
554 | self.callHook('afterDisable', source);
555 | },
556 |
557 | enable: function() {
558 | var self = this;
559 | var source = self.isAsync ? 'async' : 'sync';
560 |
561 | if (self.callHook('beforeEnable', source) === false) return;
562 |
563 | self.disabled = false;
564 | self.model.disabled = false;
565 |
566 | self.callHook('afterEnable', source);
567 | },
568 |
569 | refresh: function(callback) {
570 | this.go(this.model.pageNumber, callback);
571 | },
572 |
573 | show: function() {
574 | var self = this;
575 |
576 | if (self.model.el.is(':visible')) return;
577 |
578 | self.model.el.show();
579 | },
580 |
581 | hide: function() {
582 | var self = this;
583 |
584 | if (!self.model.el.is(':visible')) return;
585 |
586 | self.model.el.hide();
587 | },
588 |
589 | // Replace variables for template string
590 | replaceVariables: function(template, variables) {
591 | var formattedString;
592 |
593 | for (var key in variables) {
594 | var value = variables[key];
595 | var regexp = new RegExp('<%=\\s*' + key + '\\s*%>', 'img');
596 |
597 | formattedString = (formattedString || template).replace(regexp, value);
598 | }
599 |
600 | return formattedString;
601 | },
602 |
603 | getPagingData: function(number) {
604 | var pageSize = attributes.pageSize;
605 | var dataSource = attributes.dataSource;
606 | var totalNumber = this.getTotalNumber();
607 |
608 | var start = pageSize * (number - 1) + 1;
609 | var end = Math.min(number * pageSize, totalNumber);
610 |
611 | return dataSource.slice(start - 1, end);
612 | },
613 |
614 | getTotalNumber: function() {
615 | return this.model.totalNumber || attributes.totalNumber || 0;
616 | },
617 |
618 | getTotalPage: function() {
619 | return Math.ceil(this.getTotalNumber() / attributes.pageSize);
620 | },
621 |
622 | getLocator: function(locator) {
623 | var result;
624 |
625 | if (typeof locator === 'string') {
626 | result = locator;
627 | } else if (typeof locator === 'function') {
628 | result = locator();
629 | } else {
630 | throwError('"locator" is incorrect. Expect string or function type.');
631 | }
632 |
633 | return result;
634 | },
635 |
636 | // Filter data with "locator"
637 | filterDataWithLocator: function(dataSource) {
638 | var locator = this.getLocator(attributes.locator);
639 | var filteredData;
640 |
641 | // Datasource is an Object, use "locator" to locate available data
642 | if (Helpers.isObject(dataSource)) {
643 | try {
644 | $.each(locator.split('.'), function(index, item) {
645 | filteredData = (filteredData ? filteredData : dataSource)[item];
646 | });
647 | }
648 | catch (e) {
649 | // ignore
650 | }
651 |
652 | if (!filteredData) {
653 | throwError('dataSource.' + locator + ' is undefined.');
654 | } else if (!Helpers.isArray(filteredData)) {
655 | throwError('dataSource.' + locator + ' should be an Array.');
656 | }
657 | }
658 |
659 | return filteredData || dataSource;
660 | },
661 |
662 | parseDataSource: function(dataSource, callback) {
663 | var self = this;
664 |
665 | if (Helpers.isObject(dataSource)) {
666 | callback(attributes.dataSource = self.filterDataWithLocator(dataSource));
667 | } else if (Helpers.isArray(dataSource)) {
668 | callback(attributes.dataSource = dataSource);
669 | } else if (typeof dataSource === 'function') {
670 | attributes.dataSource(function(data) {
671 | if (!Helpers.isArray(data)) {
672 | throwError('The parameter of "done" Function should be an Array.');
673 | }
674 | self.parseDataSource.call(self, data, callback);
675 | });
676 | } else if (typeof dataSource === 'string') {
677 | if (/^https?|file:/.test(dataSource)) {
678 | attributes.ajaxDataType = 'jsonp';
679 | }
680 | callback(dataSource);
681 | } else {
682 | throwError('Unexpected dataSource type');
683 | }
684 | },
685 |
686 | callHook: function(hook) {
687 | var paginationData = container.data('pagination') || {};
688 | var result;
689 |
690 | var args = Array.prototype.slice.apply(arguments);
691 | args.shift();
692 |
693 | if (attributes[hook] && typeof attributes[hook] === 'function') {
694 | if (attributes[hook].apply(global, args) === false) {
695 | result = false;
696 | }
697 | }
698 |
699 | if (paginationData.hooks && paginationData.hooks[hook]) {
700 | $.each(paginationData.hooks[hook], function(index, item) {
701 | if (item.apply(global, args) === false) {
702 | result = false;
703 | }
704 | });
705 | }
706 |
707 | return result !== false;
708 | },
709 |
710 | observer: function() {
711 | var self = this;
712 | var el = self.model.el;
713 |
714 | // Go to specified page number
715 | container.on(eventPrefix + 'go', function(event, pageNumber, done) {
716 | if (typeof pageNumber === 'string') {
717 | pageNumber = parseInt(pageNumber.trim());
718 | }
719 |
720 | if (!pageNumber) return;
721 |
722 | if (typeof pageNumber !== 'number') {
723 | throwError('"pageNumber" is incorrect. (Number)');
724 | }
725 |
726 | self.go(pageNumber, done);
727 | });
728 |
729 | // Page number button click listener
730 | el.on('click', '.J-paginationjs-page', function(event) {
731 | var current = $(event.currentTarget);
732 | var pageNumber = current.attr('data-num').trim();
733 |
734 | if (!pageNumber || current.hasClass(attributes.disableClassName) || current.hasClass(attributes.activeClassName)) return;
735 |
736 | if (self.callHook('beforePageOnClick', event, pageNumber) === false) return false;
737 |
738 | self.go(pageNumber);
739 |
740 | self.callHook('afterPageOnClick', event, pageNumber);
741 |
742 | if (!attributes.pageLink) return false;
743 | });
744 |
745 | // Previous button click listener
746 | el.on('click', '.J-paginationjs-previous', function(event) {
747 | var current = $(event.currentTarget);
748 | var pageNumber = current.attr('data-num').trim();
749 |
750 | if (!pageNumber || current.hasClass(attributes.disableClassName)) return;
751 |
752 | if (self.callHook('beforePreviousOnClick', event, pageNumber) === false) return false;
753 |
754 | self.go(pageNumber);
755 |
756 | self.callHook('afterPreviousOnClick', event, pageNumber);
757 |
758 | if (!attributes.pageLink) return false;
759 | });
760 |
761 | // Next button click listener
762 | el.on('click', '.J-paginationjs-next', function(event) {
763 | var current = $(event.currentTarget);
764 | var pageNumber = current.attr('data-num').trim();
765 |
766 | if (!pageNumber || current.hasClass(attributes.disableClassName)) return;
767 |
768 | if (self.callHook('beforeNextOnClick', event, pageNumber) === false) return false;
769 |
770 | self.go(pageNumber);
771 |
772 | self.callHook('afterNextOnClick', event, pageNumber);
773 |
774 | if (!attributes.pageLink) return false;
775 | });
776 |
777 | // Go button click listener
778 | el.on('click', '.J-paginationjs-go-button', function(event) {
779 | var pageNumber = $('.J-paginationjs-go-pagenumber', el).val();
780 |
781 | if (self.callHook('beforeGoButtonOnClick', event, pageNumber) === false) return false;
782 |
783 | container.trigger(eventPrefix + 'go', pageNumber);
784 |
785 | self.callHook('afterGoButtonOnClick', event, pageNumber);
786 | });
787 |
788 | // go input enter keyup listener
789 | el.on('keyup', '.J-paginationjs-go-pagenumber', function(event) {
790 | if (event.which === 13) {
791 | var pageNumber = $(event.currentTarget).val();
792 |
793 | if (self.callHook('beforeGoInputOnEnter', event, pageNumber) === false) return false;
794 |
795 | container.trigger(eventPrefix + 'go', pageNumber);
796 |
797 | // Maintain the cursor
798 | $('.J-paginationjs-go-pagenumber', el).focus();
799 |
800 | self.callHook('afterGoInputOnEnter', event, pageNumber);
801 | }
802 | });
803 |
804 | el.on('change', '.J-paginationjs-size-select', function(event) {
805 | var current = $(event.currentTarget);
806 | var size = parseInt(current.val());
807 | var currentPage = self.model.pageNumber || attributes.pageNumber;
808 |
809 | if (typeof size !== 'number') return;
810 |
811 | if (self.callHook('beforeSizeSelectorChange', event, size) === false) return false;
812 |
813 | attributes.pageSize = size;
814 | self.model.pageSize = size;
815 | self.model.totalPage = self.getTotalPage();
816 | if (currentPage > self.model.totalPage) {
817 | currentPage = self.model.totalPage;
818 | }
819 | self.go(currentPage);
820 |
821 | self.callHook('afterSizeSelectorChange', event, size);
822 |
823 | if (!attributes.pageLink) return false;
824 | });
825 |
826 | // Previous page
827 | container.on(eventPrefix + 'previous', function(event, done) {
828 | self.previous(done);
829 | });
830 |
831 | // Next page
832 | container.on(eventPrefix + 'next', function(event, done) {
833 | self.next(done);
834 | });
835 |
836 | // Disable
837 | container.on(eventPrefix + 'disable', function() {
838 | self.disable();
839 | });
840 |
841 | // Enable
842 | container.on(eventPrefix + 'enable', function() {
843 | self.enable();
844 | });
845 |
846 | // Refresh
847 | container.on(eventPrefix + 'refresh', function(event, done) {
848 | self.refresh(done);
849 | });
850 |
851 | // Show
852 | container.on(eventPrefix + 'show', function() {
853 | self.show();
854 | });
855 |
856 | // Hide
857 | container.on(eventPrefix + 'hide', function() {
858 | self.hide();
859 | });
860 |
861 | // Destroy
862 | container.on(eventPrefix + 'destroy', function() {
863 | self.destroy();
864 | });
865 |
866 | // Whether to load the default page
867 | var validTotalPage = Math.max(self.getTotalPage(), 1)
868 | var defaultPageNumber = attributes.pageNumber;
869 |
870 | // Default pageNumber should be 1 when totalNumber is dynamic
871 | if (self.isDynamicTotalNumber) {
872 | if (attributes.resetPageNumberOnInit) defaultPageNumber = 1;
873 | }
874 |
875 | if (attributes.triggerPagingOnInit) {
876 | container.trigger(eventPrefix + 'go', Math.min(defaultPageNumber, validTotalPage));
877 | }
878 | }
879 | };
880 |
881 | // Pagination has been initialized
882 | if (container.data('pagination') && container.data('pagination').initialized === true) {
883 | // Handle events
884 | if (isNumeric(options)) {
885 | // eg: container.pagination(5)
886 | container.trigger.call(this, eventPrefix + 'go', options, arguments[1]);
887 | return this;
888 | } else if (typeof options === 'string') {
889 | var args = Array.prototype.slice.apply(arguments);
890 | args[0] = eventPrefix + args[0];
891 |
892 | switch (options) {
893 | case 'previous':
894 | case 'next':
895 | case 'go':
896 | case 'disable':
897 | case 'enable':
898 | case 'refresh':
899 | case 'show':
900 | case 'hide':
901 | case 'destroy':
902 | container.trigger.apply(this, args);
903 | break;
904 | case 'getSelectedPageNum':
905 | case 'getCurrentPageNum':
906 | if (container.data('pagination').model) {
907 | return container.data('pagination').model.pageNumber;
908 | } else {
909 | return container.data('pagination').attributes.pageNumber;
910 | }
911 | case 'getTotalPage':
912 | return Math.ceil(container.data('pagination').model.totalNumber / container.data('pagination').model.pageSize);
913 | case 'getSelectedPageData':
914 | case 'getCurrentPageData':
915 | return container.data('pagination').currentPageData;
916 | // Whether pagination has been disabled
917 | case 'isDisabled':
918 | return container.data('pagination').model.disabled === true;
919 | default:
920 | throwError('Unknown action: ' + options);
921 | }
922 | return this;
923 | } else {
924 | // Uninstall the old instance before initializing a new one
925 | uninstallPlugin(container);
926 | }
927 | } else {
928 | if (!Helpers.isObject(options)) throwError('Illegal options');
929 | }
930 |
931 | // Check parameters
932 | parameterChecker(attributes);
933 |
934 | pagination.initialize();
935 |
936 | return this;
937 | };
938 |
939 | // Instance defaults
940 | $.fn[pluginName].defaults = {
941 |
942 | // Data source
943 | // Array | String | Function | Object
944 | //dataSource: '',
945 |
946 | // String | Function
947 | //locator: 'data',
948 |
949 | // Function
950 | //totalNumberLocator: function() {},
951 |
952 | // Total number of data items
953 | totalNumber: 0,
954 |
955 | // Default page number
956 | pageNumber: 1,
957 |
958 | // Number of data items per page
959 | pageSize: 10,
960 |
961 | // Page range (pages around current page)
962 | pageRange: 2,
963 |
964 | // Whether to display the 'Previous' button
965 | showPrevious: true,
966 |
967 | // Whether to display the 'Next' button
968 | showNext: true,
969 |
970 | // Whether to display the page buttons
971 | showPageNumbers: true,
972 |
973 | showNavigator: false,
974 |
975 | // Whether to display the 'Go' input
976 | showGoInput: false,
977 |
978 | // Whether to display the 'Go' button
979 | showGoButton: false,
980 |
981 | showSizeChanger: false,
982 |
983 | sizeChangerOptions: [10, 20, 50, 100],
984 |
985 | // Page link
986 | pageLink: '',
987 |
988 | // 'Previous' text
989 | prevText: '‹',
990 |
991 | // 'Next' text
992 | nextText: '›',
993 |
994 | // Ellipsis text
995 | ellipsisText: '...',
996 |
997 | // 'Go' button text
998 | goButtonText: 'Go',
999 |
1000 | // Additional class name(s) for the Pagination container
1001 | //className: '',
1002 |
1003 | classPrefix: 'paginationjs',
1004 |
1005 | activeClassName: 'active',
1006 |
1007 | // class name when disabled
1008 | disableClassName: 'disabled',
1009 |
1010 | //ulClassName: '',
1011 |
1012 | //pageClassName: '',
1013 |
1014 | //prevClassName: '',
1015 |
1016 | //nextClassName: '',
1017 |
1018 | formatNavigator: 'Total <%= totalNumber %> items',
1019 |
1020 | formatGoInput: '<%= input %>',
1021 |
1022 | formatGoButton: '<%= button %>',
1023 |
1024 | // position in the container
1025 | position: 'bottom',
1026 |
1027 | // Auto hide previous button when current page is the first
1028 | autoHidePrevious: false,
1029 |
1030 | // Auto hide next button when current page is the last
1031 | autoHideNext: false,
1032 |
1033 | //header: '',
1034 |
1035 | //footer: '',
1036 |
1037 | //alias: {},
1038 |
1039 | // Whether to trigger pagination at initialization
1040 | triggerPagingOnInit: true,
1041 |
1042 | // Whether to reset page number at initialization, it works only if dataSource is a URL and totalNumberLocator is specified
1043 | resetPageNumberOnInit: true,
1044 |
1045 | // Whether to hide pagination when less than one page
1046 | hideOnlyOnePage: false,
1047 |
1048 | hideFirstOnEllipsisShow: false,
1049 |
1050 | hideLastOnEllipsisShow: false,
1051 |
1052 | // Customize item's innerHTML
1053 | callback: function() {}
1054 | };
1055 |
1056 | // Hook register
1057 | $.fn[pluginHookMethod] = function(hook, callback) {
1058 | if (arguments.length < 2) {
1059 | throwError('Expect 2 arguments at least.');
1060 | }
1061 |
1062 | if (typeof callback !== 'function') {
1063 | throwError('callback should be a function.');
1064 | }
1065 |
1066 | var container = $(this);
1067 | var paginationData = container.data('pagination');
1068 |
1069 | if (!paginationData) {
1070 | container.data('pagination', {});
1071 | paginationData = container.data('pagination');
1072 | }
1073 |
1074 | !paginationData.hooks && (paginationData.hooks = {});
1075 |
1076 | //paginationData.hooks[hook] = callback;
1077 | paginationData.hooks[hook] = paginationData.hooks[hook] || [];
1078 | paginationData.hooks[hook].push(callback);
1079 |
1080 | };
1081 |
1082 | // Static method
1083 | $[pluginName] = function(selector, options) {
1084 | if (arguments.length < 2) {
1085 | throwError('Requires two parameters.');
1086 | }
1087 |
1088 | var container;
1089 |
1090 | // 'selector' is a jQuery object
1091 | if (typeof selector !== 'string' && selector instanceof jQuery) {
1092 | container = selector;
1093 | } else {
1094 | container = $(selector);
1095 | }
1096 |
1097 | if (!container.length) return;
1098 |
1099 | container.pagination(options);
1100 |
1101 | return container;
1102 | };
1103 |
1104 | // ============================================================
1105 | // helpers
1106 | // ============================================================
1107 |
1108 | var Helpers = {};
1109 |
1110 | // Throw error
1111 | function throwError(content) {
1112 | throw new Error('Pagination: ' + content);
1113 | }
1114 |
1115 | // Check parameters
1116 | function parameterChecker(args) {
1117 | if (!args.dataSource) {
1118 | throwError('"dataSource" is required.');
1119 | }
1120 |
1121 | if (typeof args.dataSource === 'string') {
1122 | if (args.totalNumberLocator === undefined) {
1123 | if (args.totalNumber === undefined) {
1124 | throwError('"totalNumber" is required.');
1125 | } else if (!isNumeric(args.totalNumber)) {
1126 | throwError('"totalNumber" is incorrect. Expect numberic type');
1127 | }
1128 | } else {
1129 | if (typeof args.totalNumberLocator !== 'function') {
1130 | throwError('"totalNumberLocator" should be a Function.');
1131 | }
1132 | }
1133 | } else if (Helpers.isObject(args.dataSource)) {
1134 | if (typeof args.locator === 'undefined') {
1135 | throwError('"dataSource" is an Object, please specify a "locator".');
1136 | } else if (typeof args.locator !== 'string' && typeof args.locator !== 'function') {
1137 | throwError('' + args.locator + ' is incorrect. Expect string or function type');
1138 | }
1139 | }
1140 |
1141 | if (args.formatResult !== undefined && typeof args.formatResult !== 'function') {
1142 | throwError('"formatResult" should be a Function.');
1143 | }
1144 |
1145 | if (args.onError !== undefined && typeof args.onError !== 'function') {
1146 | throwError('"onError" should be a Function.');
1147 | }
1148 | }
1149 |
1150 | // uninstall plugin
1151 | function uninstallPlugin(target) {
1152 | var events = ['go', 'previous', 'next', 'disable', 'enable', 'refresh', 'show', 'hide', 'destroy'];
1153 |
1154 | // off all events
1155 | $.each(events, function(index, value) {
1156 | target.off(eventPrefix + value);
1157 | });
1158 |
1159 | // reset pagination data
1160 | target.data('pagination', {});
1161 |
1162 | // remove pagination element
1163 | $('.paginationjs', target).remove();
1164 | }
1165 |
1166 | // Object type detection
1167 | function getObjectType(object, tmp) {
1168 | return ( (tmp = typeof(object)) == "object" ? object == null && "null" || Object.prototype.toString.call(object).slice(8, -1) : tmp ).toLowerCase();
1169 | }
1170 |
1171 | function isNumeric(n) {
1172 | return !isNaN(parseFloat(n)) && isFinite(n);
1173 | }
1174 |
1175 | $.each(['Object', 'Array', 'String'], function(index, name) {
1176 | Helpers['is' + name] = function(object) {
1177 | return getObjectType(object) === name.toLowerCase();
1178 | };
1179 | });
1180 |
1181 | /*
1182 | * export via AMD or CommonJS
1183 | * */
1184 | if (typeof define === 'function' && define.amd) {
1185 | define(function() {
1186 | return $;
1187 | });
1188 | }
1189 |
1190 | })(this, window.jQuery);
1191 |
--------------------------------------------------------------------------------
/dist/pagination.less:
--------------------------------------------------------------------------------
1 | @borderColor: #aaa;
2 | @activeBgColor: #aaa;
3 |
4 | @Blue_color_base: #289DE9;
5 | @Blue_color_font: @Blue_color_base;
6 | @Blue_color_border: @Blue_color_base;
7 | @Blue_bgColor_active: @Blue_color_base;
8 | @Blue_bgColor_hover: #E9F4FC;
9 | @Blue_bgColor_buttonHover: #3CA5EA;
10 |
11 | @Green_color_base: #449D44;
12 | @Green_color_font: @Green_color_base;
13 | @Green_color_border: @Green_color_base;
14 | @Green_bgColor_active: @Green_color_base;
15 | @Green_bgColor_hover: #EBF4EB;
16 | @Green_bgColor_buttonHover: #55A555;
17 |
18 | @Yellow_color_base: #EC971F;
19 | @Yellow_color_font: @Yellow_color_base;
20 | @Yellow_color_border: @Yellow_color_base;
21 | @Yellow_bgColor_active: @Yellow_color_base;
22 | @Yellow_bgColor_hover: #FDF5E9;
23 | @Yellow_bgColor_buttonHover: #EEA135;
24 |
25 | @Red_color_base: #C9302C;
26 | @Red_color_font: @Red_color_base;
27 | @Red_color_border: @Red_color_base;
28 | @Red_bgColor_active: @Red_color_base;
29 | @Red_bgColor_hover: #FAEAEA;
30 | @Red_bgColor_buttonHover: #CE4541;
31 |
32 | @S_fontSize: 12px;
33 | @S_minWidth: 26px;
34 | @S_height: 24px;
35 | @S_lineHeight: @S_height;
36 | @S_activeHeight: @S_height + 2;
37 | @S_inputWidth: 26px;
38 | @S_inputHeight: 24px;
39 | @S_buttonMinWidth: 30px;
40 | @S_buttonHeight: 26px;
41 | @S_buttonLineHeight: @S_buttonHeight - 2;
42 | @S_buttonPadding: 0 6px;
43 | @S_navHeight: @S_activeHeight;
44 |
45 |
46 | @N_fontSize: 14px;
47 | @N_minWidth: 30px;
48 | @N_height: 28px;
49 | @N_lineHeight: @N_height;
50 | @N_activeHeight: @N_height + 2;
51 | @N_inputWidth: 30px;
52 | @N_inputHeight: 28px;
53 | @N_buttonMinWidth: 40px;
54 | @N_buttonHeight: 30px;
55 | @N_buttonLineHeight: @N_buttonHeight - 2;
56 | @N_buttonPadding: 0 8px;
57 | @N_navHeight: @N_activeHeight;
58 |
59 |
60 | @B_fontSize: 16px;
61 | @B_minWidth: 36px;
62 | @B_height: 34px;
63 | @B_lineHeight: @B_height;
64 | @B_activeHeight: @B_height + 2;
65 | @B_inputWidth: 36px;
66 | @B_inputHeight: 34px;
67 | @B_buttonMinWidth: 50px;
68 | @B_buttonHeight: 36px;
69 | @B_buttonLineHeight: @B_buttonHeight - 2;
70 | @B_buttonPadding: 0 12px;
71 | @B_navHeight: @B_activeHeight;
72 |
73 |
74 | .paginationjs{
75 | display: flex;
76 | line-height: 1.6;
77 | font-family: "Marmelad", "Lucida Grande", "Arial", "Hiragino Sans GB", Georgia, sans-serif;
78 | font-size: @N_fontSize;
79 | box-sizing: initial;
80 | &:after{
81 | display: table;
82 | content: " ";
83 | clear: both;
84 | }
85 | .paginationjs-pages{
86 | float: left;
87 | margin-left: 10px;
88 | ul{
89 | float: left;
90 | margin: 0;
91 | padding: 0;
92 | }
93 | li{
94 | float: left;
95 | border: 1px solid @borderColor;
96 | border-right: none;
97 | list-style: none;
98 | > a{
99 | min-width: @N_minWidth;
100 | height: @N_height;
101 | line-height: @N_lineHeight;
102 | display: block;
103 | background: #fff;
104 | font-size: @N_fontSize;
105 | color: #333;
106 | text-decoration: none;
107 | text-align: center;
108 | cursor: pointer;
109 | &:hover{
110 | background: #eee;
111 | }
112 | }
113 | &.active{
114 | border: none;
115 | > a{
116 | height: @N_activeHeight;
117 | line-height: @N_activeHeight;
118 | background: @activeBgColor;
119 | color: #fff;
120 | cursor: default;
121 | }
122 | }
123 | &.disabled{
124 | > a{
125 | opacity: .3;
126 | cursor: default;
127 | &:hover{
128 | background: none;
129 | }
130 | }
131 | }
132 | &:first-child{
133 | border-radius: 3px 0 0 3px;
134 | > a{
135 | border-radius: 3px 0 0 3px;
136 | }
137 | }
138 | &:last-child{
139 | border-right: 1px solid @borderColor;
140 | border-radius: 0 3px 3px 0;
141 | > a{
142 | border-radius: 0 3px 3px 0;
143 | }
144 | }
145 | }
146 | }
147 | .paginationjs-size-changer {
148 | float: left;
149 | font-size: @N_fontSize;
150 | margin-left: 10px;
151 | > select{
152 | height: @N_inputHeight;
153 | background: #fff;
154 | border-radius: 3px;
155 | border: 1px solid @borderColor;
156 | padding: 0;
157 | font-size: @N_fontSize;
158 | text-align: center;
159 | vertical-align: baseline;
160 | outline: none;
161 | box-shadow: none;
162 | box-sizing: initial;
163 | }
164 | }
165 | .paginationjs-go-input{
166 | float: left;
167 | margin-left: 10px;
168 | font-size: @N_fontSize;
169 | > input[type="text"]{
170 | width: @N_inputWidth;
171 | height: @N_inputHeight;
172 | background: #fff;
173 | border-radius: 3px;
174 | border: 1px solid @borderColor;
175 | padding: 0;
176 | font-size: @N_fontSize;
177 | text-align: center;
178 | vertical-align: baseline;
179 | outline: none;
180 | box-shadow: none;
181 | box-sizing: initial;
182 | }
183 | }
184 | .paginationjs-go-button{
185 | float: left;
186 | margin-left: 10px;
187 | font-size: @N_fontSize;
188 | > input[type="button"]{
189 | min-width: @N_buttonMinWidth;
190 | height: @N_buttonHeight;
191 | line-height: @N_buttonLineHeight;
192 | background: #fff;
193 | border-radius: 3px;
194 | border: 1px solid @borderColor;
195 | text-align: center;
196 | padding: @N_buttonPadding;
197 | font-size: @N_fontSize;
198 | vertical-align: baseline;
199 | outline: none;
200 | box-shadow: none;
201 | color: #333;
202 | cursor: pointer;
203 | &:hover{
204 | background-color: #f8f8f8;
205 | }
206 | }
207 | }
208 | .paginationjs-nav{
209 | float: left;
210 | height: @N_navHeight;
211 | line-height: @N_navHeight;
212 | font-size: @N_fontSize;
213 | }
214 |
215 | &.paginationjs-small{
216 | font-size: @S_fontSize;
217 | .paginationjs-pages{
218 | li{
219 | > a{
220 | min-width: @S_minWidth;
221 | height: @S_height;
222 | line-height: @S_lineHeight;
223 | font-size: @S_fontSize;
224 | }
225 | &.active{
226 | > a{
227 | height: @S_activeHeight;
228 | line-height: @S_activeHeight;
229 | }
230 | }
231 | }
232 | }
233 | .paginationjs-size-changer {
234 | font-size: @S_fontSize;
235 | > select{
236 | height: @S_inputHeight;
237 | font-size: @S_fontSize;
238 | }
239 | }
240 | .paginationjs-go-input{
241 | font-size: @S_fontSize;
242 | > input[type="text"]{
243 | width: @S_inputWidth;
244 | height: @S_inputHeight;
245 | font-size: @S_fontSize;
246 | }
247 | }
248 | .paginationjs-go-button{
249 | font-size: @S_fontSize;
250 | > input[type="button"]{
251 | min-width: @S_buttonMinWidth;
252 | height: @S_buttonHeight;
253 | line-height: @S_buttonLineHeight;
254 | padding: @S_buttonPadding;
255 | font-size: @S_fontSize;
256 | }
257 | }
258 | .paginationjs-nav{
259 | height: 26px;
260 | line-height: 26px;
261 | font-size: @S_fontSize;
262 | }
263 | }
264 | &.paginationjs-big{
265 | font-size: @B_fontSize;
266 | .paginationjs-pages{
267 | li{
268 | > a{
269 | min-width: @B_minWidth;
270 | height: @B_height;
271 | line-height: @B_lineHeight;
272 | font-size: @B_fontSize;
273 | }
274 | &.active{
275 | > a{
276 | height: @B_activeHeight;
277 | line-height: @B_activeHeight;
278 | }
279 | }
280 | }
281 | }
282 | .paginationjs-size-changer {
283 | font-size: @B_fontSize;
284 | > select{
285 | height: @B_inputHeight;
286 | font-size: @B_fontSize;
287 | }
288 | }
289 | .paginationjs-go-input{
290 | font-size: @B_fontSize;
291 | > input[type="text"]{
292 | width: @B_inputWidth;
293 | height: @B_inputHeight;
294 | font-size: @B_fontSize;
295 | }
296 | }
297 | .paginationjs-go-button{
298 | font-size: @B_fontSize;
299 | > input[type="button"]{
300 | min-width: @B_buttonMinWidth;
301 | height: @B_buttonHeight;
302 | line-height: @B_buttonLineHeight;
303 | padding: @B_buttonPadding;
304 | font-size: @B_fontSize;
305 | }
306 | }
307 | .paginationjs-nav{
308 | height: @B_navHeight;
309 | line-height: @B_navHeight;
310 | font-size: @B_fontSize;
311 | }
312 | }
313 |
314 | > :first-child {
315 | margin-left: 0;
316 | }
317 | }
318 |
319 | .paginationjs{
320 | &.paginationjs-theme-blue{
321 | .paginationjs-pages{
322 | li{
323 | border-color: @Blue_color_border;
324 | > a{
325 | color: @Blue_color_font;
326 | &:hover{
327 | background: @Blue_bgColor_hover;
328 | }
329 | }
330 | &.active{
331 | > a{
332 | background: @Blue_bgColor_active;
333 | color: #fff;
334 | }
335 | }
336 | &.disabled > a:hover{
337 | background: none;
338 | }
339 | }
340 | }
341 | .paginationjs-size-changer {
342 | > select{
343 | border-color: @Blue_color_border;
344 | }
345 | }
346 | .paginationjs-go-input{
347 | > input[type="text"]{
348 | border-color: @Blue_color_border;
349 | }
350 | }
351 | .paginationjs-go-button{
352 | > input[type="button"]{
353 | background: @Blue_bgColor_active;
354 | border-color: @Blue_color_border;
355 | color: #fff;
356 | &:hover{
357 | background-color: @Blue_bgColor_buttonHover;
358 | }
359 | }
360 | }
361 | }
362 | }
363 |
364 | .paginationjs{
365 | &.paginationjs-theme-green{
366 | .paginationjs-pages{
367 | li{
368 | border-color: @Green_color_border;
369 | > a{
370 | color: @Green_color_font;
371 | &:hover{
372 | background: @Green_bgColor_hover;
373 | }
374 | }
375 | &.active{
376 | > a{
377 | background: @Green_bgColor_active;
378 | color: #fff;
379 | }
380 | }
381 | &.disabled > a:hover{
382 | background: none;
383 | }
384 | }
385 | }
386 | .paginationjs-size-changer {
387 | > select{
388 | border-color: @Green_color_border;
389 | }
390 | }
391 | .paginationjs-go-input{
392 | > input[type="text"]{
393 | border-color: @Green_color_border;
394 | }
395 | }
396 | .paginationjs-go-button{
397 | > input[type="button"]{
398 | background: @Green_bgColor_active;
399 | border-color: @Green_color_border;
400 | color: #fff;
401 | &:hover{
402 | background-color: @Green_bgColor_buttonHover;
403 | }
404 | }
405 | }
406 | }
407 | }
408 |
409 | .paginationjs{
410 | &.paginationjs-theme-yellow{
411 | .paginationjs-pages{
412 | li{
413 | border-color: @Yellow_color_border;
414 | > a{
415 | color: @Yellow_color_font;
416 | &:hover{
417 | background: @Yellow_bgColor_hover;
418 | }
419 | }
420 | &.active{
421 | > a{
422 | background: @Yellow_bgColor_active;
423 | color: #fff;
424 | }
425 | }
426 | &.disabled > a:hover{
427 | background: none;
428 | }
429 | }
430 | }
431 | .paginationjs-size-changer {
432 | > select{
433 | border-color: @Yellow_color_border;
434 | }
435 | }
436 | .paginationjs-go-input{
437 | > input[type="text"]{
438 | border-color: @Yellow_color_border;
439 | }
440 | }
441 | .paginationjs-go-button{
442 | > input[type="button"]{
443 | background: @Yellow_bgColor_active;
444 | border-color: @Yellow_color_border;
445 | color: #fff;
446 | &:hover{
447 | background-color: @Yellow_bgColor_buttonHover;
448 | }
449 | }
450 | }
451 | }
452 | }
453 |
454 | .paginationjs{
455 | &.paginationjs-theme-red{
456 | .paginationjs-pages{
457 | li{
458 | border-color: @Red_color_border;
459 | > a{
460 | color: @Red_color_font;
461 | &:hover{
462 | background: @Red_bgColor_hover;
463 | }
464 | }
465 | &.active{
466 | > a{
467 | background: @Red_bgColor_active;
468 | color: #fff;
469 | }
470 | }
471 | &.disabled > a:hover{
472 | background: none;
473 | }
474 | }
475 | }
476 | .paginationjs-size-changer {
477 | > select{
478 | border-color: @Red_color_border;
479 | }
480 | }
481 | .paginationjs-go-input{
482 | > input[type="text"]{
483 | border-color: @Red_color_border;
484 | }
485 | }
486 | .paginationjs-go-button{
487 | > input[type="button"]{
488 | background: @Red_bgColor_active;
489 | border-color: @Red_color_border;
490 | color: #fff;
491 | &:hover{
492 | background-color: @Red_bgColor_buttonHover;
493 | }
494 | }
495 | }
496 | }
497 | }
498 |
499 | /* Hacks for IE 6~9 */
500 | .paginationjs{
501 | .paginationjs-pages{
502 | li{
503 | > a{
504 |
505 | }
506 | &.paginationjs-next{
507 | *border-right: 1px solid @borderColor;
508 | border-right: 1px solid #aaa\0;
509 | }
510 | }
511 | }
512 | .paginationjs-size-changer{
513 | *margin-left: 5px;
514 | margin-left: 5px\0;
515 | > select{
516 | *line-height: @N_inputHeight;
517 | line-height: 28px\0;
518 | *vertical-align: middle;
519 | vertical-align: middle\0;
520 | }
521 | }
522 | .paginationjs-go-input{
523 | *margin-left: 5px;
524 | margin-left: 5px\0;
525 | > input[type="text"]{
526 | *line-height: @N_inputHeight;
527 | line-height: 28px\0;
528 | *vertical-align: middle;
529 | vertical-align: middle\0;
530 | }
531 | }
532 | .paginationjs-go-button{
533 | *margin-left: 5px;
534 | margin-left: 5px\0;
535 | > input[type="button"]{
536 | *vertical-align: middle;
537 | vertical-align: middle\0;
538 | }
539 | }
540 | &.paginationjs-big{
541 | .paginationjs-pages{
542 | li{
543 | > a{
544 | line-height: 36px\0;
545 | }
546 | }
547 | }
548 | .paginationjs-go-input{
549 | > input[type="text"]{
550 | *height: 35px;
551 | height: 36px\0;
552 | *line-height: 36px;
553 | line-height: 36px\0;
554 | }
555 | }
556 | }
557 | }
558 |
--------------------------------------------------------------------------------
/dist/pagination.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | * pagination.js 2.6.0
3 | * A jQuery plugin to provide simple yet fully customisable pagination
4 | * https://github.com/superRaytin/paginationjs
5 |
6 | * Homepage: http://pagination.js.org
7 | *
8 | * Copyright 2014-2100, superRaytin
9 | * Released under the MIT license.
10 | */
11 | !function(n,u){void 0===u&&l("Pagination requires jQuery.");var r="pagination",s="__pagination-",D=(u.fn.pagination&&l('plugin conflicted, the name "pagination" has been taken by another jQuery plugin.'),u.fn[r]=function(a){if(void 0!==a){var t,c=u(this),J=u.extend({},u.fn[r].defaults,a),e={initialize:function(){var e,t=this;c.data("pagination")||c.data("pagination",{}),!1!==t.callHook("beforeInit")&&(c.data("pagination").initialized&&u(".paginationjs",c).remove(),t.disabled=!!J.disabled,e=t.model={pageRange:J.pageRange,pageSize:J.pageSize},t.parseDataSource(J.dataSource,function(a){t.isAsync=D.isString(a),D.isArray(a)&&(e.totalNumber=J.totalNumber=a.length),t.isDynamicTotalNumber=t.isAsync&&J.totalNumberLocator;a=t.render(!0);J.className&&a.addClass(J.className),e.el=a,c["bottom"===J.position?"append":"prepend"](a),t.observer(),c.data("pagination").initialized=!0,t.callHook("afterInit",a)}))},render:function(a){var e=this,t=e.model,o=t.el||u(''),a=!0!==a,t=(e.callHook("beforeRender",a),t.pageNumber||J.pageNumber),i=J.pageRange||0,n=e.getTotalPage(),r=t-i,s=t+i;return(r=n${a}`:`${a}`},generatePageNumbersHTML:function(a){var e,t=a.currentPage,o=this.getTotalPage(),i=this.getPageLinkTag,n=a.rangeStart,r=a.rangeEnd,s="",a=J.ellipsisText,l=J.classPrefix,c=J.pageClassName||"",u=J.activeClassName||"",g=J.disableClassName||"";if(null===J.pageRange)for(e=1;e<=o;e++)s+=e==t?``:``;else{if(n<=3)for(e=1;e