├── .editorconfig ├── .eslintrc.json ├── .gitattributes ├── .gitignore ├── .travis.yml ├── .verb.md ├── LICENSE ├── README.md ├── index.js ├── lib ├── page.js └── pages.js ├── package.json └── test.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | end_of_line = lf 6 | charset = utf-8 7 | indent_size = 2 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [{,**/}{actual,fixtures,expected,templates}/**/*.*] 12 | trim_trailing_whitespace = false 13 | insert_final_newline = false 14 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "ecmaFeatures": { 3 | "modules": true, 4 | "experimentalObjectRestSpread": true 5 | }, 6 | 7 | "env": { 8 | "browser": false, 9 | "es6": true, 10 | "node": true, 11 | "mocha": true 12 | }, 13 | 14 | "globals": { 15 | "document": false, 16 | "navigator": false, 17 | "window": false 18 | }, 19 | 20 | "rules": { 21 | "accessor-pairs": 2, 22 | "arrow-spacing": [2, { "before": true, "after": true }], 23 | "block-spacing": [2, "always"], 24 | "brace-style": [2, "1tbs", { "allowSingleLine": true }], 25 | "comma-dangle": [2, "never"], 26 | "comma-spacing": [2, { "before": false, "after": true }], 27 | "comma-style": [2, "last"], 28 | "constructor-super": 2, 29 | "curly": [2, "multi-line"], 30 | "dot-location": [2, "property"], 31 | "eol-last": 2, 32 | "eqeqeq": [2, "allow-null"], 33 | "generator-star-spacing": [2, { "before": true, "after": true }], 34 | "handle-callback-err": [2, "^(err|error)$" ], 35 | "indent": [2, 2, { "SwitchCase": 1 }], 36 | "key-spacing": [2, { "beforeColon": false, "afterColon": true }], 37 | "keyword-spacing": [2, { "before": true, "after": true }], 38 | "new-cap": [2, { "newIsCap": true, "capIsNew": false }], 39 | "new-parens": 2, 40 | "no-array-constructor": 2, 41 | "no-caller": 2, 42 | "no-class-assign": 2, 43 | "no-cond-assign": 2, 44 | "no-const-assign": 2, 45 | "no-control-regex": 2, 46 | "no-debugger": 2, 47 | "no-delete-var": 2, 48 | "no-dupe-args": 2, 49 | "no-dupe-class-members": 2, 50 | "no-dupe-keys": 2, 51 | "no-duplicate-case": 2, 52 | "no-empty-character-class": 2, 53 | "no-eval": 2, 54 | "no-ex-assign": 2, 55 | "no-extend-native": 2, 56 | "no-extra-bind": 2, 57 | "no-extra-boolean-cast": 2, 58 | "no-extra-parens": [2, "functions"], 59 | "no-fallthrough": 2, 60 | "no-floating-decimal": 2, 61 | "no-func-assign": 2, 62 | "no-implied-eval": 2, 63 | "no-inner-declarations": [2, "functions"], 64 | "no-invalid-regexp": 2, 65 | "no-irregular-whitespace": 2, 66 | "no-iterator": 2, 67 | "no-label-var": 2, 68 | "no-labels": 2, 69 | "no-lone-blocks": 2, 70 | "no-mixed-spaces-and-tabs": 2, 71 | "no-multi-spaces": 2, 72 | "no-multi-str": 2, 73 | "no-multiple-empty-lines": [2, { "max": 1 }], 74 | "no-native-reassign": 0, 75 | "no-negated-in-lhs": 2, 76 | "no-new": 2, 77 | "no-new-func": 2, 78 | "no-new-object": 2, 79 | "no-new-require": 2, 80 | "no-new-wrappers": 2, 81 | "no-obj-calls": 2, 82 | "no-octal": 2, 83 | "no-octal-escape": 2, 84 | "no-proto": 0, 85 | "no-redeclare": 2, 86 | "no-regex-spaces": 2, 87 | "no-return-assign": 2, 88 | "no-self-compare": 2, 89 | "no-sequences": 2, 90 | "no-shadow-restricted-names": 2, 91 | "no-spaced-func": 2, 92 | "no-sparse-arrays": 2, 93 | "no-this-before-super": 2, 94 | "no-throw-literal": 2, 95 | "no-trailing-spaces": 0, 96 | "no-undef": 2, 97 | "no-undef-init": 2, 98 | "no-unexpected-multiline": 2, 99 | "no-unneeded-ternary": [2, { "defaultAssignment": false }], 100 | "no-unreachable": 2, 101 | "no-unused-vars": [2, { "vars": "all", "args": "none" }], 102 | "no-useless-call": 0, 103 | "no-with": 2, 104 | "one-var": [0, { "initialized": "never" }], 105 | "operator-linebreak": [0, "after", { "overrides": { "?": "before", ":": "before" } }], 106 | "padded-blocks": [0, "never"], 107 | "quotes": [2, "single", "avoid-escape"], 108 | "radix": 2, 109 | "semi": [2, "always"], 110 | "semi-spacing": [2, { "before": false, "after": true }], 111 | "space-before-blocks": [2, "always"], 112 | "space-before-function-paren": [2, "never"], 113 | "space-in-parens": [2, "never"], 114 | "space-infix-ops": 2, 115 | "space-unary-ops": [2, { "words": true, "nonwords": false }], 116 | "spaced-comment": [0, "always", { "markers": ["global", "globals", "eslint", "eslint-disable", "*package", "!", ","] }], 117 | "use-isnan": 2, 118 | "valid-typeof": 2, 119 | "wrap-iife": [2, "any"], 120 | "yoda": [2, "never"] 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Enforce Unix newlines 2 | * text eol=lf 3 | 4 | # binaries 5 | *.ai binary 6 | *.psd binary 7 | *.jpg binary 8 | *.gif binary 9 | *.png binary 10 | *.jpeg binary -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | *.sublime-* 3 | _gh_pages 4 | bower_components 5 | node_modules 6 | npm-debug.log 7 | actual 8 | test/actual 9 | temp 10 | tmp 11 | TODO.md 12 | vendor 13 | .idea 14 | benchmark 15 | coverage 16 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - '6' 5 | - '5' 6 | - '4' 7 | - '0.12' 8 | - '0.10' 9 | matrix: 10 | fast_finish: true 11 | allow_failures: 12 | - node_js: '4' 13 | - node_js: '0.10' 14 | - node_js: '0.12' 15 | -------------------------------------------------------------------------------- /.verb.md: -------------------------------------------------------------------------------- 1 | ![image](https://cloud.githubusercontent.com/assets/995160/9802527/ca15f300-57e8-11e5-96db-523ea5a0572e.png) 2 | 3 | ## Usage 4 | 5 | ```js 6 | var paginationator = require('{%= name %}'); 7 | ``` 8 | 9 | ## API 10 | {%= apidocs("index.js") %} 11 | {%= apidocs("lib/page.js") %} 12 | {%= apidocs("lib/pages.js") %} 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015-2016, Brian Woodward 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # paginationator [![NPM version](https://img.shields.io/npm/v/paginationator.svg?style=flat)](https://www.npmjs.com/package/paginationator) [![NPM downloads](https://img.shields.io/npm/dm/paginationator.svg?style=flat)](https://npmjs.org/package/paginationator) [![Build Status](https://img.shields.io/travis/doowb/paginationator.svg?style=flat)](https://travis-ci.org/doowb/paginationator) 2 | 3 | Paginate an array into pages of items. 4 | 5 | ## Install 6 | 7 | Install with [npm](https://www.npmjs.com/): 8 | 9 | ```sh 10 | $ npm install --save paginationator 11 | ``` 12 | 13 | ![image](https://cloud.githubusercontent.com/assets/995160/9802527/ca15f300-57e8-11e5-96db-523ea5a0572e.png) 14 | 15 | ## Usage 16 | 17 | ```js 18 | var paginationator = require('paginationator'); 19 | ``` 20 | 21 | ## API 22 | 23 | ### [paginationator](index.js#L34) 24 | 25 | Paginate an array with given options and return a `Page` object containing an array of `pages` with pagination information. 26 | 27 | **Params** 28 | 29 | * `arr` **{Array}**: Array of items to paginate 30 | * `options` **{Object}**: Additional options to control pagination 31 | * `options.limit` **{Number}**: Number of items per page (defaults to 10) 32 | * `returns` **{Object}**: paginated pages 33 | 34 | **Example** 35 | 36 | ```js 37 | var pages = paginationator([1, 2, 3, 4, 5], {limit: 2}); 38 | //=> { pages: [ 39 | //=> { idx: 0, total: 3, current: 1, items: [1, 2], first: 1, last: 3, next: 2 }, 40 | //=> { idx: 1, total: 3, current: 2, items: [3, 4], first: 1, last: 3, prev: 1, next: 3 }, 41 | //=> { idx: 2, total: 3, current: 3, items: [5], first: 1, last: 3, prev: 2 } 42 | //=> ]} 43 | ``` 44 | 45 | ### [Page](lib/page.js#L14) 46 | 47 | Page constructor 48 | 49 | **Params** 50 | 51 | * `page` **{Object}**: optional page object to populate initial values. 52 | 53 | **Example** 54 | 55 | ```js 56 | var page = new Page(); 57 | ``` 58 | 59 | ### [Pages](lib/pages.js#L16) 60 | 61 | Pages constructor 62 | 63 | **Params** 64 | 65 | * `pages` **{Array}**: Optional array of pages to initialize the `pages` array. 66 | 67 | **Example** 68 | 69 | ```js 70 | var pages = new Pages(); 71 | ``` 72 | 73 | ### [.addPage](lib/pages.js#L37) 74 | 75 | Add a page to the list. 76 | 77 | **Params** 78 | 79 | * `page` **{Object}**: Plain object or instance of a `Page` 80 | * `returns` **{Object}**: Returns the instance for chaining 81 | 82 | **Example** 83 | 84 | ```js 85 | pages.addPage({items: [1, 2, 3]}); 86 | ``` 87 | 88 | ### [.addPages](lib/pages.js#L55) 89 | 90 | Add an array of pages to the list. 91 | 92 | **Params** 93 | 94 | * `pages` **{Object}**: Array of page objects 95 | * `returns` **{Object}**: Returns the instance for chaining 96 | 97 | **Example** 98 | 99 | ```js 100 | pages.addPages([...]); 101 | ``` 102 | 103 | ## About 104 | 105 | ### Related projects 106 | 107 | * [assemble](https://www.npmjs.com/package/assemble): Get the rocks out of your socks! Assemble makes you fast at creating web projects… [more](https://github.com/assemble/assemble) | [homepage](https://github.com/assemble/assemble "Get the rocks out of your socks! Assemble makes you fast at creating web projects. Assemble is used by thousands of projects for rapid prototyping, creating themes, scaffolds, boilerplates, e-books, UI components, API documentation, blogs, building websit") 108 | * [templates](https://www.npmjs.com/package/templates): System for creating and managing template collections, and rendering templates with any node.js template engine… [more](https://github.com/jonschlinkert/templates) | [homepage](https://github.com/jonschlinkert/templates "System for creating and managing template collections, and rendering templates with any node.js template engine. Can be used as the basis for creating a static site generator or blog framework.") 109 | * [verb](https://www.npmjs.com/package/verb): Documentation generator for GitHub projects. Verb is extremely powerful, easy to use, and is used… [more](https://github.com/verbose/verb) | [homepage](https://github.com/verbose/verb "Documentation generator for GitHub projects. Verb is extremely powerful, easy to use, and is used on hundreds of projects of all sizes to generate everything from API docs to readmes.") 110 | 111 | ### Contributing 112 | 113 | Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). 114 | 115 | ### Building docs 116 | 117 | _(This document was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme) (a [verb](https://github.com/verbose/verb) generator), please don't edit the readme directly. Any changes to the readme must be made in [.verb.md](.verb.md).)_ 118 | 119 | To generate the readme and API documentation with [verb](https://github.com/verbose/verb): 120 | 121 | ```sh 122 | $ npm install -g verb verb-generate-readme && verb 123 | ``` 124 | 125 | ### Running tests 126 | 127 | Install dev dependencies: 128 | 129 | ```sh 130 | $ npm install -d && npm test 131 | ``` 132 | 133 | ### Author 134 | 135 | **Brian Woodward** 136 | 137 | * [github/doowb](https://github.com/doowb) 138 | * [twitter/doowb](http://twitter.com/doowb) 139 | 140 | ### License 141 | 142 | Copyright © 2016, [Brian Woodward](https://github.com/doowb). 143 | Released under the [MIT license](https://github.com/doowb/paginationator/blob/master/LICENSE). 144 | 145 | *** 146 | 147 | _This file was generated by [verb](https://github.com/verbose/verb), v0.9.0, on July 19, 2016._ -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * paginationator 3 | * 4 | * Copyright (c) 2015, Brian Woodward. 5 | * Licensed under the MIT License. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | var Pages = require('./lib/pages'); 11 | var Page = require('./lib/page'); 12 | 13 | /** 14 | * Paginate an array with given options and return a `Page` object 15 | * containing an array of `pages` with pagination information. 16 | * 17 | * ```js 18 | * var pages = paginationator([1, 2, 3, 4, 5], {limit: 2}); 19 | * //=> { pages: [ 20 | * //=> { idx: 0, total: 3, current: 1, items: [1, 2], first: 1, last: 3, next: 2 }, 21 | * //=> { idx: 1, total: 3, current: 2, items: [3, 4], first: 1, last: 3, prev: 1, next: 3 }, 22 | * //=> { idx: 2, total: 3, current: 3, items: [5], first: 1, last: 3, prev: 2 } 23 | * //=> ]} 24 | * ``` 25 | * 26 | * @param {Array} `arr` Array of items to paginate 27 | * @param {Object} `options` Additional options to control pagination 28 | * @param {Number} `options.limit` Number of items per page (defaults to 10) 29 | * @return {Object} paginated pages 30 | * @api public 31 | * @name paginationator 32 | */ 33 | 34 | module.exports = function paginationator(arr, options) { 35 | if (!Array.isArray(arr)) { 36 | throw new TypeError('expected arr to be an Array'); 37 | } 38 | options = options || {}; 39 | var limit = options.limit || 10; 40 | var total = Math.ceil(arr.length / limit); 41 | var i = 0; 42 | 43 | var pages = new Pages(); 44 | while (i < total) { 45 | var page = new Page(); 46 | var start = i * limit; 47 | var end = start + limit; 48 | page.items = arr.slice(start, end); 49 | pages.addPage(page); 50 | i++; 51 | } 52 | return pages; 53 | }; 54 | 55 | /** 56 | * Expose `Pages` 57 | */ 58 | 59 | module.exports.Pages = Pages; 60 | 61 | /** 62 | * Expose `Page` 63 | */ 64 | 65 | module.exports.Page = Page; 66 | -------------------------------------------------------------------------------- /lib/page.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Page constructor 5 | * 6 | * ```js 7 | * var page = new Page(); 8 | * ``` 9 | * 10 | * @param {Object} `page` optional page object to populate initial values. 11 | * @api public 12 | */ 13 | 14 | function Page(page) { 15 | if (!page) page = {}; 16 | for (var key in page) this[key] = page[key]; 17 | if (!this.hasOwnProperty('idx')) this.idx = 0; 18 | if (!this.hasOwnProperty('total')) this.total = 1; 19 | if (!this.hasOwnProperty('current')) { 20 | this.current = this.total; 21 | } 22 | } 23 | 24 | /** 25 | * Page getters 26 | */ 27 | 28 | Object.defineProperties(Page.prototype, { 29 | 30 | /** 31 | * Helper property to determine if this is the first page in a list. 32 | */ 33 | 34 | isFirst: { 35 | configurable: true, 36 | enumerable: true, 37 | get: function() { 38 | return this.idx === 0; 39 | } 40 | }, 41 | 42 | /** 43 | * Helper property to determine if this is the last page in a list. 44 | */ 45 | 46 | isLast: { 47 | configurable: true, 48 | enumerable: true, 49 | get: function() { 50 | return this.idx === (this.total - 1); 51 | } 52 | }, 53 | 54 | /** 55 | * Helper property to determine if this is there is a page before this one in a list. 56 | */ 57 | 58 | hasPrevious: { 59 | configurable: true, 60 | enumerable: true, 61 | get: function() { 62 | return !this.isFirst; 63 | } 64 | }, 65 | 66 | /** 67 | * Helper property to determine if this is there is a page before this one in a list. 68 | */ 69 | 70 | hasPrev: { 71 | configurable: true, 72 | enumerable: true, 73 | get: function() { 74 | return !this.isFirst; 75 | } 76 | }, 77 | 78 | /** 79 | * Helper property to determine if this is there is a page after this one in a list. 80 | */ 81 | 82 | hasNext: { 83 | configurable: true, 84 | enumerable: true, 85 | get: function() { 86 | return !this.isLast; 87 | } 88 | } 89 | }); 90 | 91 | /** 92 | * Expose `Page` 93 | */ 94 | 95 | module.exports = Page; 96 | -------------------------------------------------------------------------------- /lib/pages.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var Page = require('./page'); 4 | 5 | /** 6 | * Pages constructor 7 | * 8 | * ```js 9 | * var pages = new Pages(); 10 | * ``` 11 | * 12 | * @param {Array} `pages` Optional array of pages to initialize the `pages` array. 13 | * @api public 14 | */ 15 | 16 | function Pages(pages) { 17 | this.pages = []; 18 | if (typeof pages === 'undefined') return; 19 | if (!Array.isArray(pages)) { 20 | throw new TypeError('expected pages to be an Array'); 21 | } 22 | this.addPages(pages); 23 | } 24 | 25 | /** 26 | * Add a page to the list. 27 | * 28 | * ```js 29 | * pages.addPage({items: [1, 2, 3]}); 30 | * ``` 31 | * 32 | * @param {Object} `page` Plain object or instance of a `Page` 33 | * @return {Object} Returns the instance for chaining 34 | * @api public 35 | */ 36 | 37 | Pages.prototype.addPage = function(page) { 38 | if (!(page instanceof Page)) page = new Page(page); 39 | this.pages.push(decorate(this, page)); 40 | return this; 41 | }; 42 | 43 | /** 44 | * Add an array of pages to the list. 45 | * 46 | * ```js 47 | * pages.addPages([...]); 48 | * ``` 49 | * 50 | * @param {Object} `pages` Array of page objects 51 | * @return {Object} Returns the instance for chaining 52 | * @api public 53 | */ 54 | 55 | Pages.prototype.addPages = function(pages) { 56 | for (var i = 0; i < pages.length; i++) { 57 | this.addPage(pages[i]); 58 | } 59 | return this; 60 | }; 61 | 62 | /** 63 | * Decorates a page with additional properties. 64 | * 65 | * @param {Object} `page` Instance of page to decorate 66 | * @return {Object} Returns the decorated page to be added to the list 67 | */ 68 | 69 | function decorate(pages, page) { 70 | Object.defineProperties(page, { 71 | first: { 72 | enumerable: true, 73 | set: function() {}, 74 | get: function() { 75 | return pages.first && pages.first.current; 76 | } 77 | }, 78 | 79 | current: { 80 | enumerable: true, 81 | set: function() {}, 82 | get: function() { 83 | return this.idx + 1; 84 | } 85 | }, 86 | 87 | last: { 88 | enumerable: true, 89 | set: function() {}, 90 | get: function() { 91 | return pages.last && pages.last.current; 92 | } 93 | }, 94 | 95 | total: { 96 | enumerable: true, 97 | set: function() {}, 98 | get: function() { 99 | return pages.total; 100 | } 101 | } 102 | }); 103 | 104 | var prev = pages.last; 105 | var idx = pages.total; 106 | page.idx = idx; 107 | if (prev) { 108 | page.prev = prev.current; 109 | prev.next = page.current; 110 | } 111 | return page; 112 | } 113 | 114 | /** 115 | * Getters 116 | */ 117 | 118 | Object.defineProperties(Pages.prototype, { 119 | 120 | /** 121 | * Helper property to calculate the total pages in the array. 122 | */ 123 | 124 | total: { 125 | get: function() { 126 | return this.pages.length; 127 | } 128 | }, 129 | 130 | /** 131 | * Helper property to get the first page from the array. 132 | */ 133 | 134 | first: { 135 | get: function() { 136 | return this.total > 0 ? this.pages[0] : null; 137 | } 138 | }, 139 | 140 | /** 141 | * Helper property to get the last page from the array. 142 | */ 143 | 144 | last: { 145 | get: function() { 146 | return this.total > 0 ? this.pages[this.total - 1] : null; 147 | } 148 | } 149 | }); 150 | 151 | /** 152 | * Expose `Pages` 153 | */ 154 | 155 | module.exports = Pages; 156 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "paginationator", 3 | "description": "Paginate an array into pages of items.", 4 | "version": "0.1.4", 5 | "homepage": "https://github.com/doowb/paginationator", 6 | "author": "Brian Woodward (https://github.com/doowb)", 7 | "repository": "doowb/paginationator", 8 | "bugs": { 9 | "url": "https://github.com/doowb/paginationator/issues" 10 | }, 11 | "license": "MIT", 12 | "files": [ 13 | "index.js", 14 | "lib", 15 | "LICENSE", 16 | "README.md" 17 | ], 18 | "main": "index.js", 19 | "engines": { 20 | "node": ">=0.10.0" 21 | }, 22 | "scripts": { 23 | "test": "mocha" 24 | }, 25 | "devDependencies": { 26 | "gulp-format-md": "^0.1.9", 27 | "mocha": "^2.5.3" 28 | }, 29 | "keywords": [ 30 | "paginationator" 31 | ], 32 | "verb": { 33 | "toc": false, 34 | "layout": "default", 35 | "tasks": [ 36 | "readme" 37 | ], 38 | "plugins": [ 39 | "gulp-format-md" 40 | ], 41 | "related": { 42 | "list": [ 43 | "assemble", 44 | "templates", 45 | "verb" 46 | ] 47 | }, 48 | "lint": { 49 | "reflinks": true 50 | }, 51 | "reflinks": [ 52 | "verb", 53 | "verb-generate-readme" 54 | ] 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * paginationator 3 | * 4 | * Copyright (c) 2015 . 5 | * Licensed under the MIT license. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | require('mocha'); 11 | var assert = require('assert'); 12 | var paginationator = require('./'); 13 | var Pages = paginationator.Pages; 14 | var Page = paginationator.Page; 15 | 16 | describe('paginationator', function() { 17 | it('should paginate array using defaults', function() { 18 | var pages = paginationator([ 19 | {name: 'item-1-1'}, {name: 'item-1-2'}, {name: 'item-1-3'}, {name: 'item-1-4'}, {name: 'item-1-5'}, 20 | {name: 'item-1-6'}, {name: 'item-1-7'}, {name: 'item-1-8'}, {name: 'item-1-9'}, {name: 'item-1-10'}, 21 | {name: 'item-2-1'}, {name: 'item-2-2'}, {name: 'item-2-3'}, {name: 'item-2-4'}, {name: 'item-2-5'}, 22 | {name: 'item-2-6'}, {name: 'item-2-7'}, {name: 'item-2-8'}, {name: 'item-2-9'}, {name: 'item-2-10'}, 23 | {name: 'item-3-1'}, {name: 'item-3-2'}, {name: 'item-3-3'}, {name: 'item-3-4'}, {name: 'item-3-5'}, 24 | {name: 'item-3-6'}, {name: 'item-3-7'}, {name: 'item-3-8'}, {name: 'item-3-9'}, {name: 'item-3-10'}, 25 | {name: 'item-4-1'}, {name: 'item-4-2'}, {name: 'item-4-3'}, {name: 'item-4-4'}, {name: 'item-4-5'}, 26 | {name: 'item-4-6'}, {name: 'item-4-7'}, {name: 'item-4-8'}, {name: 'item-4-9'}, {name: 'item-4-10'}, 27 | ]); 28 | assert.deepEqual(pages, { 29 | pages: [ 30 | {current: 1, first: 1, idx: 0, last: 4, next: 2, total: 4, items: [ 31 | {name: 'item-1-1'}, {name: 'item-1-2'}, {name: 'item-1-3'}, {name: 'item-1-4'}, {name: 'item-1-5'}, 32 | {name: 'item-1-6'}, {name: 'item-1-7'}, {name: 'item-1-8'}, {name: 'item-1-9'}, {name: 'item-1-10'} 33 | ]}, 34 | {current: 2, first: 1, idx: 1, last: 4, next: 3, prev: 1, total: 4, items: [ 35 | {name: 'item-2-1'}, {name: 'item-2-2'}, {name: 'item-2-3'}, {name: 'item-2-4'}, {name: 'item-2-5'}, 36 | {name: 'item-2-6'}, {name: 'item-2-7'}, {name: 'item-2-8'}, {name: 'item-2-9'}, {name: 'item-2-10'} 37 | ]}, 38 | {current: 3, first: 1, idx: 2, last: 4, next: 4, prev: 2, total: 4, items: [ 39 | {name: 'item-3-1'}, {name: 'item-3-2'}, {name: 'item-3-3'}, {name: 'item-3-4'}, {name: 'item-3-5'}, 40 | {name: 'item-3-6'}, {name: 'item-3-7'}, {name: 'item-3-8'}, {name: 'item-3-9'}, {name: 'item-3-10'} 41 | ]}, 42 | {current: 4, first: 1, idx: 3, last: 4, prev: 3, total: 4, items: [ 43 | {name: 'item-4-1'}, {name: 'item-4-2'}, {name: 'item-4-3'}, {name: 'item-4-4'}, {name: 'item-4-5'}, 44 | {name: 'item-4-6'}, {name: 'item-4-7'}, {name: 'item-4-8'}, {name: 'item-4-9'}, {name: 'item-4-10'} 45 | ]} 46 | ] 47 | }); 48 | }); 49 | 50 | it('should paginate array using custom options', function() { 51 | var opts = {limit: 25}; 52 | var pages = paginationator([ 53 | {name: 'item-1-1'}, {name: 'item-1-2'}, {name: 'item-1-3'}, {name: 'item-1-4'}, {name: 'item-1-5'}, 54 | {name: 'item-1-6'}, {name: 'item-1-7'}, {name: 'item-1-8'}, {name: 'item-1-9'}, {name: 'item-1-10'}, 55 | {name: 'item-2-1'}, {name: 'item-2-2'}, {name: 'item-2-3'}, {name: 'item-2-4'}, {name: 'item-2-5'}, 56 | {name: 'item-2-6'}, {name: 'item-2-7'}, {name: 'item-2-8'}, {name: 'item-2-9'}, {name: 'item-2-10'}, 57 | {name: 'item-3-1'}, {name: 'item-3-2'}, {name: 'item-3-3'}, {name: 'item-3-4'}, {name: 'item-3-5'}, 58 | {name: 'item-3-6'}, {name: 'item-3-7'}, {name: 'item-3-8'}, {name: 'item-3-9'}, {name: 'item-3-10'}, 59 | {name: 'item-4-1'}, {name: 'item-4-2'}, {name: 'item-4-3'}, {name: 'item-4-4'}, {name: 'item-4-5'}, 60 | {name: 'item-4-6'}, {name: 'item-4-7'}, {name: 'item-4-8'}, {name: 'item-4-9'}, {name: 'item-4-10'}, 61 | ], opts); 62 | 63 | assert.deepEqual(pages, { 64 | pages: [ 65 | {current: 1, first: 1, idx: 0, last: 2, next: 2, total: 2, items: [ 66 | {name: 'item-1-1'}, {name: 'item-1-2'}, {name: 'item-1-3'}, {name: 'item-1-4'}, {name: 'item-1-5'}, 67 | {name: 'item-1-6'}, {name: 'item-1-7'}, {name: 'item-1-8'}, {name: 'item-1-9'}, {name: 'item-1-10'}, 68 | {name: 'item-2-1'}, {name: 'item-2-2'}, {name: 'item-2-3'}, {name: 'item-2-4'}, {name: 'item-2-5'}, 69 | {name: 'item-2-6'}, {name: 'item-2-7'}, {name: 'item-2-8'}, {name: 'item-2-9'}, {name: 'item-2-10'}, 70 | {name: 'item-3-1'}, {name: 'item-3-2'}, {name: 'item-3-3'}, {name: 'item-3-4'}, {name: 'item-3-5'} 71 | ]}, 72 | {current: 2, first: 1, idx: 1, last: 2, prev: 1, total: 2, items: [ 73 | {name: 'item-3-6'}, {name: 'item-3-7'}, {name: 'item-3-8'}, {name: 'item-3-9'}, {name: 'item-3-10'}, 74 | {name: 'item-4-1'}, {name: 'item-4-2'}, {name: 'item-4-3'}, {name: 'item-4-4'}, {name: 'item-4-5'}, 75 | {name: 'item-4-6'}, {name: 'item-4-7'}, {name: 'item-4-8'}, {name: 'item-4-9'}, {name: 'item-4-10'} 76 | ]} 77 | ] 78 | }); 79 | }); 80 | 81 | describe('Page', function() { 82 | it('should create a new instance of Page with defaults', function() { 83 | var page = new Page(); 84 | assert.deepEqual(page, {idx: 0, total: 1, current: 1}); 85 | }); 86 | 87 | it('should create a new instance of Page with provided page', function() { 88 | var page = new Page({idx: 5, total: 10, current: 6}); 89 | assert.deepEqual(page, {idx: 5, total: 10, current: 6}); 90 | }); 91 | 92 | it('should calculate correct positional values when first', function() { 93 | var page = new Page({idx: 0, total: 10, current: 1}); 94 | assert.equal(page.isFirst, true); 95 | assert.equal(page.hasPrevious, false); 96 | assert.equal(page.hasNext, true); 97 | assert.equal(page.isLast, false); 98 | }); 99 | 100 | it('should calculate correct positional values when last', function() { 101 | var page = new Page({idx: 9, total: 10, current: 10}); 102 | assert.equal(page.isFirst, false); 103 | assert.equal(page.hasPrevious, true); 104 | assert.equal(page.hasNext, false); 105 | assert.equal(page.isLast, true); 106 | }); 107 | 108 | it('should calculate correct positional values when in the middle', function() { 109 | var page = new Page({idx: 5, total: 10, current: 6}); 110 | assert.equal(page.isFirst, false); 111 | assert.equal(page.hasPrevious, true); 112 | assert.equal(page.hasNext, true); 113 | assert.equal(page.isLast, false); 114 | }); 115 | }); 116 | 117 | describe('Pages', function() { 118 | it('should create a new instance of Pages', function() { 119 | var pages = new Pages(); 120 | assert.deepEqual(pages, {pages: []}); 121 | }); 122 | 123 | it('should create a new instance of Pages with provided pages', function() { 124 | var pages = new Pages([ 125 | {name: 'page-1'}, 126 | {name: 'page-2'}, 127 | {name: 'page-3'}, 128 | {name: 'page-4'} 129 | ]); 130 | assert.deepEqual(pages, { 131 | pages: [ 132 | {current: 1, first: 1, idx: 0, last: 4, next: 2, total: 4, name: 'page-1'}, 133 | {current: 2, first: 1, idx: 1, last: 4, next: 3, prev: 1, total: 4, name: 'page-2'}, 134 | {current: 3, first: 1, idx: 2, last: 4, next: 4, prev: 2, total: 4, name: 'page-3'}, 135 | {current: 4, first: 1, idx: 3, last: 4, prev: 3, total: 4, name: 'page-4'} 136 | ] 137 | }); 138 | }); 139 | 140 | it('should update page information when new pages are added', function() { 141 | var pages = new Pages([ 142 | {name: 'page-1'}, 143 | {name: 'page-2'}, 144 | {name: 'page-3'}, 145 | {name: 'page-4'} 146 | ]); 147 | pages.addPage({name: 'page-5'}); 148 | 149 | assert.deepEqual(pages, { 150 | pages: [ 151 | {current: 1, first: 1, idx: 0, last: 5, next: 2, total: 5, name: 'page-1'}, 152 | {current: 2, first: 1, idx: 1, last: 5, next: 3, prev: 1, total: 5, name: 'page-2'}, 153 | {current: 3, first: 1, idx: 2, last: 5, next: 4, prev: 2, total: 5, name: 'page-3'}, 154 | {current: 4, first: 1, idx: 3, last: 5, next: 5, prev: 3, total: 5, name: 'page-4'}, 155 | {current: 5, first: 1, idx: 4, last: 5, prev: 4, total: 5, name: 'page-5'} 156 | ] 157 | }); 158 | }); 159 | }); 160 | }); 161 | --------------------------------------------------------------------------------