Skip to content

Commit

Permalink
Add alternativeCount and skipCount options
Browse files Browse the repository at this point in the history
Closes #355
  • Loading branch information
aldeed committed Nov 19, 2016
1 parent a929247 commit 3cab61b
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 4 deletions.
18 changes: 18 additions & 0 deletions README.md
Expand Up @@ -547,6 +547,24 @@ More options to translate can be found here: https://datatables.net/reference/op

You can set the `titleFn` column option to a function instead of supplying a string `title` option. This is reactively rerun as necessary.

### Optimizing the Total Table Count

By default, a count of the entire available filtered dataset is done on the server. This can be slow for large datasets. You have two options that can help:

First, you can calculate total counts yourself and return them from a function provided as the `alternativeCount` option to your `Tabular.Table`:

```js
alternativeCount: (selector) => 200,
```

Second, you can skip the count altogether. If you do this, we return a fake count that ensures the Next button will be available. But the fake count will not be the correct total count, so the paging info and the numbered page buttons will be misleading. To deal with this, you should use `pagingType: 'simple'` and either `info: false` or an `infoCallback` function that omits the total count:

```js
skipCount: true,
pagingType: 'simple',
infoCallback: (settings, start, end) => `Showing ${start} to ${end}`,
```

## Integrating DataTables Extensions

There are a wide variety of [useful extensions](http://datatables.net/extensions/index) for DataTables. To integrate them into Tabular, it is best to use the NPM packages.
Expand Down
19 changes: 18 additions & 1 deletion common/Tabular.js
Expand Up @@ -30,6 +30,8 @@ Tabular.Table = class {
this.allowFields = options.allowFields;
this.changeSelector = options.changeSelector;
this.throttleRefresh = options.throttleRefresh;
this.alternativeCount = options.alternativeCount;
this.skipCount = options.skipCount;

if (_.isArray(options.extraFields)) {
const fields = {};
Expand All @@ -41,7 +43,22 @@ Tabular.Table = class {

this.selector = options.selector;

this.options = _.omit(options, 'collection', 'pub', 'sub', 'onUnload', 'allow', 'allowFields', 'extraFields', 'name', 'selector');
this.options = _.omit(
options,
'collection',
'pub',
'sub',
'onUnload',
'allow',
'allowFields',
'changeSelector',
'throttleRefresh',
'extraFields',
'alternativeCount',
'skipCount',
'name',
'selector'
);

Tabular.tablesByName[this.name] = this;
}
Expand Down
17 changes: 14 additions & 3 deletions server/main.js
Expand Up @@ -108,11 +108,22 @@ Meteor.publish('tabular_getInfo', function (tableName, selector, sort, skip, lim

let filteredRecordIds = filteredCursor.map(doc => doc._id);

// If we are not going to count for real, in order to improve performance, then we will fake
// the count to ensure the Next button is always available.
const fakeCount = filteredRecordIds.length + skip + 1;

const countCursor = table.collection.find(selector, {fields: {_id: 1}});

let recordReady = false;
let updateRecords = () => {
const currentCount = countCursor.count();
let currentCount;
if (!table.skipCount) {
if (typeof table.alternativeCount === 'function') {
currentCount = table.alternativeCount(selector);
} else {
currentCount = countCursor.count();
}
}

// From https://datatables.net/manual/server-side
// recordsTotal: Total records, before filtering (i.e. the total number of records in the database)
Expand All @@ -123,8 +134,8 @@ Meteor.publish('tabular_getInfo', function (tableName, selector, sort, skip, lim
// count() will give us the updated total count
// every time. It does not take the find options
// limit into account.
recordsTotal: currentCount,
recordsFiltered: currentCount
recordsTotal: table.skipCount ? fakeCount : currentCount,
recordsFiltered: table.skipCount ? fakeCount : currentCount
};

if (recordReady) {
Expand Down

0 comments on commit 3cab61b

Please sign in to comment.