Skip to content

Commit c196273

Browse files
[TEX-14900] Fork kurounin:pagination
1 parent 72611e7 commit c196273

10 files changed

+831
-0
lines changed

.idea/.gitignore

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/inspectionProfiles/Project_Default.xml

+40
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/modules.xml

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/pagination.iml

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/vcs.xml

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

+263
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
carlosalvidrez:pagination
2+
=================
3+
4+
Meteor v3+ pagination done right
5+
6+
Forked from: Kurounin:Pagination
7+
8+
This package allows you to paginate the subscriptions over meteor's collections. It can be used in a Blaze template or in ReactJS.
9+
10+
11+
Features
12+
--------
13+
14+
+ **Incremental subscriptions**. Downloads only what is needed, not the entire collection at once. Suitable for large datasets.
15+
+ **Instant changes propagation**. Any document changes are instantly propagated, thanks to light-weight modifications of subscription mechanism.
16+
+ **Easy integration**. The package works out of the box. Page changes are triggered by a single reactive dictionary variable.
17+
+ **Multiple collections per page**. Each Pagination instance runs independently. You can even create multiple paginations for one collection on a single page.
18+
+ **Bootstrap 3 and 4 compatible navigation template**. Blaze template for a bootstrap 3 and 4 styled paginator.
19+
+ **Bootstrap 3 and 4 compatible navigation react class**. ReactJS class for a bootstrap 3 and 4 styled paginator.
20+
21+
# Installation
22+
```meteor add kurounin:pagination```
23+
24+
**For Blaze paginator install [kurounin:pagination-blaze](https://atmospherejs.com/kurounin/pagination-blaze) package**
25+
```meteor add kurounin:pagination```
26+
27+
**For ReactJS paginator in Meteor 1.2 install [kurounin:pagination-reactjs](https://atmospherejs.com/kurounin/pagination-reactjs) package**
28+
```meteor add kurounin:pagination-reactjs```
29+
30+
**For ReactJS paginator in Meteor 1.3+ install [react-bootstrap-pagination](https://www.npmjs.com/package/react-bootstrap-pagination) npm package**
31+
```npm i react-bootstrap-pagination```
32+
33+
# Usage
34+
35+
In your collections file (e.g. lib/collections.js):
36+
```js
37+
MyCollection = new Meteor.Collection('myCollectionName');
38+
```
39+
40+
In your publications file (e.g. server/publications.js):
41+
```js
42+
import { publishPagination } from 'meteor/kurounin:pagination';
43+
publishPagination(MyCollection);
44+
```
45+
46+
Optionally you can provide a set of filters on the server-side or even dynamic filters, which can not be overridden.
47+
There's also the option of providing a transformation filter function to validate the client filters (e.g. server/publications.js):
48+
```js
49+
publishPagination(MyCollection, {
50+
filters: {is_published: true},
51+
dynamic_filters: function () {
52+
return {user_id: this.userId};
53+
},
54+
transform_filters: function (filters, options) {
55+
// called after filters & dynamic_filters
56+
allowedKeys = ['_id', 'title'];
57+
58+
const modifiedFilters = [];
59+
60+
// filters is an array of the provided filters (client side filters & server side filters)
61+
for (let i = 0; i < filters.length; i++) {
62+
modifiedFilters[i] = _.extend(
63+
_.pick(filters[i], allowedKeys),
64+
{user_id: this.userId}
65+
);
66+
}
67+
68+
return modifiedFilters;
69+
},
70+
transform_options: function (filters, options) {
71+
const fields = { name: 1, email: 1 }
72+
if (Roles.userIsInRole(this.userId, 'admin')) {
73+
fields.deleted = 1;
74+
}
75+
options.fields = _.extend(fields, options.fields);
76+
return options;
77+
}
78+
});
79+
80+
```
81+
82+
For Blaze template
83+
--------------------------------------------------
84+
In your template file (e.g. client/views/mylist.html):
85+
```html
86+
<template name="myList">
87+
<div>
88+
{{#if isReady}}
89+
<ul>
90+
{{#each documents}}
91+
<li>Document #{{_id}}</li>
92+
{{/each}}
93+
</ul>
94+
{{> defaultBootstrapPaginator pagination=templatePagination limit=10 containerClass="text-center" onClick=clickEvent}}
95+
{{else}}
96+
Loading...
97+
{{/if}}
98+
</div>
99+
</template>
100+
```
101+
**[kurounin:pagination-blaze](https://atmospherejs.com/kurounin/pagination-blaze) package is needed for paginator**
102+
103+
104+
In your template javascript file (e.g. client/scripts/mylist.js):
105+
```js
106+
Template.myList.onCreated(function () {
107+
this.pagination = new Meteor.Pagination(MyCollection, {
108+
sort: {
109+
_id: -1
110+
}
111+
});
112+
});
113+
114+
Template.myList.helpers({
115+
isReady: function () {
116+
return Template.instance().pagination.ready();
117+
},
118+
templatePagination: function () {
119+
return Template.instance().pagination;
120+
},
121+
documents: function () {
122+
return Template.instance().pagination.getPage();
123+
},
124+
// optional helper used to return a callback that should be executed before changing the page
125+
clickEvent: function() {
126+
return function(e, templateInstance, clickedPage) {
127+
e.preventDefault();
128+
console.log('Changing page from ', templateInstance.data.pagination.currentPage(), ' to ', clickedPage);
129+
};
130+
}
131+
});
132+
```
133+
134+
For ReactJS template
135+
--------------------------------------------------
136+
In your view file (e.g. client/views/mylist.jsx):
137+
```html
138+
MyListPage = React.createClass({
139+
mixins: [ReactMeteorData],
140+
141+
pagination: new Meteor.Pagination(MyCollection),
142+
143+
getMeteorData: function() {
144+
return {
145+
documents: this.pagination.getPage(),
146+
ready: this.pagination.ready()
147+
};
148+
},
149+
150+
renderDocument: function(document) {
151+
return (
152+
<li>Document #{document._id} </li>
153+
);
154+
},
155+
156+
render: function() {
157+
if (!this.pagination.ready()) {
158+
return (
159+
<div>Loading...</div>
160+
);
161+
}
162+
163+
return (
164+
<div>
165+
<ul>
166+
{this.data.documents.map(this.renderDocument)}
167+
</ul>
168+
<DefaultBootstrapPaginator
169+
pagination={this.pagination}
170+
limit={10}
171+
containerClass="text-center"
172+
/>
173+
</div>
174+
);
175+
}
176+
});
177+
```
178+
**For Meteor 1.2 [kurounin:pagination-reactjs](https://atmospherejs.com/kurounin/pagination-reactjs) package is needed for paginator**
179+
180+
**For Meteor 1.3+ [react-bootstrap-pagination](https://www.npmjs.com/package/react-bootstrap-pagination) npm package is needed for paginator**
181+
182+
183+
# Demo project
184+
For an example on how this package can be implemented check [the pagination example project](https://github.com/Kurounin/PaginationExample) or [the react pagination example project](https://github.com/Kurounin/PaginationReactExample).
185+
186+
You can also checkout [this example application in React](https://github.com/mgscreativa/kurounin-pagination-react-example) created by [mgscreativa](https://github.com/mgscreativa).
187+
188+
189+
# Server Pagination settings available on init
190+
191+
* `name`: set the publication name (defaults to **collection name**; *needs to be unique, to not collide with other publications*)
192+
* `filters`: provide a set of filters on the server-side, which can not be overridden (defaults to **{}**, meaning no filters)
193+
* `dynamic_filters`: provide a function which returns additional filters to be applied (**this** is the publication; receives no other parameters)
194+
* `transform_filters`: provide a function which returns the modified filters object to be applied (**this** is the publication; receives the current **filters** as an array containing the client & server defined filters and **options** as parameters)
195+
* `transform_options`: provide a function which returns the modified options object to be applied (**this** is the publication; receives the current **filters** as an array containing the client & server defined filters and **options** as parameters)
196+
* `countInterval`: set the interval in ms at which the subscription count is updated (defaults to **10000**, meaning every 10s)
197+
198+
199+
# Client Pagination settings available on init
200+
201+
* `name`: set the subscription name (defaults to **collection name**; *needs to be identical with the server side publication name*)
202+
* `page`: set the initial page, for example the page parameter from url (defaults to **1**)
203+
* `perPage`: set the number of documents to be fetched per page (defaults to **10**)
204+
* `skip`: set the number of documents that should be skipped when fetching a page (defaults to **0**)
205+
* `filters`: filters to be applied to the subscription (defaults to **{}**, meaning no filters)
206+
* `fields`: fields to be returned (defaults to **{}**, meaning all fields)
207+
* `sort`: set the sorting for retrieved documents (defaults to **{_id: -1}**)
208+
* `reactive`: set the subscription reactivity, allowing to only retrieve the initial results when set to false (defaults to **true**)
209+
* `debug`: console logs the query and options used when performing the find (defaults to **false**)
210+
* `connection`: the server connection that will manage this collection. Pass the return value of calling DDP.connect to specify a different server. (defaults to **Meteor.connection**)
211+
212+
213+
# Client Pagination available methods
214+
215+
* `currentPage([int])`: get/set the current page
216+
* `perPage([int])`: get/set the number of documents per page
217+
* `skip([int])`: get/set the number of documents to skip
218+
* `filters([Object])`: get/set the current filters
219+
* `fields([Object])`: get/set the retrieved fields
220+
* `sort([Object])`: get/set the sorting order
221+
* `debug([boolean])`: get/set the debug
222+
* `totalItems()`: get the total number of documents
223+
* `totalPages()`: get the total number of pages
224+
* `ready()`: checks if the subscription for the current page is ready
225+
* `refresh()`: forcefully refreshes the subscription (useful for non-reactive subscriptions)
226+
* `getPage()`: returns the documents for the current page
227+
228+
229+
# Blaze Paginator template
230+
231+
A Blaze template is provided to allow navigation through available pages:
232+
233+
In the template html file add the paginator
234+
```html
235+
{{> defaultBootstrapPaginator pagination=templatePagination onClick=clickEvent limit=10 containerClass="text-center"}}
236+
```
237+
Available template parameters are:
238+
* `pagination`: pagination instance
239+
* `limit`: the maximum number of page links to display
240+
* `containerClass`: optional container class for the paginator
241+
* `paginationClass`: optional class for the *ul* element (defaults to `pagination`)
242+
* `itemClass`: optional class for the page links elements
243+
* `wrapLinks`: if set to true page links will be wrapped in *li* elements (defaults to `true`)
244+
* `onClick`: optional callback to be called when page link is clicked (default callback runs `e.preventDefault()`)
245+
246+
247+
# ReactJS Paginator class
248+
249+
A ReactJS class is provided to allow navigation through available pages:
250+
251+
```js
252+
<DefaultBootstrapPaginator pagination={this.pagination} limit={10} containerClass="text-center" />
253+
```
254+
Available class properties are:
255+
* `pagination`: pagination instance
256+
* `limit`: maximum number of page links to display (defaults to **10**)
257+
* `containerClass`: optional container class for the paginator
258+
259+
260+
### Packages used as inspiration:
261+
262+
* [alethes:pages](https://atmospherejs.com/alethes/pages) for pagination instantiation
263+
* [aida:pagination](https://atmospherejs.com/aida/pagination) for bootstrap paginator template

0 commit comments

Comments
 (0)