51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/src/core/computed.ts:
--------------------------------------------------------------------------------
1 | import * as v from "./utils";
2 |
3 | export function isNoPreviousOrDisabled(this: uibPagination) {
4 | return this.noPrevious || this.disabled;
5 | }
6 |
7 | export function isNoNextOrDisabled(this: uibPagination) {
8 | return this.noNext || this.disabled;
9 | }
10 |
11 | export function noNext(this: uibPagination) {
12 | return this.value.currentPage === this.totalPages;
13 | }
14 |
15 | export function noPrevious(this: uibPagination) {
16 | return this.value.currentPage === 1;
17 | }
18 |
19 | export function totalPages(this: uibPagination) {
20 | let totalPages = this.itemsPerPage < 1 ? 1 : Math.ceil(this.totalItems / this.itemsPerPage);
21 | return Math.max(totalPages || 0, 1);
22 | }
23 |
24 | export function pages(this: uibPagination) {
25 | let pages: Array = [];
26 |
27 | if (this.currentPage <= 0 || this.currentPage > this.totalPages) {
28 | return pages;
29 | }
30 |
31 | // Default page limits
32 | let startPage = 1, endPage = this.totalPages;
33 | let isMaxSized = v.isDefined(this.maxSize) && this.maxSize < this.totalPages;
34 |
35 | // recompute if maxSize
36 | if (isMaxSized) {
37 | if (this.rotate) {
38 | // Current page is displayed in the middle of the visible ones
39 | startPage = Math.max(this.currentPage - Math.floor(this.maxSize / 2), 1);
40 | endPage = startPage + this.maxSize - 1;
41 |
42 | // Adjust if limit is exceeded
43 | if (endPage > this.totalPages) {
44 | endPage = this.totalPages;
45 | startPage = endPage - this.maxSize + 1;
46 | }
47 | } else {
48 | // Visible pages are paginated with maxSize
49 | startPage = (Math.ceil(this.currentPage / this.maxSize) - 1) * this.maxSize + 1;
50 |
51 | // Adjust last page if limit is exceeded
52 | endPage = Math.min(startPage + this.maxSize - 1, this.totalPages);
53 | }
54 | }
55 |
56 | // Add page number links
57 | for (let number = startPage; number <= endPage; number++) {
58 | let page = this.makePage(number, this.pageLabel(number), number === this.currentPage);
59 | pages.push(page);
60 | }
61 |
62 | // Add links to move between page sets
63 | if (isMaxSized && this.maxSize > 0 && (!this.rotate || this.forceEllipses || this.boundaryLinkNumbers)) {
64 | if (startPage > 1) {
65 | if (!this.boundaryLinkNumbers || startPage > 3) { //need ellipsis for all options unless range is too close to beginning
66 | let previousPageSet = this.makePage(startPage - 1, '...', false);
67 | pages.unshift(previousPageSet);
68 | }
69 | if (this.boundaryLinkNumbers) {
70 | if (startPage === 3) { //need to replace ellipsis when the buttons would be sequential
71 | let secondPageLink = this.makePage(2, '2', false);
72 | pages.unshift(secondPageLink);
73 | }
74 | //add the first page
75 | let firstPageLink = this.makePage(1, '1', false);
76 | pages.unshift(firstPageLink);
77 | }
78 | }
79 |
80 | if (endPage < this.totalPages) {
81 | if (!this.boundaryLinkNumbers || endPage < this.totalPages - 2) { //need ellipsis for all options unless range is too close to end
82 | let nextPageSet = this.makePage(endPage + 1, '...', false);
83 | pages.push(nextPageSet);
84 | }
85 | if (this.boundaryLinkNumbers) {
86 | if (endPage === this.totalPages - 2) { //need to replace ellipsis when the buttons would be sequential
87 | let secondToLastPageLink = this.makePage(this.totalPages - 1, this.totalPages - 1, false);
88 | pages.push(secondToLastPageLink);
89 | }
90 | //add the last page
91 | let lastPageLink = this.makePage(this.totalPages, this.totalPages, false);
92 | pages.push(lastPageLink);
93 | }
94 | }
95 | }
96 |
97 | // Emit the new data to the parent.
98 | this.$emit("input", this.createDataForModel(this.currentPage, this.totalPages));
99 |
100 | return pages;
101 | }
--------------------------------------------------------------------------------
/src/types/vuejs-uib-pagination.d.ts:
--------------------------------------------------------------------------------
1 | interface uibPagination extends uibPaginationComputed, uibPaginationMethods, uibPaginationModel, uibPaginationProps { }
2 |
3 | interface uibPaginationData extends uibPaginationMethods, uibPaginationProps { }
4 |
5 | interface uibPaginationComputed {
6 | /** Computed - Has reached the last page. */
7 | readonly noNext: boolean;
8 |
9 | /** Computed - Has reached the first page. */
10 | readonly noPrevious: boolean;
11 |
12 | /** Computed - Shorhand for is noPrevious or disabled. */
13 | readonly isNoPreviousOrDisabled: boolean;
14 |
15 | /** Computed - Shorhand for is noNext or disabled. */
16 | readonly isNoNextOrDisabled: boolean;
17 |
18 | /** Computed - Total number of pages to display. */
19 | readonly totalPages: number;
20 | }
21 |
22 | interface uibPaginationMethods {
23 | /** Method - Mutate parent's v-model. */
24 | $emit(input: string, value?: any): void;
25 |
26 | /** Method - Create a schema for parent's model. */
27 | createDataForModel(currentPage: number, numPages: number): uibParentModel;
28 |
29 | /** Method - Create a schema for each page in the pagination plugin. */
30 | makePage(number: number, text: string | number, isActive: boolean): uibPage;
31 | }
32 |
33 | interface uibPaginationModel {
34 | /** Model - Current page number. */
35 | currentPage: number;
36 | }
37 |
38 | interface uibPaginationProps {
39 | /** Property - Whether to display First / Last buttons. */
40 | readonly boundaryLinks: boolean;
41 |
42 | /** Property - Whether to always display the first and last page numbers. If max-size is smaller than the number of pages, then the first and last page numbers are still shown with ellipses in-between as necessary. NOTE: max-size refers to the center of the range. This option may add up to 2 more numbers on each side of the displayed range for the end value and what would be an ellipsis but is replaced by a number because it is sequential. */
43 | readonly boundaryLinkNumbers: boolean;
44 |
45 | /** Property - Whether to display Previous / Next buttons. */
46 | readonly directionLinks: boolean;
47 |
48 | /** Property - Used to disable the pagination component. */
49 | readonly disabled: boolean;
50 |
51 | /** Property - Text for First button. */
52 | readonly firstText: string;
53 |
54 | /** Property - Also displays ellipses when rotate is true and max-size is smaller than the number of pages. */
55 | readonly forceEllipses: boolean;
56 |
57 | /** Property - Maximum number of items per page. A value less than one indicates all items on one page. */
58 | readonly itemsPerPage: number;
59 |
60 | /** Property - Text for Last button. */
61 | readonly lastText: string;
62 |
63 | /** Property - Limit number for pagination size. */
64 | readonly maxSize: number;
65 |
66 | /** Property - Text for Next button. */
67 | readonly nextText: string;
68 |
69 | /** Property - Emit `change` events on click. */
70 | readonly changeOnClick: boolean;
71 |
72 | /** Property - V-model from parent. */
73 | readonly value: uibParentModel;
74 |
75 | /** Property - Override the page label based on passing the current page indexes. Supports page number with a paramenter. */
76 | readonly pageLabel: Function;
77 |
78 | /** Property - Text for Previous button. */
79 | readonly previousText: string;
80 |
81 | /** Property - Whether to keep current page in the middle of the visible ones. */
82 | readonly rotate: boolean;
83 |
84 | /** Property - Total number of items in all pages. */
85 | readonly totalItems: number;
86 | }
87 |
88 | interface uibParentModel {
89 | /** Current page number. */
90 | readonly currentPage: number;
91 |
92 | /** Total number of pages to display. */
93 | readonly numPages: number;
94 | }
95 |
96 | interface uibPage {
97 | /** Number page. */
98 | number: number;
99 |
100 | /** Content page. */
101 | text: string | number;
102 |
103 | /** Is active? */
104 | active: boolean;
105 | }
106 |
107 | interface vueBinding {
108 | readonly name: string;
109 | readonly value: any;
110 | readonly oldValue: any;
111 | readonly expression: any;
112 | readonly arg: string;
113 | readonly modifiers: { [key: string]: boolean };
114 | }
115 |
116 | declare module "*.html" {
117 | var html: string;
118 | export default html;
119 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vuejs-uib-pagination
2 | Best and complete pagination plugin for Vue.js 2.0. Inspired in [Angular Bootstrap Pagination](https://angular-ui.github.io/bootstrap/#pagination).
3 |
4 | ## Not Using Bootstrap?
5 | No problem! The plugin template is not 100% Bootstrap dependent, that is why you can build your own styles for your pagination!
6 |
7 | ## Demo
8 | Click [here](https://plnkr.co/edit/hcfYWCTaQ7GnlO7AitGM?p=preview).
9 |
10 | ## Installation
11 |
12 | ```sh
13 | $ npm install vuejs-uib-pagination
14 | ```
15 |
16 | ## Quick Start
17 |
18 | Global:
19 |
20 | ```html
21 |
22 |
23 | ```
24 |
25 | CommonJS:
26 |
27 | ```javascript
28 | var Vue = require("vue");
29 | var pagination = require("vuejs-uib-pagination");
30 |
31 | Vue.use(pagination);
32 | ```
33 |
34 | ES2015:
35 |
36 | ```javascript
37 | import * as Vue from "vue";
38 | import pagination from "vuejs-uib-pagination";
39 |
40 | Vue.use(pagination);
41 | ```
42 |
43 | ## Use
44 |
45 | HTML:
46 |
47 | ```html
48 |
49 |
50 |
51 |
52 |
53 | ```
54 |
55 | Script:
56 |
57 | ```javascript
58 | var app = new Vue({
59 | el: "#app",
60 | data: {
61 | pagination: { }
62 | }
63 | });
64 | ```
65 |
66 | ## Settings
67 |
68 | The settings are almost the same as Angular Bootstrap Pagination, there are only 3 differences:
69 |
70 | * `v-model` is an object and has these keys:
71 | * currentPage
72 | * numPages (avoid [props mutation anti-patern](https://vuejs.org/v2/guide/migration.html#Prop-Mutation-deprecated))
73 | * `page-label` does not accept expressions, it works with functions.
74 | * `template-url` is not supported.
75 |
76 | ### boundary-links
77 |
78 | (Default: false) - Whether to display First / Last buttons.
79 |
80 | ```html
81 |
82 | ```
83 |
84 | ### boundary-link-numbers
85 |
86 | (Default: false) - Whether to always display the first and last page numbers. If max-size is smaller than the number of pages, then the first and last page numbers are still shown with ellipses in-between as necessary. NOTE: max-size refers to the center of the range. This option may add up to 2 more numbers on each side of the displayed range for the end value and what would be an ellipsis but is replaced by a number because it is sequential.
87 |
88 | ```html
89 |
90 | ```
91 |
92 | ### direction-links
93 |
94 | (Default: true) - Whether to display Previous / Next buttons.
95 |
96 | ```html
97 |
98 | ```
99 |
100 | ### first-text
101 |
102 | (Default: First) - Text for First button.
103 |
104 | ```html
105 |
106 | ```
107 |
108 | ### force-ellipses
109 |
110 | (Default: false) - Also displays ellipses when rotate is true and max-size is smaller than the number of pages.
111 |
112 | ```html
113 |
114 | ```
115 |
116 | ### items-per-page
117 |
118 | (Default: 10) - Maximum number of items per page. A value less than one indicates all items on one page.
119 |
120 | ```html
121 |
122 | ```
123 |
124 | ### last-text
125 | (Default: Last) - Text for Last button.
126 |
127 | ```html
128 |
129 | ```
130 |
131 | ### max-size
132 | (Default: null) - Limit number for pagination size.
133 |
134 | ```html
135 |
136 | ```
137 |
138 | ### next-text
139 | (Default: Next) - Text for Next button.
140 |
141 | ```html
142 |
143 | ```
144 |
145 | ### change
146 | This can be used to call a function whenever the page changes.
147 |
148 | ```html
149 |
150 | ```
151 |
152 | ### disabled
153 | (Default: false) - Used to disable the pagination component.
154 |
155 | ```html
156 |
157 | ```
158 |
159 | ### v-model
160 | (Required)
161 | * pagination (Default: 1) - Current page number. First page is 1.
162 | * numPages (Readonly) - Total number of pages to display.
163 |
164 | ```html
165 |
166 | ```
167 |
168 | ### page-label
169 | (Default: identity) - Override the page label based on passing the current page indexes. Supports page number with a paramenter.
170 |
171 | ```html
172 |
173 | ```
174 |
175 | ### previous-text
176 | (Default: Previous) - Text for Previous button.
177 |
178 | ```html
179 |
180 | ```
181 |
182 | ### rotate
183 | (Default: true) - Whether to keep current page in the middle of the visible ones.
184 |
185 | ```html
186 |
187 | ```
188 |
189 | ### total-items
190 | Total number of items in all pages.
191 |
192 | ```html
193 |
194 | ```
195 |
196 | ## Inspiration
197 | Give people comming from Angular.js major facility to use pagination.
198 |
199 | ## License
200 |
201 | [MIT](LICENSE)
202 |
--------------------------------------------------------------------------------
/dist/vuejs-uib-pagination.js:
--------------------------------------------------------------------------------
1 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports["vuejs-uib-pagination"]=t():e["vuejs-uib-pagination"]=t()}(this,function(){return function(e){function t(a){if(i[a])return i[a].exports;var n=i[a]={i:a,l:!1,exports:{}};return e[a].call(n.exports,n,n.exports,t),n.l=!0,n.exports}var i={};return t.m=e,t.c=i,t.d=function(e,i,a){t.o(e,i)||Object.defineProperty(e,i,{configurable:!1,enumerable:!0,get:a})},t.n=function(e){var i=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(i,"a",i),i},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=1)}([function(e,t,i){"use strict";t.a=function(e){return e},t.b=function(e){return void 0!==e}},function(e,t,i){"use strict";function a(e,t){e.component("uib-pagination",{data:n.a,props:o,watch:r.a,methods:l,template:u.a,computed:c,directives:d})}Object.defineProperty(t,"__esModule",{value:!0}),i.d(t,"install",function(){return a});var n=i(2),r=i(3),s=i(4),u=i.n(s),o=i(5),l=i(6),c=i(7),d=i(8);t.default=a,"undefined"!=typeof window&&window.Vue&&window.Vue.use(a)},function(e,t,i){"use strict";var a=i(0);t.a=function(){return{currentPage:a.b(this.value.currentPage)?this.value.currentPage:1}}},function(e,t,i){"use strict";t.a={"value.currentPage":function(e,t){this.currentPage=e,null!=t&&(this.changeOnClick||this.$emit("change"))}}},function(e,t){e.exports='