Release Notes

RTL Text Direction Support

Tabulator now supports both "Right to Left" and "Left To Right" text directions.

By default Tabulator will attempt determine the correct text direction for the table based on the direction CSS property inherited from its parent element.

If you want to force the direction of the table, you can use the textDirection setup option. This can take one of three string values:

  • auto - this will automatically detect text direction from the direction CSS property inherited from its parent element (default)
  • ltr - this will force the table into left to right layout mode
  • rtl - this will force the table into right to left layout mode

var table = new Tabulator("#example-table", {
    textDirection:"rtl", // force table into right to left text direction
});

Frozen Column Support
Frozen columns are currently not supported in RTL mode, this functionality will be coming in the 4.9 release

Horizontal Virtual DOM

By default, tabulator will use the standard virtual DOM to ensure that the table can process any number of rows passed to it. This works well for most usage cases, but on tables with a large number of columns, the rendering time for each row can result in sluggish rendering and scroll performance

To get round this Tabulator now has a horizontal virtual DOM that can be enabled in such circumstances. which generates only the visible columns for each row, improving row rendering performance

The horizontal virtual DOM is disabled by default, if you want to enable it you can use the virtualDomHoz option

var table = new Tabulator("#example-table", {
    virtualDomHoz:true, //enable horizontal virtual DOM
});

Compatibility

The horizontal virtual DOM is not compatible with other table features that also work to limit the number of scrollable columns. When these features are enabled, the horizontal virtual DOM will be automatically disabled. These features include:

  • The fitDataTable layout mode
  • Responsive Columns
  • Classic Render Mode

Row Formatters
Use of row formatters with the horizontal DOM is permitted if they only involve styling the row or its cells. Row formatters that manipulate the contents of the row element will likely malfunction when used with the horizontal virtual DOM

Frozen Columns
Use of frozen columns with the horizontal DOM is currently not supported. The horizontal virtual DOM will be automatically disabled if frozen columns are detected. This limitation will be removed in a future release

RTL
Use of RTL text direction with the horizontal DOM is currently not supported. The horizontal virtual DOM will be automatically disabled if RTL detected. This limitation will be removed in a future release

The Future

In this release, this feature needs to be manually enabled, because i am looking to gather some user feedback on the feature before a full roll out, and don't want to force it on every table configuration all at once.

In the 4.9 release this feature will automatically enable itself when the number of columns crosses a threshold when the performance increase is noticeable (around 20-30 columns) with the option to override the automatic decision and force it on or off

ESM Module

The tabulator-tables package now comes with an ESM module to allow support of import statements and take advantage of ESM features like tree-shaking.

import Tabulator from 'tabulator-tables';

Framework Support
If you are using Tabulator with other ESM compatible frameworks the require use of the import statement, you will need to switch to importing Tabulator in this fashion to.

Auto Column Generation

Customising Automatic Column Definitions

By default, columns generated using the autocolumns option will be basic columns with no additional configuration. You can now use the autoColumnsDefinitions option to manipulate the generated column definition array.

The autoColumnsDefinitions option can be used in three different ways.

Callback Function

If you pass a function to the autoColumnsDefinitions option, it will be called when the column definitions have been generated. It will be passed the column definition array for you to manipulate. The callback must return the array of definition objects.

var table = new Tabulator("#example-table", {
    data:tabledata,
    autoColumns:true,
    autoColumnsDefinitions:function(definitions){
        //definitions - array of column definition objects

        definitions.forEach((column) => {
            column.headerFilter = true; // add header filter to every column
        });

        return definitions;
    },
});

Column Definition Array

If you pass an array of column definition objects to the autoColumnsDefinitions option, the properties for each object will be copied over to the generated column definitions.

Objects are matched by field, so you must set the field property for each object in the array.

var table = new Tabulator("#example-table", {
    data:tabledata,
    autoColumns:true,
    autoColumnsDefinitions:[
        {field:"name", editor:"input"}, //add input editor to the name column
        {field:"age", headerFilter:true}, //add header filters to the age column
    ],
});

Definitions will only be applied to columns generated by autocolums, others will be ignored. So you can use this to define options for possible columns, that will only be included if they are needed.

Field Name Lookup Object

If you pass an object to the autoColumnsDefinitions option, it will lookup the definitions for each column, with the field name of the column used as the property name in the object

var table = new Tabulator("#example-table", {
    data:tabledata,
    autoColumns:true,
    autoColumnsDefinitions:{
        name: {editor:"input"}, //add input editor to the name column
        age: {headerFilter:true}, //add header filters to the age column
    },
});

Definitions will only be applied to columns generated by autocolums, others will be ignored. So you can use this to define options for possible columns, that will only be included if they are needed.

Menus

Mobile Devices

When used on mobile devices, context menus are now triggered by long pressing on the element.

Click Events

Click event objects are now passed into the second argument of all menu generator functions

var table = new Tabulator("#example-table", {
    rowContextMenu: function(component, e){
        //component - column/cell/row component that triggered the menu
        //e - click event object

        var menu = [];

        return menu;
    }
});

Left Click Menus

Each of the context menu options now has a left click equivalent.

Cell Menu

As an alternative to the right click context menu, you can also trigger a menu on a left click by using the clickMenu option in the column definition.

//define cell menu
var cellContextMenu = [
    {
        label:"Reset Value",
        action:function(e, cell){
            cell.setValue("");
        }
    },
]

//add header menu in column definition
var table = new Tabulator("#example-table", {
    columns:[
        {title:"Name", field:"name", width:200, clickMenu:cellContextMenu}, //add a left click menu to the cells in this column
    ]
});

Row Menu

As an alternative to the row right click context menu, you can also trigger a menu on a left click by using the rowClickMenu option in the column definition.

var table = new Tabulator("#example-table", {
    rowClickMenu:[
        {
            label:"Delete Row",
            action:function(e, row){
                row.delete();
            }
        },
    ]
});

Group Menu

As an alternative to the group right click context menu, you can also trigger a menu on a left click by using the groupClickMenu table setup option.

var table = new Tabulator("#example-table", {
    groupClickMenu:[
        {
            label:"Hide Group",
            action:function(e, group){
                //e - context click event
                //group - group component for group

                group.hide();
            }
        },
    ]
});

Columns

Column Header Title Alignment

By default column headers are left aligned. To change this, you can now globally set the horizontal text alignment for all cells in the table using the headerHozAlign option:

var table = new Tabulator("#example-table", {
    headerHozAlign:"right", //right align column header titles
});

The property can take one of three values:

  • left - left align column header title
  • center - center align column header title
  • right - right align column header title

If you want to set the horizontal alignment on a column by column basis, you can use the headerHozAlign property in a column's definition:

var table = new Tabulator("#example-table", {
    columns:[
        {title:"Name", field:"name", headerHozAlign:"right"}, //right align column header title
    ],
});

Formatters

Module Formatters

Row Selection

When used as a title formatter, the rowSelection formatter now has an optional rowRange parameter that can be used to set the row range selected when you toggle the header tickbox.

By default all rows in the table are toggled when the title formatter check box is clicked, you can change this by passing a Row Range Lookup value to the rowRange parameter in the column definitions titleFormatterParams option

var table = new Tabulator("#table", {
    columns:[
        {formatter:"rowSelection", titleFormatter:"rowSelection", titleFormatterParams:{
            rowRange:"active" //only toggle the values of the active filtered rows
        }, hozAlign:"center", headerSort:false},
    ],
});

Sorting

Header Sort Icon

You can now customise the icon used for the column header sort by passing in the HTML for the sorting element to the headerSortElement property.

The table will automatically vertically center the icon with the header text. It is worth noting that in order for the table to render correctly, the sorter icon used should not exceed the height of the title text

Two different approaches to customising the sort icon are shown below. Both examples use font awesome icon elements for the sort icon, but you could just as easily add any HTML you like.

Single Vertically Flipping Icon

In this example we will use one icon, and then use some CSS to change its colour and direction depending on the sort.

Using the headerSortElement we will define a single icon for the sorter element:

var table = new Tabulator("#table", {
    headerSortElement:"<i class='fas fa-arrow-up'></i>",
});

And then use CSS to define what it should look like in the different sort direction

/* Define the style when the column is not sorted */
.tabulator-col[aria-sort="none"] .tabulator-col-sorter i{
    color:#999;
}

/* Define the style when the column is sorted in ascending order */
.tabulator-col[aria-sort="asc"] .tabulator-col-sorter i{
    color:#f00;
}

/* Define the style when the column is sorted in descending order */
.tabulator-col[aria-sort="desc"] .tabulator-col-sorter i{
    color:#f00;
    transform: scaleY(-1); /* flip the icon vertically so the arrow points down */
}

Different Icons Depending on Sort Direction

In this example we will define different icons for the unsorterd, ascending and descending sorts, and then use some CSS to change its colour and direction depending on the sort.

Using the headerSortElement we will define a single icon for the sorter element:

var table = new Tabulator("#table", {
    headerSortElement:"<span><i class='fas fa-sort'></i><i class='fas fa-sort-up'></i><i class='fas fa-sort-down'></i></span>",
});

And then use CSS to define what it should look like in the different sort direction

/* Hide all icons by default */
.tabulator-col .tabulator-col-sorter i{
    display: none;
}

/* Display the fa-sort icon when the column is not sorted */
.tabulator-col[aria-sort="none"] .tabulator-col-sorter i.fa-sort{
    display: inline-block;
    color:#999;
}

/* Display the fa-sort-up icon when the column is sorted in ascending order */
.tabulator-col[aria-sort="asc"] .tabulator-col-sorter i.fa-sort-up{
    display: inline-block;
    color:#f00;
}

/* Display the fa-sort-down icon when the column is sorted in descending order */
.tabulator-col[aria-sort="desc"] .tabulator-col-sorter i.fa-sort-down{
    display: inline-block;
    color:#f00;
}

Editing

Handling Home and End Keys In Editors

The input, number and textarea editors have be updated to allow the home and end key events to trigger their normal behaviour of moving the cursor in the text, without triggering the keybindings module to scroll the table.

Data Export

Get Data

The getData function now supports all Row Range Lookup values in its first argument

var data = table.getData("active"); //return currently filtered data

Count Data

The getDataCount function now supports all Row Range Lookup values in its first argument

var rowCount = table.getDataCount("active"); //count only rows that pass the currently filtered data

Get Row Components

The getRows function now supports all Row Range Lookup values in its first argument

var rows = table.getRows("active"); //return currently filtered rows

Row Selection

The selectRow function now supports all Row Range Lookup values in its first argument

table.selectRow("active"); //select all currently active rows

Data Tree

Filtering Child Rows

When you are filtering rows in the table, Tabulator will by default apply the filter to all child rows, showing only child rows that match the filter.

If you would prefer that only the top level rows are filtered and the child rows left unfiltered, you can set the dataTreeFilter option to false in your table constructor:

var table = new Tabulator("#example-table", {
    dataTree:true,
    dataTreeFilter:false, //disable child row filtering
});

Sorting Child Rows

When you are sorting rows in the table, Tabulator will by default apply the sort to all child rows as well.

If you would prefer that only the top level rows are sorted and the child rows left unsorted, you can set the dataTreeSort option to false in your table constructor:

var table = new Tabulator("#example-table", {
    dataTree:true,
    dataTreeSort:false, //disable child row sorting
});

Accessors

Row Component Availability

Accessor Function

A Row Component is now passed into the accessor function

//define custom accessor
var customAccessor = function(value, data, type, params, column, row){
    //value - original value of the cell
    //data - the data for the row
    //type - the type of access occurring  (data|download|clipboard)
    //params - the accessorParams object passed from the column definition
    //column - column component for the column this accessor is bound to
    //row - row component for the row

    return Math.floor(value); //return the new value for the cell data.
}

//column definition
{title:"Tax Owed (£)", field:"tax", accessorParams:{}, accessor:customAccessor}

Accessor Params Function

A Row Component is now passed into the accessorParams function

//define lookup function
function paramLookup(value, data, type, component, row){
    //value - original value of the cell
    //data - the data for the row
    //type - the type of access occurring  (data|download|clipboard)
    //column - column component for the column this accessor is bound to
    //row - row component for the row

    //do some processing and return the param object
    return {param1:"green"};
}

//column definition
{title:"Tax Owed (£)", field:"tax", accessor:customAccessor, accessorParams:paramLookup}

Component Objects

Cell Component

Initial Value Functions

The new getInitialValue function returns the value the cell held when it was first loaded, before any editing took place.

var cellInitialValue = cell.getInitialValue();

The new restoreInitialValue reverts the value of the cell back to its initial value, without triggering any of the cell edit callbacks.

cell.restoreInitialValue();

Calculation Component

The Calc Component object is now available to allow direct manipulation of calculation rows. It is a subset of the Row Component and is used for all calculation rows in the table, it has similar basic functionality to the row component, without a lot of the row specific functionality.

The component provides the following functions:

Get Data

The getData function returns the data object for the row.

var rowData = row.getData();

Get Element

The getElement function returns the DOM node for the row.

var rowElement = row.getElement();

Get Table

The getTable function returns the Tabulator object for the table containing the row.

var table = row.getTable();

Get Cells

The getCells function returns an array of CellComponent objects, one for each cell in the row.

var cells = row.getCells();

Get Cell in Specific Column

The getCell function returns the CellComponent for the specified column from this row.

var cell = row.getCell(column);

Grouping

Change Allowed Group Values

You can now use the setGroupValues function to change the list of allowed values that rows are grouped by. This function has one argument and takes the same values as passed to the groupValues setup option.

table.setGroupValues([["male", "female", "smizmar"]]);

Change Row Group On Cell Edit

Enabling the groupUpdateOnCellEdit option will cause a row to be regrouped when the cell it is grouped by is edited.

var table = new Tabulator("#example-table", {
    groupUpdateOnCellEdit:true, //regroup a row when its groubBy cell is edited
});

Data Reactivity

Data Tree Children

When the dataTree and reactiveData options are both enabled, Tabulator will now reactively monitor the _children array for each row to ensure that using any array manipulation functions like push, unshift, shift, pop and splice will result in the table updating correctly

Themes

Bootstrap 4

Input elements used in column header filters are now styled to match the bootstrap form-control class.

Callbacks

Data Changed Callback

The dataEdited callback has been renamed to dataChanged to better describe its updated functionality, and is now triggered when any data is changed by row or cell edits, updates, deletion or addition.

var table = new Tabulator("#example-table", {
    dataChanged:function(data){},
});

Bug Fixes

V4.8.0 Release

The following minor updates and bugfixes have been made:

  • The active row range lookup option now includes all pages of data when pagination is enabled on the table
  • An error is no longer thrown when an export function is called and the table has a rowFormatter defined
  • The paginationSizeSelector value of true now correctly shows all rows
  • The csv downloader now uses the custom delimiter for column header values when set
  • Column resize handles are no longer present on calculation rows
  • Column calculations no longer error when initialised on small table using responsive collapse
  • Improved object isolation when exporting objects from the table
  • Fixed issue with custom localization text transfering between tables
  • Fixed scoping issue in clearValidation function on cell component
  • The count of edited rows is now updated before the cellEdited event is fired
  • The tickCross editor now correctly starts with focus when used on the Firefox browser
  • Deleted cells are now removed from the history list to prevent errors on undo
  • Right clicking on an editable cell no longer incorrectly triggers the edit
  • Column header height and vertical alignment is now correctly recalculated when a column is deleted or updated
  • The textarea editor now correctly calculates its initial height when it is loaded
  • Row height is now normalized after a cancelled edit on a column with the variableHeight option set or the textarea editor
  • Fixed null comparison issues in the download and clipboard modules
  • Fixed scoping issue for comms function call in xlsx downloader
  • Variable definition issue in Persistence module getGroupConfig function has been fixed

V4.8.1 Release

The following minor updates and bugfixes have been made:

  • Function based column definition properties are no longer eroniously stored by the persistence module
  • The getTable function now works correctly on CalcComponents
  • The rowSelection formatter now correctly renders an empty cell on calculation rows
  • All row management arrays are now cleared down correctly when the table is wiped before new data is loaded
  • Child rows are now correctly reinitialized when columns are moved programatically
  • The getRow function on the CellComponent wrapper object passed into formatters when exported, now works correctly
  • Sub pixel rounding errors in the non-fixed height layout mode when using a zoomed browser have been fixed

V4.8.2 Release

The following minor updates and bugfixes have been made:

  • The scrollToColumn function now works correctly when scrolling to the left of the table
  • Vertically aligned cells are now correctly displayed when made visible after being hidden
  • Export functions now correctly return row data in row formatters
  • Fixed regression where calculation row cells were accidentally calling column formatters instead of their specific calc formatters
  • Fixed regression preventing pasting into empty tables