Git Product home page Git Product logo

pagination's Introduction

Kurounin:Pagination

This package allows you to paginate the subscriptions over meteor's collections. It can be used in a Blaze template or in ReactJS.

Features

  • Incremental subscriptions. Downloads only what is needed, not the entire collection at once. Suitable for large datasets.
  • Instant changes propagation. Any document changes are instantly propagated, thanks to light-weight modifications of subscription mechanism.
  • Easy integration. The package works out of the box. Page changes are triggered by a single reactive dictionary variable.
  • Multiple collections per page. Each Pagination instance runs independently. You can even create multiple paginations for one collection on a single page.
  • Bootstrap 3 and 4 compatible navigation template. Blaze template for a bootstrap 3 and 4 styled paginator.
  • Bootstrap 3 and 4 compatible navigation react class. ReactJS class for a bootstrap 3 and 4 styled paginator.

Installation

meteor add kurounin:pagination

For Blaze paginator install kurounin:pagination-blaze package meteor add kurounin:pagination

For ReactJS paginator in Meteor 1.2 install kurounin:pagination-reactjs package meteor add kurounin:pagination-reactjs

For ReactJS paginator in Meteor 1.3+ install react-bootstrap-pagination npm package npm i react-bootstrap-pagination

Usage

In your collections file (e.g. lib/collections.js):

MyCollection = new Meteor.Collection('myCollectionName');

In your publications file (e.g. server/publications.js):

import { publishPagination } from 'meteor/kurounin:pagination';

publishPagination(MyCollection);

Optionally you can provide a set of filters on the server-side or even dynamic filters, which can not be overridden. There's also the option of providing a transformation filter function to validate the client filters (e.g. server/publications.js):

publishPagination(MyCollection, {
    filters: {is_published: true},
    dynamic_filters: function () {
        return {user_id: this.userId};
    },
    transform_filters: function (filters, options) {
        // called after filters & dynamic_filters
        allowedKeys = ['_id', 'title'];

        const modifiedFilters = [];

        // filters is an array of the provided filters (client side filters & server side filters)
        for (let i = 0; i < filters.length; i++) {
            modifiedFilters[i] =  _.extend(
                _.pick(filters[i], allowedKeys),
                {user_id: this.userId}
            );
        }

        return modifiedFilters;
    },
    transform_options: function (filters, options) {
        const fields = { name: 1, email: 1 }
        if (Roles.userIsInRole(this.userId, 'admin')) {
            fields.deleted = 1;
        }
        options.fields = _.extend(fields, options.fields);
        return options;
    }
});

For Blaze template

In your template file (e.g. client/views/mylist.html):

<template name="myList">
    <div>
        {{#if isReady}}
            <ul>
              {{#each documents}}
                  <li>Document #{{_id}}</li>
              {{/each}}
            </ul>
            {{> defaultBootstrapPaginator pagination=templatePagination limit=10 containerClass="text-center" onClick=clickEvent}}
        {{else}}
            Loading...
        {{/if}}
    </div>
</template>

kurounin:pagination-blaze package is needed for paginator

In your template javascript file (e.g. client/scripts/mylist.js):

Template.myList.onCreated(function () {
    this.pagination = new Meteor.Pagination(MyCollection, {
        sort: {
            _id: -1
        }
    });
});

Template.myList.helpers({
    isReady: function () {
        return Template.instance().pagination.ready();
    },
    templatePagination: function () {
        return Template.instance().pagination;
    },
    documents: function () {
        return Template.instance().pagination.getPage();
    },
    // optional helper used to return a callback that should be executed before changing the page
    clickEvent: function() {
        return function(e, templateInstance, clickedPage) {
            e.preventDefault();
            console.log('Changing page from ', templateInstance.data.pagination.currentPage(), ' to ', clickedPage);
        };
    }
});

For ReactJS template

In your view file (e.g. client/views/mylist.jsx):

MyListPage = React.createClass({
    mixins: [ReactMeteorData],

    pagination: new Meteor.Pagination(MyCollection),

    getMeteorData: function() {
        return {
            documents: this.pagination.getPage(),
            ready: this.pagination.ready()
        };
    },

    renderDocument: function(document) {
        return (
            <li>Document #{document._id}    </li>
        );
    },

    render: function() {
        if (!this.pagination.ready()) {
            return (
                <div>Loading...</div>
            );
        }

        return (
            <div>
                <ul>
                    {this.data.documents.map(this.renderDocument)}
                </ul>
                <DefaultBootstrapPaginator
                    pagination={this.pagination}
                    limit={10}
                    containerClass="text-center"
                    />
            </div>
        );
    }
});

For Meteor 1.2 kurounin:pagination-reactjs package is needed for paginator

For Meteor 1.3+ react-bootstrap-pagination npm package is needed for paginator

Demo project

For an example on how this package can be implemented check the pagination example project or the react pagination example project.

You can also checkout this example application in React created by mgscreativa.

Server Pagination settings available on init

  • name: set the publication name (defaults to collection name; needs to be unique, to not collide with other publications)
  • filters: provide a set of filters on the server-side, which can not be overridden (defaults to {}, meaning no filters)
  • dynamic_filters: provide a function which returns additional filters to be applied (this is the publication; receives no other parameters)
  • 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)
  • 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)
  • countInterval: set the interval in ms at which the subscription count is updated (defaults to 10000, meaning every 10s)

Client Pagination settings available on init

  • name: set the subscription name (defaults to collection name; needs to be identical with the server side publication name)
  • page: set the initial page, for example the page parameter from url (defaults to 1)
  • perPage: set the number of documents to be fetched per page (defaults to 10)
  • skip: set the number of documents that should be skipped when fetching a page (defaults to 0)
  • filters: filters to be applied to the subscription (defaults to {}, meaning no filters)
  • fields: fields to be returned (defaults to {}, meaning all fields)
  • sort: set the sorting for retrieved documents (defaults to {_id: -1})
  • reactive: set the subscription reactivity, allowing to only retrieve the initial results when set to false (defaults to true)
  • debug: console logs the query and options used when performing the find (defaults to false)
  • 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)

Client Pagination available methods

  • currentPage([int]): get/set the current page
  • perPage([int]): get/set the number of documents per page
  • skip([int]): get/set the number of documents to skip
  • filters([Object]): get/set the current filters
  • fields([Object]): get/set the retrieved fields
  • sort([Object]): get/set the sorting order
  • debug([boolean]): get/set the debug
  • totalItems(): get the total number of documents
  • totalPages(): get the total number of pages
  • ready(): checks if the subscription for the current page is ready
  • refresh(): forcefully refreshes the subscription (useful for non-reactive subscriptions)
  • getPage(): returns the documents for the current page

Blaze Paginator template

A Blaze template is provided to allow navigation through available pages:

In the template html file add the paginator

{{> defaultBootstrapPaginator pagination=templatePagination onClick=clickEvent limit=10 containerClass="text-center"}}

Available template parameters are:

  • pagination: pagination instance
  • limit: the maximum number of page links to display
  • containerClass: optional container class for the paginator
  • paginationClass: optional class for the ul element (defaults to pagination)
  • itemClass: optional class for the page links elements
  • wrapLinks: if set to true page links will be wrapped in li elements (defaults to true)
  • onClick: optional callback to be called when page link is clicked (default callback runs e.preventDefault())

ReactJS Paginator class

A ReactJS class is provided to allow navigation through available pages:

<DefaultBootstrapPaginator pagination={this.pagination} limit={10} containerClass="text-center" />

Available class properties are:

  • pagination: pagination instance
  • limit: maximum number of page links to display (defaults to 10)
  • containerClass: optional container class for the paginator

Packages used as inspiration:

pagination's People

Contributors

ankitv89 avatar dchan3 avatar jahosh avatar kurounin avatar manzapanza avatar marla-singer avatar zeroasterisk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

pagination's Issues

Meteor.users + Search

How would I go about implementing a search feature combined with your package for Meteor.users()? I am already using the filters field to narrow the list of users to paginate based on other aspects of the app like so:
filters: { '_id': { '$in': org.membership.current } }

This works perfectly.

Now if I wanted to search the users, do I need to modify the `filters:' field to pass the search text? If so how would that query look.

Also on the server side, do I need to setup indexes to handle the fields that should be searched of will the pagination package handle that as well?

Thanks.

pagination.ready() never true - Still an issue

Similar issue to #11 except the solution is NOT working. Using a modified version of demo project.

My helpers:

Template.hello.helpers({
    isReady: function () {
        console.log("isReady: " +  Template.instance().pagination.ready() );
        return Template.instance().pagination.ready();
    },
    templatePagination: function () {
        return Template.instance().pagination;
    },
    documents: function () {
        return Template.instance().pagination.getPage();
    },
	clickEvent: function() {
		return function(e, templateInstance, clickedPage) {
			e.preventDefault();
			console.log('Changing page from ', templateInstance.data.pagination.currentPage(), ' to ', clickedPage);
		};
	},

});

onCreated:

`this.pagination = new Meteor.Pagination(MyCollection, {
filters: {

    },
    sort: {

    },
    perPage: 20
});

this.pagination.ready(true);`

HTML:

`{{#if isReady}}

        <ul>
            {{#each documents}}
                <li>{{title}} - Brand: {{brand}} - Code: {{code}} - Number: {{number}} - isTrue: {{isTrue}}</li>
            {{/each}}
        </ul>

        {{> defaultBootstrapPaginator pagination=templatePagination limit=5 containerClass="text-left" onClick=clickEvent}}

    {{else}}
        Loading...
    {{/if}}`

Regarding the solution to #11, you can see I added the item in to the onCreated.

But the console.log outputs:

http://screencast.com/t/1F8nru9T3o

If I remove the if isReady block, everything works perfectly.

So it seems that isReady is never actually setting itself to true, even though all the data is actually ready.

According to console.log (included in screenshot) you can see it briefly set as true from the onCreated, but it gets set back to false, and never true again...

After updating a record, data not updated reactively

Hi,
I found out really strange error. (I use blaze)
I've a pagination and a update form inside 1 page. After updating a record through that form (autoform), the data list inside pagination did not updated, it just still the old one. I had to refresh the page to see the changes.

I think there's something wrong between pagination publication and updating operation.

Meteor.users ?

Does this package work with the Meteor.users collection? I tried the following :

new Meteor.Pagination(Meteor.users);

and get the following error:

TypeError: Cannot read property '_name' of undefined
at Pagination.publish (packages/kurounin_pagination/server/pagination.js:11:1)

Also tried
new Meteor.Pagination(Schemas.users); (because I am using simple schema but get the same error).

Thanks.

Can't stop subscription when changing route

So, If the paginator is created inside a "Template.created: -> " instance, then when I change the route, the paginator is still publishing the data.

Is there a way to stop the publication in other routes? I expected to be destroyed.

Thanks

Doesn't work properly with React Komposer?

I'm using Meteor 1.3.4.1, kurounin:pagination 1.0.9, and react-komposer 1.8.0 (npm package).

function composer(props, onData) {
  console.log('loading pages');
  const pagination = new Meteor.Pagination(UfcFighters);

  if( pagination.ready() ) {
    console.log('ready');
    const fighters = {
      columns: [
        { width: '5%', label: '', className: '' },
        { width: '20%', label: 'Name', className: 'text-center' },
        { width: '20%', label: 'Wins/Losses/Draws', className: 'text-center' },
        { width: '20%', label: 'Weight Class', className: 'text-center' },
        { width: '10%', label: 'Status', className: 'text-center' },
        { width: '10%', label: 'Rank', className: 'text-center' },
      ],
      data: pagination.getPage(),
    };
    onData(null, { fighters, pagination });
  }
};

Is this the proper use for React Komposer? I noticed that the Pagination would constantly load the subscriptions and never be ready to present the data. The console output would say 'loading pages' repeatedly, but it never says 'ready'.

Any advice would be appreciated.

How to use this pagination reactively?

this.pagination = new Meteor.Pagination(Customers, { sort: { name: 1 } });
Original code is like above. But I think this subscription is not reactive. I want to change this sorting like following.

this.pagination = new Meteor.Pagination(Customers, { sort: { name: Session.get("sortNumber") } });

But it not works with Session. Please help me to solve this. Thanks

Unable to stop subscription on route change

When starting a pagination at the template level inside Template.created, after the template is destroyed i.e route is changed (using flow router), the pagination data persists. Is there a method for stopping the pagination subscription? p.s thank you for the great work!

Using i18n-db

Hi,

First of all let me tell you this is a fantastic package, I have used it in all of my projects.

I am now trying to implement translation using the tap:i18n-db package for translating the same collection that I am using with your pagination. For this I would need to change the publication and the subscriptions in the following way.
if (Meteor.isServer) {
TAPi18n.publish("inventors", function (born_after) {
return Inventors.i18nFind({born: {$gt: born_after}});
});
}

if (Meteor.isClient) {
TAPi18n.subscribe("inventors", 1800);
}
Do you have any ideas on how to do this?

Thank you for your help in advance.

Refreshing with F5 issue

Hi! If I refresh the page with F5, I don't get any results.

Accessing through defined route, gets the desired page results, but if I press F5 in that route, I don't get any results. I'm currently using Meteor 1.5.1, React 15.5.4 and createContainer HOC.

It seems that on my createContainer props.pagination.ready() never gets true...

Client log by following a route

Pagination users.paginatedList unsubscribe
Pagination devices.paginatedList non-reactive subscribe {} {"fields":{},"sort":{"updatedAt":1},"skip":0,"limit":10,"reactive":false}
Pagination devices.paginatedList find {"sub_c8Jn5fmdRhZ3cCFPu":1} {"fields":{},"sort":{"updatedAt":1}}

Server log by following a route

Pagination devices.paginatedList non-reactive publish {} {"fields":{},"sort":{"updatedAt":1},"skip":0,"limit":10,"reactive":false,"debug":true}

Client log after pressing F5

Pagination devices.paginatedList non-reactive subscribe {} {"fields":{},"sort":{"updatedAt":1},"skip":0,"limit":10,"reactive":false}
Pagination devices.paginatedList unsubscribe

Server log after pressing F5

Pagination devices.paginatedList non-reactive publish {} {"fields":{},"sort":{"updatedAt":1},"skip":0,"limit":10,"reactive":false,"debug":true}

Infinite Scroll?

I'm wondering what it would take to build infinite scroll instead of doing pages.

Great package BTW. Been looking for something to replace pages that works with react.

How make aggregation with pagination?

Hi, i'm enjoying using this package in my project, but i'm faced with a problem:

I have a Collection named Tickets:
tickets:{ _id, customer_id, content }

And a Collection named Customers:
customers:{ _id, name, email }

I made a search and found AGGREGATION solution, but is apparently incompatible with this package.
How can i do the relation?

Thank you for your attention.

ES6 with createContainer()

I'm having an issue with the library and using the ES6 syntax. The problem is that createContainer() doesn't have a reference to the instance of the component that is doing the pagination. As a result, I have to move the pagination object to an external scope. This makes it so that I can't reuse the component multiple times on the same page though because all components would have the same reference to the pagination object.

Hopefully, this gives you a better idea of what my code currently looks like. I have comments in the parts I want to change.

Thanks!

let Pagination = new Meteor.Pagination(Appointments);

class FindAppointmentsPaginated extends React.Component {
  constructor(props) {
    //This is where I want to insantiace the meteor pagination object
  }
  renderAppointment(appointment) {
    return (
      <div className="row" key={appointment._id}>
        <div className="col-md-12">
          <p>
            {appointment.services.toString()}
          </p>
      </div>
     </div>
    );
  }
  render () {
    return(
      <div>
        {this.props.appointments.map(this.renderAppointment)}
        <BootstrapPaginator
                  pagination={Pagination}
                  limit={10}
                  containerClass="text-center"
                  />
      </div>
    );
  }
}

export default createContainer(() => {
  //I want to access the component instance's pagination object here, instead of the external one I made

  return {
    ready: Pagination.ready(),
    appointments: Pagination.getPage()
  };
}, FindAppointmentsPaginated);

publishPagination overrides other publications

Hi!
I have publication problem.
Here is my code:

Meteor.publish("Sites.showByIdEdit", function(_id) {
  check(_id, String);
  if (!this.userId) return this.ready();
  return Sites.find({_id}, {fields: { 'feild': 1, 'feild': 1}});
});

publishPagination(Sites);

So the site has all fields available always.
What can I do to restrict fields?

How to increase data per page

How can I increase the amount of data per page?
i have tried increasing the limit in
{{> defaultBootstrapPaginator pagination=templatePagination limit=15 containerClass="text-center"}}
but it still remains 10 (which is the default). How can i increase this to 20? Thanks

Can't set timers inside simulations

When I do Collection.remove(id) in meteor method and Collection is used in Pagination then document is deleted ok but i have this exception in console:

Exception in queued task: Error: Can't set timers inside simulations at withoutInvocation (http://localhost:3000/packages/meteor.js?9730f4ff059088b3f7f14c0672d155218a1802d4:427:13) at bindAndCatch (http://localhost:3000/packages/meteor.js?9730f4ff059088b3f7f14c0672d155218a1802d4:435:33) at Object._.extend.setTimeout (http://localhost:3000/packages/meteor.js?9730f4ff059088b3f7f14c0672d155218a1802d4:451:23) at Object.cachedSub.delayedStop (http://localhost:3000/packages/ccorcos_subs-cache.js?e7ce9a57920f4ba6ca11739375ab4895358435aa:211:44) at http://localhost:3000/packages/ccorcos_subs-cache.js?e7ce9a57920f4ba6ca11739375ab4895358435aa:202:30 at http://localhost:3000/packages/tracker.js?7776276660c988c38fed448d8262b925dffb5bc3:310:31 at Object.Tracker.nonreactive (http://localhost:3000/packages/tracker.js?7776276660c988c38fed448d8262b925dffb5bc3:615:12) at Tracker.Computation.invalidate (http://localhost:3000/packages/tracker.js?7776276660c988c38fed448d8262b925dffb5bc3:309:15) at Tracker.Dependency.changed (http://localhost:3000/packages/tracker.js?7776276660c988c38fed448d8262b925dffb5bc3:443:30) at http://localhost:3000/packages/minimongo.js?cdf1a26cf7719fa9471a8017c3defd5aea812727:407:13

This may be related to #4 in ccorcos:subs-cache nad this #10 in ccorcos:subs-cache

Semantic UI

Is it possible to load with semantic UI css rather than bootstrap?

Printing returned document's values to PDF prints nothing

I changed from alethes pagination to kurounin pagination hoping for different/desired results. I am trying to print returned document's values to PDF using meteor add ongoworks:pdf but nothing is printed. Values from normal helper functions do get printed but values from the paginated documents are not being printed

My code is as follows:

import { publishPagination } from 'meteor/kurounin:pagination';
publishPagination(PurchaseHistory);

{{#if isReady}}
    {{#each documents}} {{> oneInvoice}} {{/each}}
{{> invoiceForm}} {{> defaultBootstrapPaginator pagination=templatePagination limit=10 containerClass="text-center" onClick=clickEvent}} {{else}} Loading... {{/if}}
  • Date #{{transactionDate}}
  • Router.route('/store/invoiceList/:_username/:startingDate/:endingDate', { //:_startingDate/:_endingDate
    name: 'invoiceList',
    template: 'invoiceList',
    onBeforeAction: function()
    {
    var userId = Meteor.userId();
    if (userId)
    {
    this.next();
    },
    data: function(){
    return {};
    },
    waitOn: function() {

    	return [Meteor.subscribe('systemInfo'),Meteor.subscribe('testingOn'),Meteor.subscribe('companyAddressNameEmailAndVatNumber')];
    }
    

    });

    if (Meteor.isClient) {

    //,transactionDate:{$gte:new Date(decodeURIComponent(Router.current().params.username;)),
    // $lt:new Date(decodeURIComponent(Router.current().params.username;))}

    Template.invoiceList.onCreated(function () {
    	this.pagination = new Meteor.Pagination(PurchaseHistory, {
    		filters: {userId:Meteor.userId()},
    		sort: {
    			transactionDate: 1
    		},
    		perPage: 1
    	});
    });
    
    Template.invoiceList.helpers({
    	isReady: function () {
    		return Template.instance().pagination.ready();
    	},
    	templatePagination: function () {
    		return Template.instance().pagination;
    	},
    	documents: function () {
    		return Template.instance().pagination.getPage();
    	},
    	// optional helper used to return a callback that should be executed before changing the page
    	clickEvent: function() {
    		return function(e, templateInstance, clickedPage) {
    			e.preventDefault();
    			console.log('Changing page from ', templateInstance.data.pagination.currentPage(), ' to ', clickedPage);
    		};
    	}
    });
    
    Template.invoiceForm.events({
    	'submit .createInvoicePDF': function (event) {
    		event.preventDefault();
    	}
    });
    
    Template.invoiceForm.onRendered(function(){
    	var validator = $('.createInvoicePDF').validate({//2. remember to attach in the html a required field to all fields that are required
    		submitHandler: function(event){
    			Blaze.saveAsPDF(Template.oneInvoice, {
    			  filename: "Invoice.pdf", // optional, default is "document.pdf"
    			  //x: 0, // optional, left starting position on resulting PDF, default is 4 units
    			  //y: 0, // optional, top starting position on resulting PDF, default is 4 units
    			  orientation: "portrait", // optional, "landscape" or "portrait" (default)
    			  //unit: "in", // optional, unit for coordinates, one of "pt", "mm" (default), "cm", or "in"
    			  //format: "letter" // optional, see Page Formats, default is "a4"
    			  //elementHandlers: specialElementHandlers
    			});
    		}
    	});
    });
    

    }

    Can't set filters or dynamic_filters

    Hi! I have created a paginated publication and works great! But if I try to add a filter to be able to display collection items from the current logged in user, it returns an empty result.

    Maybe it's because I'm getting this.userId as undefined! If i replace this.userId by a current user id string, it works.

    This works:

      filters: { owner: 'SsZ4uWc5hdH2abisk' },
    

    This doesn't:

      filters: { owner: this.userId},
    

    This is the log I'm getting hardcoding the user id:

    I20170623-19:40:15.777(-3)? Pagination documents.paginatedList reactive publish {"owner":"SsZ4uWc5hdH2abisk"} {"fields":{"title":1,"body":1,"owner":1},"sort":{},"skip":0,"limit":10,"reactive":true,"debug":true}

    This is the log I'm getting using this.userId:

    => Meteor server restarted
    I20170623-19:25:26.550(-3)? undefined
    I20170623-19:25:26.556(-3)? Pagination documents.paginatedList reactive publish {"$and":[{},{}]} {"fields":{"title":1,"body":1,"owner":1},"sort":{},"skip":0,"limit":10,"reactive":true,"debug":true}

    This is the code in imports/api/documents/server/publications.js

    new Meteor.Pagination(Documents, {
      name: 'documents.paginatedList',
      filters: { owner: this.userId }, // Seems to be undefined
      dynamic_filters: () => {
        console.log(this.userId); // Got undefined in log
    
        return (
          { owner: this.userId }
        );
      },
      transform_options: (filters, options) => {
        const newOptions = options;
        const fields = {
          title: 1,
          body: 1,
          owner: 1,
        };
    
        newOptions.fields = _.extend(fields, newOptions.fields);
    
        return newOptions;
      },
    });
    

    Thanks in advise!

    Set current Page

    I've been trying to set the current page by taking the page number from my url. According to your documentation

    documents() {
       var pageNumb = Number(FlowRouter.getQueryParam('page'))
      return Template.instance().pagination.currentPage(pageNumb);
    },
    

    should set the page to "pageNumb",but the method currentPage return type is "Int", not object with all docs for this particular page.

    Cannot have conflicting publication

    This is not really an issue, but more something I feel should be documented but not sure if it should go in the readme, so I'm not doing a pull request.

    pagination.getPage() will return empty if there is a conflicting publication.

    i.e. You can't have in your collections/publications api both

    Meteor.publish('myCollection', function {
    return MyCollection.find();
    });

    and

    publishPagination(MyCollection);

    You can, however, have a secondary publication with another name, such as:

    Meteor.publish('singleCollectionItem', function(dbID) {
    		return MyCollection.findOne({ _id: dbID });
    	});

    Define is not defined error when setup Kurouning pagination

    When I trying to setup kurouning pagination in my meteor app it shows error like "define is not defined". Please can you give me some solution for this.

    I think it comes up with this code

    this.bookPagination = new Meteor.Pagination(Books, { sort: { title: 1 }, reactive: true });

    pagination.ready() never true

    I am having the same issue as issue #4 . I used the following:

    Template.myList.helpers({
        isReady: function () {
            console.log( Template.instance().pagination.ready() );
            return Template.instance().pagination.ready();
        },
        templatePagination: function () {
            return Template.instance().pagination;
        },
        documents: function () {
            return Template.instance().pagination.getPage();
        }
    });

    and in my template the one difference is that I am using {{#with documents}} instead of {{#each documents }}

    The console.log( Template.instance().pagination.ready() ) runs once false and never runs again.

    Using the solution mentioned in #4 does work however.

    Make subscription non reactive

    Hi! I read elsewhere that passing reactive: false as an option to a publication, renders it non reactive, so as that's what I want to several data grids in my project (IE: I don't want a reactive admin only user list data grid) I created the transform_options override as this:

    new Meteor.Pagination(Documents, {
      name: 'documents.paginatedList',
      transform_options: (filters, options) => {
        const newOptions = options;
    
        newOptions.reactive = false;
    
        return newOptions;
      },
    });
    

    According to logs, this seems to set the reactive option as I want

    Pagination documents.paginatedList find {} {"fields":{},"sort": {},"skip":100,"limit":10,"debug":true,"reactive":false}

    But after testing a little, if I open two browsers and login with different users on each other and then add or modify the published collection on one browser, it updates the data grid in the other browser.

    Is it possible to make this great pagination component non reactive by passing some option?

    Thanks!

    PS: More detailed use case here https://forums.meteor.com/t/meteor-1-5-publication-method-pagination/37240/24

    Meteor.Pagination constructor violates ESLint rule no-new

    Hi! In order to use Meteor.Pagination I have to define it as this

    new Meteor.Pagination(Activities, {
      name: 'activities.paginatedList',
      /* filters: { owner: userId },*/
      dynamic_filters: function activitiesDynamicFilters() {
        if (isAdmin(this.userId)) return {};
    
        return { owner: this.userId };
      },
      transform_options: (filters, options) => {
        const newOptions = options;
        const fields = {
          title: 1,
          body: 1,
          owner: 1,
        };
    
        newOptions.fields = _.extend(fields, newOptions.fields);
    
        return newOptions;
      },
    });
    

    This definition violates ESLint rule no-new http://eslint.org/docs/rules/no-new

    Is it possible to avoid that ESLint message without disabling the rule? Or is it possible to define the pagination otherwise?

    Thanks!

    Initial load - somehow getting un-subscribed

    I can sometimes recreate this, but have not yet made an easy reproducible example. (sorry)

    Basic summary:

    on initial page load

    • browser loads client
    • client starts resume-token login auth & subscribes to current user
    • auth in progress & React shows a loading placeholder
    • auth completes & my React page loads
    • React page loads a Component wrapped with a HOC which implements Pagination clientside
    • pagination sets up the subscription
    • meteor transfers records to minimongo
    • during transfer, React component receives new props (unsure what at this point)
    • pagination un-subscribes but doesn't re-subscribe
    • client trashes records from minimongo

    ss
    ss

    After that, if I can change pages and change back, without reloading the browser, it all works great


    I suspect the next step would be to add more debugging inside pagination client _checkObservers.

    I was just interested if you had any idea what was going on or what I should be trying out to get to the bottom of this.

    Is it possible to define a sorting with relevance algorithm

    Hi, is it possible to define somehow a sorting algorithm where I can define different sorting weights based on some conditions even regex maybe, so I can influence what elements to show up first in the result?

    Btw, the package is super extraordinary, it works great and fast with large collections, great work !!!

    Regex filters not working correctly?

    I've used other pagination packages and typically they accept regex filters (same as MongoDB does naturally) to find partial matches/case insensitivity.

    For example, if inputting "Val"

    var regexed = new RegExp(attributes.code, "i");

    Would return any case insensitive matches ("val" or "VAL"), as well as any partial matches ("value").

    But if I input regex filters in to this package, the results are empty.

    Any ideas on how to resolve?

    (EDIT: I found the closed issue related to this! Sorry for posting! Will toggle this issue as closed!)

    Pagination with komposer never returns any documents

    Below is my composer class trying to use Pagination. This never returns any documents, debug doesn't show me anything that would indicate why nothing is returned.

    const pagination = new Meteor.Pagination(CitiesCollection, {debug:true,perPage:2});
    const composer = (props, onData) => {
      const cities = pagination.getPage();
      if(pagination.ready()) {
        const cityData = {cities, pagination, props};
        onData(null, cityData);
      }
    };
    const AdminCityContainer = composeWithTracker(composer, SpinnerComponent)(CityTableComponent);
    export default connect()(AdminCityContainer);
    
    

    Did not check() all arguments during publisher 'questions'

    Hi,

    After carefully following your instructions for my Questions collection, I'm getting the following error in my server log.

    Exception from sub questions id zw2ARJsNHwec2GArw Error: Did not check() all arguments during publisher 'questions'
    I20151213-15:17:03.176(1)?     at [object Object]._.extend.throwUnlessAllArgumentsHaveBeenChecked (packages/check/match.js:411:1)
    I20151213-15:17:03.177(1)?     at Object.Match._failIfArgumentsAreNotAllChecked (packages/check/match.js:106:1)
    I20151213-15:17:03.177(1)?     at maybeAuditArgumentChecks (livedata_server.js:1695:18)
    I20151213-15:17:03.178(1)?     at [object Object]._.extend._runHandler (livedata_server.js:1023:17)
    I20151213-15:17:03.178(1)?     at [object Object].subscriptionProto._runHandler (packages/meteorhacks_kadira/lib/hijack/wrap_subscription.js:12:1)
    I20151213-15:17:03.181(1)?     at [object Object]._.extend._startSubscription (livedata_server.js:842:9)
    I20151213-15:17:03.182(1)?     at [object Object]._.extend.protocol_handlers.sub (livedata_server.js:614:12)
    I20151213-15:17:03.182(1)?     at packages/meteorhacks_kadira/lib/hijack/wrap_session.js:77:1
    I20151213-15:17:03.182(1)?     at [object Object]._.extend.withValue (packages/meteor/dynamics_nodejs.js:56:1)
    I20151213-15:17:03.182(1)?     at [object Object].sessionProto.protocol_handlers.sub (packages/meteorhacks_kadira/lib/hijack/wrap_session.js:76:1)
    

    Also, on the frontend, the questions show up and disappear without any errors in the javascript console.

    Filtering with regexp not working?

    I use your package, and it works almost fine because have a problem with filtering using RegExp.

        const yearFilter = {
            year: year,
        };
    
        const searchFilter = search ? {
          $or: [
            {'paragraph.symbol': new RegExp(search)},
          ],
        } : {};
    
        const filter = _.extend({}, yearFilter, searchFilter);
    
        Template.instance().pagination.filters(filter);

    This without RegExp (code below) works ok.

        const yearFilter = {
            year: year,
        };
    
        const searchFilter = search ? {
          $or: [
            {'paragraph.symbol': search},
          ],
        } : {};
    
        const filter = _.extend({}, yearFilter, searchFilter);
    
        Template.instance().pagination.filters(filter);

    I used earlier filters with RegExp on normal publication and it was ok as well.

    Cannot access props from within subcomponent

    Can you add an example of accessing prop data for filtering inside of the pagination component? I am passing data from one component to another (MyApplicants) via my router (FlowRouter):

    FlowRouter.route('/applicants', {
        name: 'Applicants',
        action: function () {
            var currentUser = Meteor.user();
            ReactLayout.render(App, {
                content:    <MyApplicants institutionID={Meteor.user().profile.institutionID} />,
                nav:        <Nav />,
                header:     <Header />
            });
        }
    });
    

    As you can see I'm passing institutionID to the new component via a prop in the router. I know that the institutionID is being passed because I can see it in the render of the MyApplicants component.

    Here is the MyApplicants component:

    MyApplicants = React.createClass({
        mixins: [ReactMeteorData],
    
        pagination: new Meteor.Pagination(Applicants, {
            perPage: 25,
            filters: {institution_id: this.props.institutionID },    //  <-- THIS IS CAUSING THE ERROR
            sort: {institution_id: 1, "last_name":1, "first_name":1}
        }),
    
        getMeteorData() {
            return {
                currentUser: Meteor.user(),
                applicants: this.pagination.getPage(),
                ready: this.pagination.ready()
            }
        },
        RenderApplicantRow(applicant, key) {
            return (
                <div key={key}>
                    <p>[{applicant.institution_id}] {applicant.last_name}, {applicant.first_name}</p>
                </div>
            )
        },
    
        render : function () {
            return (
                <div>
                    <section className="content">
    
                   {this.data.applicants.map(this.RenderApplicantRow)}
    
                              <DefaultBootstrapPaginator
                                  pagination={this.pagination}
                                  limit={6}
                                  containerClass="text-center"/>
    
                    </section>
                </div>
            )
        }
    });
    
    

    The problem is that I cannot access this.props.institutionID inside of the pagination component. I know the value is getting passed (I can see it if I'm just testing output in the render) but can't figure out why it doesn't pass into the pagination call. And I know the pagination works because I do not get an error if I hard code in a value.

    Thanks for the help.

    More information and understanding on client getPage()

    I'm looking at the current client implementation and I don't understand it

     Pagination.prototype.getPage = function() {
            var options = {
                    fields: this.fields(),
                    sort: this.sort(),
                    skip: (this.currentPage() - 1) * this.perPage(),
                    limit: this.perPage()
                },
                handle = Meteor.subscribe(
                    this.collection._name,
                    this.filters(),
                    options
                ),
                query = {};
    
            this.ready(handle.ready());
            if (handle.ready()) {
                this.totalItems(Counts.get('sub_count_' + handle.subscriptionId));
            }
    
            query['sub_' + handle.subscriptionId] = 1;
            return this.collection.find(query, {fields: this.fields(), sort: this.sort()}).fetch();
        };

    This bit creates a new subscription, which is reactive, but should start as not-ready...

     handle = Meteor.subscribe(
                    this.collection._name,
                    this.filters(),
                    options
                ),

    This bit copies the "current" value from the subscription handle to the reactive dict (always false)

    this.ready(handle.ready());

    This bit would take the clientside data from mini-mongo and return it, if it's there...

    query['sub_' + handle.subscriptionId] = 1;
    return this.collection.find(query, {fields: this.fields(), sort: this.sort()}).fetch();

    The problem is, the next time you run getPage, it sets the subscription, again, to a new subscription... every time you re-run getPage

    Use _.map(Meteor.connection._subscriptions, c => c.name) to see what I'm talking about.

    None of that data/implementation is reactive.

    Data Tables related with Kurounin pagination

    I used this pagination to integrate subscription base pagination in my meteor app. Its work perfectly. But now I want to convert my all tables to the data tables. How can I do it?
    Thanks

    pagination.ready() not reactive

    I have noticed that assigning pagination.ready() to a ReactiveVar doesn't keep reactivity,
    I think in order to make it work, the handle should be stored instead:
    so it will be this.ready(handle) instead of this.ready(handle.ready()) and then it will keep reactivity on the outside :)

    As a workaround, i have defined a helper like this to check for ready state

     pageReady:function(){
            var instance = Template.instance();
            var pagesChange = instance.pagination.getPage();
            return instance.pagination.ready();
        }

    How to publish dependable collection?

    Hi

    In client onCreated I am using following code

    this.pagination = new Meteor.Pagination(Ads, {
      	sort: {
        				_id: -1
            	},
    		perPage: 1,
    		filters:conditions,
    		fields:{"images":1,"adlocation":1,"title":1,"slug":1}
      });
    

    In server publish

    new Meteor.Pagination(Ads,{
    	transform_options: function (filters, options) {
            const fields = { "images":1,"adlocation":1,"title":1,"slug":1 }
            options.fields = _.extend(fields, options.fields);
            return options;
        }
    });
    

    Defined images in Ads schema like

    images: {
        type: [String],
        optional: true,
        label: "Pictures",
        autoform: {
          afFieldInput: {
            type: "cfs-files",
            collection: "images"
          }
        }
      },
    

    How to fetch(subscribe) images from images collection with same pagination.

    I am struggling with the solution.
    Please help me

    Regards,
    Jagan

    Server side filters

    This is more of a request.

    It would be nice to be able to filter the data from the server side for security reasons. Based on my use of the package thus far, the filter is the only thing preventing the user from accessing all the documents in a given collection. This is handled on the client side, so if the client changes the filter they can get access to all the documents in that given collection.

    Is there anyway to hard-code the filters from the server side?

    Recommend Projects

    • React photo React

      A declarative, efficient, and flexible JavaScript library for building user interfaces.

    • Vue.js photo Vue.js

      🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

    • Typescript photo Typescript

      TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

    • TensorFlow photo TensorFlow

      An Open Source Machine Learning Framework for Everyone

    • Django photo Django

      The Web framework for perfectionists with deadlines.

    • D3 photo D3

      Bring data to life with SVG, Canvas and HTML. 📊📈🎉

    Recommend Topics

    • javascript

      JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

    • web

      Some thing interesting about web. New door for the world.

    • server

      A server is a program made to process requests and deliver data to clients.

    • Machine learning

      Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

    • Game

      Some thing interesting about game, make everyone happy.

    Recommend Org

    • Facebook photo Facebook

      We are working to build community through open source technology. NB: members must have two-factor auth.

    • Microsoft photo Microsoft

      Open source projects and samples from Microsoft.

    • Google photo Google

      Google ❤️ Open Source for everyone.

    • D3 photo D3

      Data-Driven Documents codes.