Version 5.3 Released!

Click to checkout the new features

Old Documentation
You are browsing documentation for an old version of Tabulator. Consider upgrading your project to Tabulator 5.3

Release Notes

Editor Config

a new .editorconfig file has been added to the Tabulator project to make it easier for developers to contribute to the project with correct indentation and other browser settings

File Importing

A new Import module has been added in this release to handle loading non JavaScript data types into the table

Import From Local File

You can let the user choose a file from their local disk by using the import function. It will present the user with a standard file open dialog where they can then choose the file to load into the table.

The first argument of the function is the importer that will parse the file and convert it into an array of row data, this can either be a string representing one of the built in importers or a function for a custom importer. If this argument is missing, the import module will default to using the value of the importFormat option.

The second argument is the value for the accept attribute of the file input, and is used to restrict the files that the user can pick, this argument will accept any of the values valid for the accept field of an input element . If this argument is missing the user will be able to pick any file type in the file picker.

table.import("json", ".json")
.then(() => {
    //file successfully imported
})
.catch(() => {
    //something went wrong
})

The import function returns a promise that resolves when the data has been successfully loaded into the table

Import From Data

If you already have the formatted data from a file and dont need to present the user with the a file picker then you can use the importFormat option to tell Tabulator how to import data into the table when it is passed into the data option or the setData function.

The importFormat option can take any of the built in importers or a function for a custom importer.

Importing With Data Option

This can be used to import custom data when the table is loaded.

//define some CSV data
var csvData = `"Oli", "London", "23"
"Jim", "Mancheser", "53"`;

//define table
var table = new Tabulator("#example-table", {
    data:csvData,
    importFormat:"csv",
    columns:[...],
});

Importing With Data Option Using Auto Columns

With autoColumns enabled, you can build the table entirely from CSV data, as long as the first row of the data contains the column titles

//define some CSV data
var csvData = `"Name", "Location", "Age"
"Oli", "London", "23"
"Jim", "Mancheser", "53"`;

//define table
var table = new Tabulator("#example-table", {
    data:csvData,
    importFormat:"csv",
    autoColumns:true,
});

Calling the setData or import functions on a table with this setup will result in it parsing the column headers again from any future import

Importing With setData Function

This can be used to import custom data at any point after the table has loaded.

//define some CSV data
var csvData = `"Oli", "London", "23"
"Jim", "Mancheser", "53"`;

//define table
var table = new Tabulator("#example-table", {
    importFormat:"csv",
});

//load data at some point later
table.setData(csvData);

Built In Importers

Tabulator comes with a number of preconfigured importers, which are outlined below.

Note: For a guide to adding your own importers to this list, have a look at the Extending Tabulator section.

JSON

The json importer will load a JSON formatted file into the table.

table.import("json", ".json");

Data Format
The data must be stored as a valid json string matching the the structure of an array of objects as defined in the Load Data from Array section.

CSV

The csv importer will load a csv formatted file into the table.

table.import("csv", ".csv");

CSV files can contain a column title row, as long as the titles match the column titles the row will be safely ignored by Tabulator

As data contained in a CSV is arranged in simple columns, each column in the CSV will be loaded in order and matched to a column of a corresponding index in the table.

Data Format
The data must be stored as a valid csv format, with rows separated with a carriage returns and columns separated by commas.

Auto Columns
If the autoColumns option is enabled on the table, then the first row of the CSV data should be the column titles.

Custom Importers

As well as the built-in importers you can define a importer using a custom importer function.

The importer function accepts one argument, a string of the text content of the file being imported.

The function can return one of two options. An array of row objects as defined in the Load Data from Array section.

Or a two dimensional array of rows containing columns, this will then be used by Tabulator to infer the columns from their position in the array. If the autoColumns option is enabled on the table, then the first row of the array should be the column titles.

//define custom importer
function customJsonImporter(fileContents){
    return JSON.parse(fileContents);
}

//trigger import using custom importer
table.import(customJsonImporter, ".json");

File Readers

When loading a file using the import function, Tabulator reads in the file using a File Reader.

By default Tabulator will read in the file as plain text, which is the format used by all the built in importers. If you need to read the file data in a different format then you can use the importReader option to instruct the file reader to read in the file in a different format.

var table = new Tabulator("#example-table", {
    importReader:"buffer", //read imported file as buffer
});

The available readers are:

  • text - Read file as plain text
  • buffer - Read file as ArrayBuffer
  • binary - Read file as raw binary in string format
  • url - Read file as data url

Ajax

Real Time Ajax Parameters

You can now generate ajax parameters for each request by passing a callback to the ajaxParams option.

This function will be called every time a request is made and should return an object containing the request parameters.

var table = new Tabulator("#example-table", {
    ajaxURL:"http://www.getmydata.com/now", //ajax URL
    ajaxParams: function(){
        return {key1:"value1", key2:"value2"},
    }
});

Data Load Error Message Timeout

The dataLoaderErrorTimeout option has been added to allow configuration of how long and data load error message is displayed.

This option will accept an integer representing the number of milliseconds the message should be displayed for (default 3000 milliseconds).

var table = new Tabulator("#example-table", {
    ajaxURL:"http://www.getmydata.com/now", //ajax URL
    dataLoaderErrorTimeout:2000, //display error message for 2 seconds
});

Keybindings

The keybindings module has received a number of updates in this release.

Updated Keybindings

Keybindings that used to use the ctrl key, now also have a second binding that uses the meta key to improve usability on mac's

Action Default Key Combination (keycode) Function
undo ctrl + z ("ctrl + 90") OR meta(cmd) + z ("meta + 90") Undo last user data edit
redo ctrl + y ("ctrl + 89") OR meta(cmd) + y ("meta + 89") Redo last user data edit
copyToClipboard ctrl + c ("ctrl + 67") OR meta(cmd) + c ("meta + 67") Copy table data to clipboard

Multiple Key Combinations

It is now possible to bind multiple key combinations for a single action by passing an array of strings to its property:

var table = new Tabulator("#example-table", {
    keybindings:{
        "redo" : ["ctrl + 82", "meta + 82"], //bind redo function to ctrl + r or meta + r
    },
});

Keycode Lookups

If you are binding an action to an a - z key, then it is now possible to use the character itself and let Tabulator lookup the keycode for you:

var table = new Tabulator("#example-table", {
    keybindings:{
        "redo" : "ctrl + r", //bind redo function to ctrl + r
    },
});

Menus

The menu module has had an overhaul in this release, using the interaction manager to radically reduce the number of event listeners needed and to improve efficiency. It has also had several new features added.

Container Element

By default Tabulator will append the menu element to the body element of the DOM as this allows the menu to appear correctly in the vast majority of situations.

There are some circumstances where you may want the menu to be appended to a different element, such as the body of a modal, so that the menu is contained with that element.

In these circumstances you can use the menuContainer option to specify the element that the menu should be appended to.

var table = new Tabulator("#example-table", {
    menuContainer:"#modal-div", //append menu to this element
});

The menuContainer option can accept one of the following values:

  • false - Append menu to the body element (default)
  • true - Append menu to the table
  • CSS selector string - A valid CSS selector string
  • DOM node - A DOM Node

If Tabulator cannot find a matching element from the property, it will default to the document body element.

Container Position
Menu elements are positioned absolutely inside their container. For this reason you must make sure that your container has its position defined in CSS

Parent Element
The element you pass into the menuContainer option must be a parent of the table element or it will be ignored

Menu Events

New menu events have been added to help with tracking user interaction with menus.

Menu Opened

The menuOpened callback is triggered when a menu is opened.

table.on("menuOpened", function(component){
    //component - the component the menu has been opened on (could be cell, row or column depending on menu)
});

Menu Closed

The menuClosed callback is triggered when a menu is closed.

table.on("menuClosed", function(component){
    //component - the component the menu has been closed for (could be cell, row or column depending on menu)
});

Pagination

Pagination Counter

You can now choose to display a pagination counter in the bottom left of the footer that shows a summary of the current number of rows shown out of the total.

To enable this you need to set the paginationCounter option in the table constructor.

var table = new Tabulator("#example-table", {
    pagination:true,
    paginationCounter:"rows", //add pagination row counter
});

Built In Counters

Tabulator comes with a couple of built in counters that format the page counter differently for different needs

The paginationCounter option can take one of two built in string values:

  • rows - displays a summary of the currently displayed rows in the format "Showing X-X of X rows"
  • pages - displays a summary of the currently displayed pages in the format "Showing X of X pages"

Note: For a guide to adding your own counters to this list, have a look at the Extending Tabulator section.

Custom Counters

If you want to have a fully customized counter, then you can pass a function to the paginationCounter option

The formatter function accepts 5 arguments:

  • pageSize - Number of rows shown per page
  • currentRow - First visible row position
  • currentPage - Current page
  • totalRows - Total rows in table
  • totalPages - Total pages in table

The function must return the contents of the counter, either the text value of the counter, valid HTML or a DOM node

var table = new Tabulator("#example-table", {
    pagination:true,
    paginationCounter:function(pageSize, currentRow, currentPage, totalRows, totalPages){
        return "Showing " pageSize +  " rows of " + totalRows + " total";
    }
});

Counter Element

By default the counter will be displayed in the left of the table footer. If you would like it displayed in another element pass a DOM node or a CSS selector for that element to the paginationCounterElement option.

var table = new Tabulator("#example-table", {
    pagination:true,
    paginationCounter:"rows",
    paginationCounterElement:"#page-count", // show counter in this element instead of footer
});

Ajax Total Row Counting

When working with remote ajax pagination the table does not know how exactly how many total rows are available, because it only loads one page of row data at a time.

If you are using remote pagination with a counter then you need to include the last_row value in your response data that is set to the total number of rows available

{
    "last_page":15, //the total number of available pages (this value must be greater than 0)
    "last_row":246, //the total number of rows pages (this value must be greater than 0)
    "data":[ // an array of row data objects
        {id:1, name:"bob", age:"23"}, //example row data object
    ]
}

If your remote response is missing the last_row value then Tabulator will attempt to estimate the number of rows by multiplying the page size by the last_page value

Localization of Counters

You can customise the text of the built in counters using the counters pagination property in the lang module

var table = new Tabulator("#example-table", {
    locale:true,
    langs:{
        "default":{
            "pagination":{
                "counter":{
                    "showing": "Showing",
                    "of": "of",
                    "rows": "rows",
                    "pages": "pages",
                }
            },
        }
    },
});

For full details on how to adjust localization, please read the localization module docs

Columns

Max Initial Width

The maxInitialWidth column definition option can be used to set the max width of a column when the table is initially rendered, in pixels.

The user can then resize the column larger than this up to the maxWidth limi, if set

{title:"Name", field:"name", initialMaxWidth:100, maxWidth:200} //allow the column to reach a max of 100px wide when initially rendered but allow the user to resize it up to 200px

Movable Rows

New Events

A couple of new external events have been added to help track row movement

Row Move Started

The rowMoving event will be triggered when a row has started to be dragged.

table.on("rowMoving", function(row){
    //row - row component
});

Row Move Cancelled

The rowMoveCancelled event will be triggered when a row has been moved but has not changed position in the table.

table.on("rowMoveCancelled", function(row){
    //row - row component
});

Sorting

Date Time Sorting

The date, time and datetime sorters have been update to parse ISO date formats.

You can enable ISO format support by passing a value of "iso" to the format property of the sorterParams object:

{title:"Example", field:"example", sorter:"datetime", sorterParams:{
    format:"iso",
}}

Formatting

Date Time Formatting

The datetime and datetimediff sorters have been update to parse ISO date formats.

You can enable ISO format support by passing a value of "iso" to the inputFormat property of the formatterParams object:

{title:"Example", field:"example", formatter:"datetime", formatterParams:{
    inputFormat:"iso",
}}

Data Trees

Row Component Functions

functions have been added to the row component to allow querying of a rows tree state.

Check If Tree Expanded

The isTreeExpanded function will return true if the row is expanded and showing its children and false if it is collapsed.

var expanded = row.isTreeExpanded();

Downloads

JSON Downloader

The json formatter now supports using the titleDownload column definition to set the name of the field in the json output

{title:"Name", field:"name", titleDownload:"Persons Name"}

Example json output:

[
    {
        "age":22,
        "color":"red",
        "Persons Name":"steve"
    }
]

JSON Lines Downloader

The new jsonLines downloader will format data as a series of JSON encoded row objects separated by carriage returns.

This format is commonly used in conjunction with Apache Spark, Hadoop and Hive.

Bug Fixes

v5.1.0 Release

The following minor updates and bugfixes have been made:

  • Row resizing no longer triggers a console error
  • Fixed issue with exception thrown when using cell navigation functionality or tabEndNewRow option
  • Interaction monitoring of group header tap events is now correctly handled through the interaction module
  • Improved stability of horizontal virtual DOM
  • Fixed issue with cellEdited callback not being triggered in a cells column definition
  • Fixed missing pagination buttons in materialize theme
  • Highlighting of selected rows now works correctly with materialize theme
  • Row initialization flag is now set before rowFormatter is called
  • Use strict comparison to handle cell data change check to allow changing between falsey values
  • Fixed typo in internal data-refreshed event name
  • The basic vertical renderer now clears dow rows before attempting to re-render them to prevent corruption of row layout
  • Console warning added to the interaction manager to warn developers when trying to listen to events on an incorrectly reinitialized table
  • Mock cell component is now correctly passed to headerFilterParams callback
  • Fixed regressions in the Validate module
  • GroupRows module now configures itself after the tables columns have been set to ensure rows are grouped correctly on load
  • Fixed issue with redraw loop when browser zoom is not 100%
  • rowMouseOver events no longer throw an error when the mouse moves over a frozen row
  • Fixed layout issue with column header sort arrows when table is in RTL mode

v5.1.1 Release

The following minor updates and bugfixes have been made:

  • Removed unnecessary console logging.
  • Fixed issue with GroupComponent function bindings
  • Fixed issue with progressive scroll attempting to load data beyond final page when initializing if all data has been loaded and the table viewport is still not full.
  • Fixed double firing of internal row-added event.
  • Adding rows to the table when using column calculations and data trees no longer throws an exception
  • The getRows function no longer returns calc rows when passed the visible argument
  • The value of a the currently edited cell is now saved before creation of a new row when using tabEndNewRow
  • Fix error with getParentColumn function always returning false
  • Collapsed data is now correctly shown when responsiveLayout is set to collapse and the responsiveLayout formatter is in use
  • Interaction events in nested tables no longer trigger console errors
  • Fixed footer layout issues when using pagination and bottom calculations
  • Sorting of data should no longer alter table vertical scroll position
  • Fixed typo in data-refreshing internal event name
  • The placeholder text now remains horizontally centered in the table viewport at all times, and the text wraps if it does not fit in the available space

v5.1.2 Release

The following minor updates and bugfixes have been made:

  • Fixed issue with placeholder text not clearing after ajax load after table has been resized
  • The paginationAddRow option now works correctly when set to a value of table
  • Added module initialization order prop to allow modules to initialize in the correct order
  • Restoed functionality to the sort, filter and page persistence modes
  • Column headers with no title are now correctly rendered as empty in the print output
  • The rownum formatter will only display a value in rows in the table, not in calc rows etc
  • When using responsiveCollapse column header titles are now displayed as HTML rather than plain text

v5.1.3 Release

The following minor updates and bugfixes have been made:

  • Fix issue with column group headers triggering a console error when redrawn in classic render mode
  • Fixed issue with double initialization of FooterManager
  • Fixed regression in last release, preventing use of the footerElement option while pagination is enabled
  • Replaced use of deprecated substr functionality with slice
  • Improved webpack tree shaking config to prevent removal of stylesheets
  • Added new layout-refreshing internal event to allow tracking of layout process
  • Fixed multiple calls of frozen columns module layout function when redrawing table
  • Using a combination of fitDataFill layout mode and a frozen right column, no longer displays an unneeded horizontal scroll bar
  • The rowSelection formatter will now correctly handle uses of the ctrl and shift keys when the selectableRangeMode option is set to click
  • Fixed column calculation issue when groupBy, dataTree, dataTreeStartExpanded and dataTreeChildColumnCalcs options used together.
  • The columnResized event is now only fired if the width of a column actually changes, simply clicking on the resize handle without moving will not fire the event.
  • When a column is resized to fit its data by double clicking on the resize handle, the columnResized event is now triggered after the recalculation of the columns width

v5.1.4 Release

The following minor updates and bugfixes have been made:

  • Fixed layout issue with external footer elements since last update
  • Fixed issue with pagination page buttons not displaying in footer when bottom column calculations are in use
  • The rows page counter now correctly handles empty tables
  • added an aria-label to the checkbox in the rowSelection formatter
  • Fixed console error when using groupContextMenu option
  • When exporting a table to HTML, the cell styles will now be cloned from the matching column and include text alignment
  • The data option only has its references cleared if it is a type of array
  • The rowSelectionChanged event is no longer triggered if table selection is cleared when no rows are selected
  • Row internal initialization state is now set before the horizontal renderer is triggered
  • Horizontal virtual dom now correctly calculates column widths when in fitData layout mode
  • Focusing in a header filter when scrolled to the far right of the table will no longer break alter the horizontal scroll position of the table
  • Improve efficiency of frozen column calculations

v5.1.5 Release

The following minor updates and bugfixes have been made:

  • The horizontal virtual dom renderer now correctly handles fitDataFill and fitDataStretch layout modes
  • The horizontal virtual dom renderer now has an adaptive buffer window to allow columns of any size to render correctly, this prevents columns with a width wider than the table from corrupting the table view
  • Pagination counters now receive the number of actual data rows on display, it now excludes group and column calc rows.

v5.1.6 Release

The following minor updates and bugfixes have been made:

  • Improved menu positioning when overflowing on statically positioned body element
  • Fixed issue with horizontal virtual renderer headers breaking alignment when table scrolled fast right then slowly left
  • Efficiency improvements to the horizontal virtual renderer

v5.1.7 Release

The following minor updates and bugfixes have been made:

  • Ensure horizontal virtual dom renderer visible row cache is cleared on data

v5.1.8 Release

The following minor updates and bugfixes have been made:

  • Menus are now correctly dismissed when editing starts on a cell
  • Fixed error message in component binder when attempting to load properties on a component
  • Build tools version bumped
  • Select editor now reshows list when cleared

Donate