Site icon Ryadel

Tabulator 3.x - Download all data from pagination-enabled Table

Tabulator 3.x - Download all data from pagination-enabled Table

Oliver Folkerd's Tabulator is nothing less than an awesome plugin, which I'm extensively using in all my JQuery-based Web Applications. In a nutshell, it's a lightweight JQuery plugin that allows you to create interactive tables from any HTML Table, Javascript Array, AJAX data source or JSON formatted data. The plugin also comes with a complete set of CSS classes to easily and effectively styling your tables.

If you don't know it yet, take a look at the Tabulator official page and/or to the Tabulator GitHub repository.

Among the many useful features offered by Tabulator, there's the download data function, which allows the users to download the table data as a file directly from their browser, without server support. The download will contain the values of all data currently visible in the table, thus matching the current column layout, column titles, sorting and filtering, in one of the following formats:

Trigger a download is just as easy as calling the download function, passing the file type (from the above list) as the first argument, and an optional second argument of the file name for the download (if this is left out it will be "Tabulator.ext"). Here's a quick example:

The Problem

Although the download data feature is great, it lacks something really important: since it's limited to the currently visible data, it doesn't give the chance to download *all* the data of  a pagination-enabled table. To better understand the issue, let's picture a table with 5000 total rows which is set to show 50 rows per page. The download data function will only get you the 50 currently visible rows, thus ignoring the remaining 4950: in other words, the resulting file (be it CSV, JSON, XLSX or PDF) will only contains the currently available/visible/fetched rows.

The only way to overcome this "by design" would be to entirely drop the pagination and getting a 5000-rows table - which could easily kill your HTML page.

The Fix

As a matter of fact, downloading only the currently-visible rows is a legitimate behaviour, expecially when remote paging is enabled, since the previous/next/remaining rows haven't even been fetched from the server.

However, since I really needed a download all data function, I did my best to find a way to download all rows regardless if they're visible or not: I managed to do that by "hacking" the downloadDataMutator / downloadDataFormatter function in the following way. 

The hack has been originally published in this GitHub issue, but I choose to make a post about it to better explain it.

The "Download All Data" Button

The first thing I did was to implement a "download all" button with an async ajax call to fetch all the values from the server: as a matter of fact, I used a slightly modified version of the same Web Service that I implemented to populate the table in the first place - without the paging logic, so that it would always return all the available rows.

Notice how the WS result - a JSON array of all the rows - is stored in the allData global variable.

The DownloadDataMutator hack

The next (and final) step involves hacking the Tabulator's downloadDataMutator option method (which has been renamed to downloadDataFormatter in Tabulator 3.5 and above) to replace the "current" table (visible) data with the allData global variable which we populated early on:

Notice how the allData global variable is then set to null, so that the standard download data function would still work for any subsequent download method call: that way multiple download visible rows and download all rows buttons can cohesist without significative conflicts.

Conclusion

Let's briefly summarize what this Tabulator's data-swapping hack actually does:

  • when the download all data button is clicked, it downloads all the unpaginated data from the Web Server in a single AJAX call and stores the results in the allData global variable;
  • as soon as the AJAX call finishes and the allData global variable is set, it fires the Tabulator's native download method, who also triggers the downloadDataMutator hook (downloadDataFormatter in Tabulator 3.5 and above);
  • within the downloadDataMutator / downloadDataFormatter hook, it swaps the "actual" table data (the visible rows) with the previously-fetched data stored in the allData global variable (all the available rows), providing it's not null; right after that, the allData variable is set to null because it's not needed anymore.

That's about it: I sincerely hope that such hack will help those who're using Tabulator and are missing such handy feature!

Many thanks to @olifolkerd for his awesome work!

Exit mobile version