Meteor-Community-Packages / meteor-tabular

Reactive datatables for large or small datasets
https://packosphere.com/aldeed/tabular
MIT License
363 stars 136 forks source link

Selector and pagination index (follow up #50) #61

Open kk4sh opened 9 years ago

kk4sh commented 9 years ago

Use the selector helper seems to remove the current pagination index even if the selector has not been changed.

As required, here is a meteorpad to reproduce.

Note: removing selector option from the tabulartable fixes the issue, but of course i need it.

Best of all, as a pro meteor user, if you can give me the tip to avoid page flashing on browsing the items, it would be awesome.

Thank you for your very valuable help!

aldeed commented 9 years ago

The issue in your example seems to be the Router.go. It makes sense that the table will reset when you change routes because the templates are destroyed.

If I'm misunderstanding, then please list the exact steps I need to do on your example to reproduce the issue.

kk4sh commented 9 years ago

Maybe a miscoding issue, in my use case i dont want to create a new instance of dt when changing route; I updated the sample. Sorry im quite new in meteor.

Thanks for help


To reproduce:

aldeed commented 9 years ago

afaik, changing routes destroys and rerenders the route template, even if it's the same template and only the params are changing. This happens both times, but since you're on page 1 in the first case, you don't notice it happening.

I'm assuming your goal is to reactively update the URL and the template's data context but not do any of the other normal routing flow. I don't see anything in the iron router docs about that. I can think of ways to fudge it, but it seems like there should be some standard solution in IR. @cmather?

cmather commented 9 years ago

Hey guys, the templates should only be destroyed from one route to the next if the template actually changes. We take great care NOT to re-render the layout or child templates if nothing has changed. But keep in mind if you change the layout from route to route, everything will necessarily re-render since the layout is at the top of the rendering hierarchy. There is one gotcha here related to using helpers on controllers. Are you doing that?

If you're seeing different behavior, it might be a bug in iron:router, or it might just be the way your helpers are used in the app. How are you determining that a re-rendering is happening?

kk4sh commented 9 years ago

As i can see, the template which contains the table seems well not be rerendered nor destroyed as wanted by ironrouter. In fact, as mentionned, just the pagination index of the datatable is reseted and not the whole datatatable . @aldeed for ie, use a filter in the datatable it is kept.

aldeed commented 9 years ago

OK, weird. I will have to take another look. It does have something to do with the Router.go call because the issue goes away when you remove that line.

lucasrosa commented 9 years ago

I have the same issue. As @kk4sh pointed out, only the pagination index is reset. If you have anything in the "Search" input, it stays there.

I tried a shot in the dark by using the "stateSave: true" option from the DataTable (http://datatables.net/reference/option/stateSave), but it didn't work.

Is there a way to manually set the pagination or the selector? It could be a possible workaround for now.

lucasrosa commented 9 years ago

Something else I noticed that might help:

If the helper referenced by the selector is a function, the pagination is reset, but if it is only a simple object the pagination works as expected.

For example:

The template: {{> tabular table=TabularTables.Clients selector=selector }}

The helpers: Works (keeps the pagination index): selector: {organization_id: "c9S4Fbgzz8WpJQwKq"} :+1:

Doesn't work (doesn't keep the pagination index): selector: function(){ return {organization_id: "c9S4Fbgzz8WpJQwKq"}} :-1:

MohammedEssehemy commented 6 years ago

for any one coming later using lucasfurlani note and boustanihani note I worked around this by reinitializing the datatable and passing the selector as object

        {{#if datatable_ready}}
          {{> tabular table=TabularTables.Order selector=state.dt_query class="table table-striped table-bordered table-hover orders-table"}}
        {{/if}}
 const state = {};
  const refreshDatatable = function (){
    // first destroy datatable
    Session.set('dt_query_changing', true);
    setTimeout(()=>{
      // changing the session var to force table reinitialization
      Session.set('dt_query_changing', false);
    }, 0);

Template.orders.onRendered(function(){
     this.autorun(function(){
            // here your logic to change state.dt_query
           refreshDatatable();
      });
});
Template.orders.helpers({
      datatable_ready(){
         return !Session.get('dt_query_changing');
     },
     state: state
});
MohammedEssehemy commented 6 years ago

I think the problem was fixed by #383

but wasn't published to atmosphere, so you might download the repo and put it in the packages folder in your project

jorisroling commented 5 years ago

I've found that using the selector function reactive, it is runs (because of Tracker.autorun) too often and prevents going to the next page. By being careful with assigning to those ReactiveVars only when actually changed (see below) this is prevented.

I use this code (both server & client):

import { ReactiveVar } from 'meteor/reactive-var'
import equal from 'fast-deep-equal'

ReactiveVar.prototype.setIfChanged = function(val) {
  if (!equal(val,this.get())) {
    return this.set(val)
  }
}

and then use .setIfChanged(value) to make the selector only be called (autoran) when actual new values arrive.

Hope it helps!