Version 6.5.0 Released!

Click to checkout the new features

Old Documentation
You are browsing documentation for an old release of Tabulator. Consider upgrading your project to Tabulator 6.x (latest 6.5.0)

Release Notes

Notes for every release in the 4.x line are collected on this page. Newer majors: 6.x, 5.x.

Performance

This update has seen a number of updates focused at improving the performance of the table with large data sets. Nelow is a summary of areas of performance improvement.

Data Loading Performance

Data loading has now been optimised, and you should see around a 3x - 4x reduction in processing times when data is loaded into the table. This will be particularly noticeable data sets with a large number of rows.

Numeric Sorting

The number sorter has been rebuilt to improve performance when working with simple integer and floating point numbers. By default it will no longer try and do any string manipulation on numbers being sorted (eg removing thousand separators etc). This has resulted in a 7x reduction in numeric sort times.

You can still carry out string processing in the number sorter if needed, using the optional thousandSeparator and decimalSeparator properties in the sorters sorterParams.

Calculation Column Scrolling

The column calculation module has been tweaked to improve horizontal scroll performance when column calculation rows are visible.

Cell Container Initialization

Intialization of event binding and styling on cells now happens without the need to generate the cell contents.

ESM Module

Minified File

A new tabulator.es2015.min.js file is available in the /dist/js/ folder, that provides a minified version of the tabulator.es2015.js file.

Menus

Nested Menus

It is now possible to build out more complex menu systems by using nested sub menus. To add a sub menu to an item, set the menu property with an array of menu items.

Sub menus can be nested as many layers deep as you need.

var table = new Tabulator("#example-table", {
    rowContextMenu: [
        {
            label:"Hide Column",
            action:function(e, column){
                column.hide();
            }
        },
        {
            label:"Sub Menu" //sub menu
            menu:[
                {
                    label:"Do Something"
                    action:function(e, column){
                        //do something
                    }
                },
                {
                    label:"Do Something Else"
                    action:function(e, column){
                        //do something else
                    }
                },
                {
                    label:"Deeper Sub Menu", //sub menu nested in sub menu
                    menu:[
                        {
                            label:"Do Another Thing"
                            action:function(e, column){
                                //do another thing
                            }
                        },
                    ]
                }
            ]
        }
    ]
});

Callback Context

All menu generation callbacks now have the Tabulator object for the table passed in as the this context of the callback

var headerMenu = function(component, e)){
    var columns = this.getColumns();
};

Updated Example

The Menus example has been updated to demonstrate the new nested menu functionality as well as a column visibility picker in the column header menu.

Columns

Maximum Column Width

Maximum Column Width

It is possible to set a maximum column width to prevent resizing columns from becoming too wide.

This can be set globally, by setting the columnMaxWidth option to the column width when you create your Tabulator.

var table = new Tabulator("#example-table", {
    columnMaxWidth:300, //maximum column width of 300px
});

This option can be overridden on a per column basis by setting the maxWidth property on the column definition.

{title:"name", field:"name", maxWidth:200} //set maximum column width to 200px

If you have defined the max column width globally using the columnMaxWidth option, then you can disable it on a per column basis by passing the value false to the maxWidth option in the column definition.

var table = new Tabulator("#example-table", {
    columnMaxWidth:300, //maximum column width of 300px
    columns:[
        {title:"name", field:"name", maxWidth:false} //remove max width on this column
    ]
});

Formatters

Image Formatter

The image formattter has a couple of new params to help customise the source URL of the image

URL Prefix

The urlPrefix option prepends a string to the start of the cell value when generating the image src url

{title:"Example", field:"example", formatter:"image", formatterParams:{
    urlPrefix:"http://website.com/images/", //prepend this string to the start of the image url
}}

URL Suffix

The urlSuffix option prepends a string to the start of the cell value when generating the image src url

{title:"Example", field:"example", formatter:"image", formatterParams:{
    urlSuffix:".png",, //append this string to the end of the image url
}}

Editors

Chrome Focus Outline

All themes have been updated to remove the thick black outline applied to focused editors in the latest releases of Chrome.

Select Editor

Keyboard Navigation

You can now navigate the list in the select editor by typing the value you are looking for on the keyboard while the editor is open, the editor will do a string comparison of the typed word against each label to find a label that starts with the typed word and will then scroll to that item.

After 800 milliseconds of inactivity the search word will reset and the next key press will trigger a new search. The search will only work with alphanumeric characters.

Filtering

Refresh Current Filters

You can now trigger a refresh of the current filters using the refreshFilter function. This function will cause the current filters to be run again and applied to the table data.

This is mainly useful when you are using custom filter functions that use variables from outside of Tabulator to determine what is filtered, when these variables change you can then call the refreshFilter function to update the existing filters.

table.refreshFilter();

History

Clear History

The clearHistory function can be used to clear out the current table interaction history.

table.clearHistory();

Column Groups

Horizontal Alignment

By default column group header titles are left aligned. you can now use the headerHozAlign option to change this in a column groups definition:

var table = new Tabulator("#example-table", {
    columns:[
        {title:"Name", field:"name", width:160},
        {
            title:"Work Info",
            headerHozAlign:"center", //center align text in column group header
            columns:[
                {title:"Progress", field:"progress"},
                {title:"Rating", field:"rating"},
            ],
        },
    ],
});

Ajax

ajaxURLGenerator Function Scope

The ajaxURLGenerator function is now called with the scope of the table so you can now access the parent table on the this variable

var table = new Tabulator("#example-table", {
    ajaxURLGenerator:function(url, config, params){
        this //The table this function is being called on
    },
});

Bug Fixes

V4.9.0 Release

The following minor updates and bugfixes have been made:

  • The sortValuesList parameter on the select editor now works correctly for all types of value list.
  • The footer calculation row in the bootstrap4 theme is now correctly styled when the table-dark class is applied to the table.
  • Fixed issue with paginated tables that under certain circumstances caused a "Maximum call stack size exceeded" error in the adjustTableSize function.
  • The fetch error object is now correctly passed to the catch on the setData functions returned promise.
  • Fixed regression in last release that was causing formatters to be fired twice on cells that contained editors.
  • The progress editor now takes account of cell padding when working out the editor value.
  • Fixed issue with column group widths not persisting when column persistence is enabled and table layout mode is set to fitDataFill
  • Column groups now correctly retain all definition options when restored from config persistence.
  • Responsive Collapse columns now correctly pull titles from the localization module.

V4.9.1 Release

The following minor updates and bugfixes have been made:

  • Fixed regression with the select editor causing all values in the list to be displayed as true when the values property of the editorParam object was set to true

V4.9.2 Release

The following minor updates and bugfixes have been made:

  • Missing dependency for gulp-uglify-es has been added to the package.json
  • Fixed regression with excepion being thrown when rendering table in IE
  • Fixed issue with row components not being passed into custom sorter functions
  • Fixed regression in persitance system that was preventing column order from being persisted
  • Using the paginationInitialPage option with remote pagination no longer results in a console warning if the page is not set to 1
  • Removed debug trace command from movable rows module
  • The select editor now correctly handles false values when used as a header filter with multiselect mode enabled
  • The autocomplete editor is now correctly reset when clearFilter is called, so the showListOnEmpty option now functions as expected
  • The built in header filter empty check function now considers headers with a numeric value of 0 to not be empty
  • The dataTreeSelectPropagate option now correctly includes all child rows in the selection, including ones in a currently collapsed parent
  • The setColumnLayout now works when the horizontal DOM is enabled
  • When focusing on an editable cell with the horizontal virtual DOM enabled, the table now correctly scrolls the cell to be visible
  • Fixed regression preventing UI update of selected rows that had yet to be rendered

V4.9.3 Release

The following minor updates and bugfixes have been made:

  • Fixed regression in the setColumnLayout function

Version 4.8 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 transferring 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 erroneously 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 programmatically
  • 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

V4.8.3 Release

The following minor updates and bugfixes have been made:

  • Avg column calculation function casts values to numbers to better handle string values
  • Overriding default options on the tabulator prototype now works correctly for array and object values
  • autocomplete and select editor lists now scroll when navigated using arrow keys
  • Fixed render issue with column headers that have both header menus and editable header titles
  • Calling the update function on a row while it is visible no longer attempts to layout the rows dataTree
  • The clipboardCopyConfig option is now correctly parsed when triggering a copy action
  • The clipboard module now correctly blocks external clipboard triggers after the first call of the copy function
  • The clearEdited function now works regardless of whether validation is enabled or disabled on the table
  • Fixed a regression in vertical header layout mode, sort arrows are now correctly positioned at the top of the column header

V4.8.4 Release

The following minor updates and bugfixes have been made:

  • Fixed an issue where Toggling visibility of a column with the horizontal virtual DOM enabled caused a graphical glitch
  • The table is now correctly redrawn when the addColumn function is used to add a column that contains child columns
  • When a child column is deleted it is now correctly removed from its parent and the parent will remove itself if it now has no children

Version 4.7 Release Notes

Build Tools

With this release of Tabulator the build tools have been updated to use Gulp 4

Commands

To make it easier to build your own version of Tabulator, the build tools are now packaged with the library.

There are now two new build commands for custom builds of your table

Build Code

To run a one off build open a console window in the root folder of Tabulator and run the following command:

npm run build

This command will take all the files in the /src folder and build them into their distribution files in the /dist folder

Watch For Changes

When using the watch command, gulp will watch your source code for changed (when you save a file) and will then automatically run the build command for you.

To run the watcher, open a console window in the root folder of Tabulator and run the following command:

npm run watch

This command will watch all the files in the /src folder and build them into their distribution files in the /dist folder when any of the files change

Build Guide

There is now improved documentation on how to create Custom Tabulator Builds

Layout

A new table layout mode is available that resizes the table container to fit the data

Fit Table and Columns to Data

The fitDataTable layout mode, will set the column widths in the same way as the fitData mode, but it will also then resize the width of the table to match the total width of the columns

var table = new Tabulator("#example-table", {
    layout:"fitDataTable",
});

Downloads

The download module has been completely rebuilt in this release and is now based on the exports module to bring it inline with the clipboard and print modules. This means that a number of the download properties have changed in this release and all downloaders have been redesigned to work with the next Export List mechanic

Download Contents

The download table will contain column header groups, row groups, data trees and column calculations.

You can choose to remove any of these from the output data by setting the values in the printConfig option in the table definition:

var table = new Tabulator("#example-table", {
    downloadConfig:{
    columnHeaders:false, //do not include column headers in downloaded table
    columnGroups:false, //do not include column groups in column headers for downloaded table
    rowGroups:false, //do not include row groups in downloaded table
    columnCalcs:false, //do not include column calcs in downloaded table
    dataTree:false, //do not include data tree in downloaded table
},
});

Availabilitity
Not all downloaders support column header groups, row groups and column calculations, see the documentation for each downloader for full information.

Row Range

By default, only the active rows (rows that have passed filtering) will be included in the download the downloadRowRange option takes a Row Range Lookup value and allows you to choose which rows are included in the download output:

  • visible - Rows currently visible in the table viewport
  • active - Rows currently in the table (rows that pass current filters etc - default)
  • selected - Rows currently selected by the selection module (this includes not currently active rows)
  • all - All rows in the table regardless of filters
var table = new Tabulator("#example-table", {
    downloadRowRange:"selected", //change default selector to selected
});

You can override the downloadRowRange option when downloading a file but passing the Row Range Lookup value into the optional fourth argument of the download function:

table.download("csv", "data.csv", {}, "visible"); //include only rows visible in the table viewport in the download output

Grouped Data
The all option is not available for grouped data. This is because grouping is carried out after filtering in Tabulators data processing pipeline, so only filtered data ever makes it into groups.

Data Trees
The all option is not available for nested data. This is because child row generation is carried out after filtering in Tabulators data processing pipeline, so only filtered data ever makes it into groups.

Column Header Titles

When downloading you may want to apply a different column header title from the one usualy used in the table. You can now do this using the titleDownload column definition option, which takes the same inputs as the standard title property.

var table = new Tabulator("#example-table", {
    columns:[
    {title:"Age", titleDownload:"User Age", field:"age"},
    ]
});

Custom File Formatter

If you want to create a custom file type from the table data then you can pass a function to the type argument, instead of a string value. At the end of this function you must call the setFileContents function, passing the formatted data and the mime type.

//custom file formatter
    var fileFormatter = function(list, options, setFileContents){
    //list - an array of export rows representing one row of data for the table;
    //options - the options object passed from the download function
    //setFileContents - function to call to pass the formatted data to the downloader

    var fileContents = [];

    //iterate over rows
    list.forEach((row) => {
    var item = [];

    switch(row.type){
    case "header":
    //handle header rows

    case "group":
    //handle group header rows

    case "calc":
    //handle calculation rows

    case "row":
    //iterate over the columns in a row
    row.columns.forEach((col) => {
    if(col){
    item.push(col.value);
}
});

fileContents.push(item.join(delimiter));
break;
}
});

//trigger file download, passing the formatted data and mime type
setFileContents(names.join(", "), "text/plain");
}

//trigger file download
table.download(fileFormatter, "test.txt");

Note: You can find out more about data URI's Here.

Export List

The list argument passed into the formatter contains all of the information you should need to layout your table. It is an array of ExportRow objects. Each object represents a row of data in the table arranged in the order they currently appear. You should iterate over this array to built each row of your output data.

ExportRow Object

The ExportRow object has 4 properties to describe the row it represents:

  • type - the type of row, this can have one of 4 values:
    • row - A standard row from the table
    • calc - A calculation row
    • group - A row group header
    • header - a row of column headers (column titles)
  • component - The Component Object for the row or group that the ExporRow represents
  • indent - if the row is either a group or a data tree child, this value contains an integer representing which level the row is on, the greater the number the more indented the row should be
  • columns - an array of ExportColumn objects representing the columns on the row.

It takes the following format

{
    type: "row",
    component: RowComponent,
    indent: 0,
    columns: [ExportColumn, ExportColumn, ExportColumn],
}

The columns property of the ExportRow object contains an array of ExportColumn objects representing the columns on the row. in the case of tables with column groups this array can also include null values representing spaces where columns would have been if not for a neighbouring column taking up multiple columns or rows, such as a column group header. These null values are included to help deal with rowspan and colspan alignment and in most cases can be ignored. (an example of where they can come in useful can be found in the built-in xlsx downloader)

{
    type: "row",
    component: RowComponent,
    indent: 0,
    columns: [null, ExportColumn, ExportColumn, null, ExportColumn],
}

When dealing with group type ExportRow objects the columns array will contain only one ExportColumn that represents the value for the group header row

ExportColumn Object

The ExportColumn object has 5 properties to describe the column it represents:

  • value - The value of the cell or title of the column header
  • width - The width in columns, generally this has a value of 1, but when dealing with grouped column headers this describes how many columns wide the column group should be, in the case of group headers this shows as the number of columns in the table to esure the group header is full width
  • height - The height of the cell in rows, generally this has a value of 1, but when dealing with grouped column headers this describes how rows hight the cell should be to allow for neighbouring grouped columun headers
  • depth - This usually has a value of 1, in the case of grouped column headers, this shows how many levels of child columns the group has
  • component - The Component Object for the column that the ExporColumn represent

For a standard cell in a row it would take the following format:

{
    value: "Bob Monkhouse",
    width: 1,
    height: 1,
    depth: 1,
    component: ColumnComponent,
}

For a column group header containing two child rows it would look like this:

{
    value: "Column Group",
    width: 2, //the group header is two columns wide
    height: 1,
    depth: 2, //the group header is made up of two levels, itself and its children
    component: ColumnComponent,
}

For a column header next to a column group header containing two child rows it would look like this:

{
    value: "Age",
    width: 1,
    height: 2, //the column header has a rowspan of 2 to match the height of the column group next to it
    depth: 1,
    component: ColumnComponent,
}

For a cell representing a group header it would take the following format:

{
    value: "Green", //group header title
    width: 7, //total number of columns in table to ensure column header is full width
    height: 1,
    depth: 1,
    component: GroupnComponent, //component object for the group of the header
}

Group Header

When downloading, you may want to apply a different group header from the one usualy used in the table. You can now do this using the groupHeaderDownload table option, which takes the same inputs as the standard groupHeader property.

var table = new Tabulator("#example-table", {
    groupHeader: function(value, count, data, group){
    return value + "<span style='color:#d00; margin-left:10px;'>(" + count + " item)</span>";
},
groupHeaderDownload: function(value, count, data, group){
return value;
},
});

Passing a value of false into groupHeaderDownload will cause the header to show the groups key as plain text

Columns

Column Widths

The Column Component now provides additional functions for manipulating column width

Get Width

The getWidth function returns the width of the column in pixels

var width = column.getWidth();
Set Width

You can set the width of a column using the setWidth function, passing the width of the column in pixes as an integer as the first argument,

column.setWidth(123); // set the column width to 123 pixels

Passing a value of true to the function will resize the column to fit its contents

column.setWidth(true); // set the column width to fit its contents
Check Visibility

The getVisibility function has now been renamed to isVisible to bring it inline with other funcnctions

var visible = column.isVisible();

Grouping

Check Visibility

The getVisibility function has now been renamed to isVisible to bring it inline with other funcnctions

var visible = group.isVisible();

Trees

Add Child Rows

You can now add child rows to a data tree row using the new addTreeChild function on the Row Component

The first argument should be a row data object. If you do not pass data for a column, it will be left empty. To create a blank row (ie for a user to fill in), pass an empty object to the function.

row.addTreeChild({name:"Billy Bob", age:"12", gender:"male", height:1});

The second argument is optional and determines whether the row is added to the top or bottom of the array of child rows. A value of true will add the row to the top of the array, a value of false will add the row to the bottom of the array. If the parameter is not set the row will be placed according to the addRowPos global option.

row.addTreeChild({name:"Billy Bob", age:"12", gender:"male", height:1}, true); //add child row to the top of the array

If you want to add the row next to an existing row you can pass an optional third argument to the function that will position the new row next to the specified row (above or below based on the value of the second argument). This argument will take any of the standard row component look up options. This must be a row that has the same parent as the row you want to add

row.addTreeChild({name:"Billy Bob", age:"12"}, true, 3); //add new row above existing row with index of 3

Delete Child Row

The delete function on the Row Component has been updated to now handle child and parent rows correctly.

row.delete();

Movable Rows

Moving Rows To Non-Tabulator Elements

Tabulator also allows you to move rows between Tabulator tables and any other non-Tabulator elements on the page. To enable this you should supply either a valid CSS selector string or a DOM node for the elements you wish to be able to connect to to the movableRowsConnectedElements option. if you want to connect to multple tables then you can pass in an array of values to this option.

var table = new Tabulator("#example-table", {
    movableRows: true, //enable movable rows
    movableRowsConnectedElements: "#drop-area", //element to receive rows
});

When you start dragging a row, the tabulator-movingrow-receiving class will be applied to all elements supplied to the movableRowsConnectedElements option, to allow you to highlight any droppable areas.

When a row is dropped on element from from the movableRowsConnectedElements option the movableRowsElementDrop callback will be triggered. You can use this callback to trigger any changes as a result of the drop

var table = new Tabulator("#example-table", {
    movableRows: true, //enable movable rows
    movableRowsConnectedElements: "#drop-area", //element to receive rows
    movableRowsElementDrop:function(e, element, row){
    //e - mouseup event object
    //element - node object for the element that the row was dropped onto
    //row - row component for the row that was moved

    //add a div to the drop element containing the name property from the row data
    var div = document.createElement("div");
    div.textContent = row.getData().name;
    element.appendChild(div);
},
});

Dropping a row in an element will not directly result in the row appearing inside the element, it will simply trigger the movableRowsElementDrop callback, allowing you to the decide the next action.

Filtering

Filter Params

You can now pass a filter params object to an optional fourth argument on the addFilter and setFilter functions:

table.setFilter("tags", "keywords", "red green blue", {matchAll:true});

Built In Filters

New string comparison filters have been added in this release.

Keywords

The keywords filter displays any rows with data containing any space separated words in the specified string (case insensitive)

table.setFilter("colors", "keywords", "red green blue"); //returns rows with a colors filed containing either the word "red", "green", or "blue"

This filter has two optional params:

  • separator - the separator used between words (default " ")
  • matchAll - the row must contain all the keywords to pass the filter
table.setFilter("colors", "keywords", "red green blue", {matchAll:true}); //returns rows with a colors filed containing ALL the words "red", "green" & "blue"
Starts With

The starts filter displays any rows with data that starts with the specified string. (case insensitive)

table.setFilter("name", "starts", "ste");
Ends With

The ends filter displays any rows with data that ends with the specified string. (case insensitive)

table.setFilter("name", "ends", "son");

Editing

Edit History

Editing of cells is now tracked to make it easier to see which cells have been edited

List Edited Cells

You can get a list of all edited cells in the table using the getEditedCells function. this will return an array of Cell Components for each cell that has been edited.

var editedCells = table.getEditedCells()

Tabulator will continue to add cells to this list until the table in the data is replaced by the setData function or the edited list is cleared.

Check if Cell Has Been Edited

You can call the isEdited function on any Cell Component to see if it has been edited. it will return true if it has been edited or false if it has not.

var edited = cell.isEdited()
Clear Edited Cells

You can clear the edited flag on a cell to prevent ir from coming up in edited lists in future

The clearEdited can be called on a Cell Component to clear the edited flag used by the isEdited function and mark the cell as unedited.

cell.clearEdited();

Alternativly, the clearCellEdited can be called on the table to clear the edited flag on all cells in the table

table.clearCellEdited();

Or optionally you can pass in a Cell Component or an array of Cell Components to the clearCellEdited function to clear the edited flag on specific cells

table.clearCellEdited([cell1, cell2]);

Editors

Select Editor Multi-Item selection

The new multiselect option for the select editor will allow users to select multiple items from the select list

{title:"Example", field:"example", editor:"select", editorParams:{
    values:true, //create list of values from all values contained
    multiselect:true, //allow multiple entries to be selected
}}

This option can take two different values:

  • true - a boolean value of true will allow the user to select as many item from the list as they like
  • number - if you set an integer for this option that will set the maximum number of items the user can select, if they try and select more than this, earlier selected items will be deselected

Select Editor List Item Attributes

When using complex values lists for the select editor you can now use the elementAttributes property to specify attributes that should be set on the list items element. In the example below we are setting a class on a list item

{title:"Name", field:"name", editor:"select", editorParams:{
    values:[
    {
        label:"Steve Boberson",
        value:"steve",
        elementAttributes:{
        class:"primary-name",
    }
},
]
}}
Autocomplete Editor Values List

You can now pass an array of objects, to the values option for the autocomplete editor to give you more control over the label, value and order of each item in the list.

{title:"Name", field:"name", editor:"autocomplete", editorParams:{
    values:[
    {
        label:"Steve Boberson",
        value:"steve",
    },
    {
        label:"Bob Jimmerson",
        value:"bob",
    },
    {
        label:"Jenny Jillerson",
        value:"jenny",
    },
    {
        label:"Jill Betterson",
        value:"jill",
    },
    ]
}}

Validation

The validation system has had an overhaul to allow greater flexibility in how you validate your table data.

Validation Modes

There are now three different validation modes available to customise the validation experience:

  • blocking - if a user enters an invalid value while editing, they are blocked from leaving the cell until a valid value is entered (default)
  • highlight - if a user enters an invalid value, then the edit will complete as usual and they are allowed to exit the cell but a highlight is applied to the cell using the tabulator-validation-fail class
  • manual - no vaildation is automatically performed on edit, but it can be triggered by calling the validate function on the table or any Component Object

The validation mode can be set using the validationMode setup option:

var table = new Tabulator("#example-table", {
    validationMode:"highlight", //highlight cells with validation errors but don't stop the edit
});

Highlight Validation

If you are using the highlight validation mode then Tabulator provides a variety of ways to check the validation state of different cells in the table.

Retrieve Invalid Cells

The getInvalidCells method returns an array of Cell Components for all cells flagged as invalid after a user edit.

var invalid = table.getInvalidCells();

Tabulator will continue to add cells to this list until the table in the data is replaced by the setData function or the invalid list is cleared.

Check Cell as Passed Validation

The isValid can be called on a Cell Component to check if a cell has previously passed a validation check without revalidating it.

var valid = cell.isValid();

This will return a value of true if every cell passes validation, or false if it fails validation.

This function is different from the validate function which actively validates the cell, the isValid function only checks to see if a user has edited the cell and that it has passed validation when that happened

Clear Invalid Validation

You can clear the invalid validation state of a cell in a couple of ways.

The clearValidation can be called on a Cell Component to clear the invalid flag used by the isValid function and mark the cell as valid.

cell.clearValidation();

Alternativly, the clearCellValidation can be called on the table to clear the invalid state on all cells in the table

table.clearCellValidation();

Or optionally you can pass in a Cell Component or an array of Cell Components to the clearCellValidation function to clear the invalid state on specific cells

table.clearCellValidation([cell1, cell2]);

Manual Validation

If you are using the manual validation mode then Tabulator provides a variety of ways to trigger validation of the table.

Table Validation

You can validate the whole table in one go by calling the validate method on the table instance.

var valid = table.validate();

This will return a value of true if every cell passes validation, if any cells fail, then it will return an array of Cell Components representing each cell that has failed validation.

Row Validation

You can validate a row by calling the validate method on any Row Component

var valid = row.validate();

This will return a value of true if every cell passes validation, if any cells fail, then it will return an array of Cell Components representing each cell in that row that has failed validation.

Column Validation

You can validate a column by calling the validate method on any Column Component

var valid = column.validate();

This will return a value of true if every cell passes validation, if any cells fail, then it will return an array of Cell Components representing each cell in that column that has failed validation.

Cell Validation

You can validate a cell by calling the validate method on any Cell Component

var valid = cell.validate();

This will return a value of true if every cell passes validation, or false if it param validation.

Built In Validators

New string comparison validators have been added in this release.

Starts With

The starts validator allows string values that start with the parameter (case insensitive)

 {title:"Example", field:"example", validator:"starts:bob"} \\value must start with 'bob'
Ends With

The ends validator allows string values that start with the parameter (case insensitive)

 {title:"Example", field:"example", validator:"ends:green"} \\value must end with 'green'

Formatters

Date Time Formatter

The datetime formatter has a new timezone param that can be used to set the timezone for a date time.

{title:"Example", field:"example", formatter:"datetime", formatterParams:{
    outputFormat:"DD/MM/YY HH:ii",
    timezone:"America/Los_Angeles",
}}

It will accept any valid Moment Timezone. In order to use this property you must include the Moment Timezone library in your project, in addition to moment.js

Pagination

Pagination Size Selector Show All Rows

You can now pass pass a boolean value of true into the paginationSizeSelector array, this will show an "All" option that will show all available rows on one page

var table = new Tabulator("#example-table", {
    pagination:"local",
    paginationSize:10,
    paginationSizeSelector:[10, 25, 50, 100, true], //select list with an "all" option at the end of the list
});

Localization

Pagination Size Selector All Option

With the addition of the "All" option for the paginationSizeSelector, there is now a matching localization property to allow customisation of the wording

var table = new Tabulator("#example-table", {
    langs:{
    "en":{
    "pagination":{
    "all":"All",
},
},
},
});

Pagination Page Button Tooltip Option

There is now a page_title localization property to allow customisation of the wording of the tooltip when hovering over page number buttons

var table = new Tabulator("#example-table", {
    langs:{
    "en":{
    "pagination":{
    "page_title":"Show Page",
},
},
},
});

Frozen Rows

Check Row Frozen State

The isFrozen function on a Row Component will return a boolean representing the current frozen state of the row.

var frozen = row.isFrozen();

Menus

Row Group Header Context Menu

You can now add a right click context menu to row group headers passing an array of menu items to the groupContextMenu option in that columns definition.

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

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

Column Group Header Menus

Column header menus can also be added to column groups using the same headerMenu option, but declared in the column group object

//define row context menu
 var headerMenu = [
    {
        label:"Hide Column",
        action:function(e, column){
            column.hide();
        }
    },
]

//add header menu in column definition
var table = new Tabulator("#example-table", {
    columns:[
        {
            title:"Column Group",
            headerMenu:headerMenu, //add a menu to this column header
            columns:[
                {title:"Name", field:"name", width:200},
                {title:"Age", field:"age", width:200}
            ]
        }
    ]
});

Column Group Header Context Menus

Column header context menus can also be added to column groups using the same headerContextMenu option, but declared in the column group object

//define row context menu
 var headerContextMenu = [
    {
        label:"Hide Column",
        action:function(e, column){
            column.hide();
        }
    },
]

//add header menu in column definition
var table = new Tabulator("#example-table", {
    columns:[
        {
            title:"Column Group",
            headerContextMenu:headerContextMenu, //add a context menu to this column header
            columns:[
                {title:"Name", field:"name", width:200},
                {title:"Age", field:"age", width:200}
            ]
        }
    ]
});

If you declare context menu in both column headers and column group headers then which menu appears will depend on where the user clicks.

Printing

Group Header

When printing you may want to apply a different group header from the one usualy used in the table. You can now do this using the groupHeaderPrint table option, which takes the same inputs as the standard groupHeader property.

var table = new Tabulator("#example-table", {
    groupHeader: function(value, count, data, group){
    return value + "<span style='color:#d00; margin-left:10px;'>(" + count + " item)</span>";
},
groupHeaderPrint: function(value, count, data, group){
return value + "<span style='color:#d00; margin-left:10px;'></span>";
},
});

Passing a value of false into groupHeaderPrint will cause the header to show the groups key as plain text

Column Header Titles

When printing you may want to apply a different column header title from the one usualy used in the table. You can now do this using the titlePrint column definition option, which takes the same inputs as the standard title property.

var table = new Tabulator("#example-table", {
    columns:[
    {title:"Age", titlePrint:"User Age", field:"age"},
    ]
});

Clipboard

Group Header

When copying to clipboard you may want to apply a different group header from the one usualy used in the table. You can now do this using the groupHeaderClipboard table option, which takes the same inputs as the standard groupHeader property.

var table = new Tabulator("#example-table", {
    groupHeader: function(value, count, data, group){
    return value + "<span style='color:#d00; margin-left:10px;'>(" + count + " item)</span>";
},
groupHeaderClipboard: function(value, count, data, group){
return value + "<span style='color:#d00; margin-left:10px;'></span>";
},
});

Passing a value of false into groupHeaderClipboard will cause the header to show the groups key as plain text

Column Header Titles

When copying to clipboard you may want to apply a different column header title from the one usualy used in the table. You can now do this using the titleClipboard column definition option, which takes the same inputs as the standard title property.

var table = new Tabulator("#example-table", {
    columns:[
    {title:"Age", titleClipboard:"User Age", field:"age"},
    ]
});

HTML Output

Group Header

When the getHtml function is called you may want to apply a different group header from the one usualy used in the table. You can now do this using the groupHeaderHtmlOutput table option, which takes the same inputs as the standard groupHeader property.

var table = new Tabulator("#example-table", {
    groupHeader: function(value, count, data, group){
    return value + "<span style='color:#d00; margin-left:10px;'>(" + count + " item)</span>";
},
groupHeaderHtmlOutput: function(value, count, data, group){
return value + "<span style='color:#d00; margin-left:10px;'></span>";
},
});

Passing a value of false into groupHeaderHtmlOutput will cause the header to show the groups key as plain text

Column Header Titles

When the getHtml function is called you may want to apply a different column header title from the one usualy used in the table. You can now do this using the titleHtmlOutput column definition option, which takes the same inputs as the standard title property.

var table = new Tabulator("#example-table", {
    columns:[
    {title:"Age", titleHtmlOutput:"User Age", field:"age"},
    ]
});

Polyfills

The built in polyfills.js file has bee updated to include pollyfils for the Array.includes, String.includes and Object.assign functions

Bug Fixes

V4.7.0 Release

The following minor updates and bugfixes have been made:

  • Component objects are now singletons to improve memory efficiency and processing speed
  • The autocomplete editor no longer lags when typing when the values property is set to true and the table has a lot of rows
  • The tabNewEndRow option now works correctly when passing in an object as its value.
  • Sorters and formatters involving time, now accept 24 hour time formats by default rather than 12 hour
  • The setPage function now correctly handles the special values of first, next, prev and last
  • The range editor is now correctly exited when using tab or shift+tab keys
  • Escape key can now be used to exit context menus
  • Left and right arrow keys can now be used to move the cursor in the autocomplete editor
  • Fixed issue with star editor where it wasnt loosing focus after a successful edit, preventing the next edit
  • The dataSorted callback is now passed the correct row components when used on a table using data trees

V4.7.1 Release

The following minor updates and bugfixes have been made:

  • cell context menu propagation to row context menu is no longer blocked when the cell context menu generation function returns false
  • select header filter in multiselect mode can now be cleared of value by clicking the cross on the input element
  • values for the select header filter in multiselect mode now persist correctly between edits of the filter value
  • typing in the select header filter in multiselect mode is now blocked
  • fixed regression in select header filter when in single value mode, values can now be correctly selected
  • values are now correctly parsed into select editor on initialization
  • deleting cells no longer causes error if validation is not enabled
  • when deleting cells make sure they are attached to a parent before attempting to remove them
  • the validationFailed callback is now triggered when validation fails in highlight validation mode

V4.7.2 Release

The following minor updates and bugfixes have been made:

  • The table is now horizontally shifted into focus when a cell is being edited
  • A regression with the setDataFromLocalFile function has been fixed
  • Row components are now correctly detached from table modules before being wiped on new table data
  • The dataLoaded callback is now triggered after the table has been rendered when new data is loaded into the table
  • The autocomplete editor now correctly loads its initial value when used as a header filter

Version 4.6 Release Notes

Table Height

In this release the virtual DOM has undergone some upgrades to make it easier to use the table in a variety of scenarios.

In scenarios where there is no height set on the table the Virtual DOM will now be used where instead it used to revert to classic render mode. This should have a range of benefits, making variable height tables easier and smoother to use, and allowing for tables to expand to show all their rows until they overflow their parent, then moving to using a vertical scroll bar.

This section take you through the different approaches to setting table height properties and the pros and cons of each.

Fixed Height Tables

Tabulator works most efficiently when the table has a fixed height, either defined in the CSS for the element or set it using the height option in the table constructor, this can be set to any valid CSS value

var table = new Tabulator("#example-table", {
    height:"100%",
});

By setting the height on the table, you allow Tabulator's virtual DOM to optimize the tables memory and processor usage. It does this by only rendering the rows you see in the table (plus a few above and below the current view) and creates and destroys the rows as you scroll through the table.

This allows tabulator to handle thousands of rows with no overhead as it only processes the information it needs to display.

If a height is set on the table then it will display vertical scroll bars when the number of row exceeds the table height. If there are less rows than the height of the table then the background of the table will be visible.

Variable Height Tables

If you would rather that your table takes up as much space as is needed to show all the available rows, then simply don't specify a height on your table element or in your table constructor.

Without a height the table will keep expanding to fit the number of available rows and will never display a vertical scroll bar.

Slow Rendering: It is worth noting that if you are loading a lot of rows into your table without a height set then it may result is blocking of the browser and slow render speeds as it takes a lot of memory to draw 100's of rows onto the screen.

Maximum Table Height

With a variable table height you can set the maximum height of the table either defined in the max-height CSS property for the element or set it using the maxHeight option in the table constructor, this can be set to any valid CSS value

var table = new Tabulator("#example-table", {
    maxHeight:"100%", //do not let table get bigger than the height of its parent element
});

By setting this you can allow your table to expand to fit the data, but not overflow its parent element. When there are too many rows to fit in the available space, the vertical scroll bar will be shown. This has the added benefit of improving load times on larger tables

Full Height Tables

If you are creating a table that has no height or maximum height and you want it to show all rows without a scroll bar, then it is advisable to disable the Vitrual DOM as the table will become inefficient if it tries to virtuallymanage a table where all rows are visible. To do this you can set the virtualDom option to false to force classic rendering.

var table = new Tabulator("#example-table", {
    virtualDom:false, //disable virtual DOM rendering
});

Though it should be noted that using a table in this way with a large number of rows will result in poor performance

Minimum Table Height

With a variable table height you can set the minimum height of the table either defined in the min-height CSS property for the element or set it using the minHeight option in the table constructor, this can be set to any valid CSS value

var table = new Tabulator("#example-table", {
    minHeight:300, //do not let table get smaller than 300 px heigh
});

Advanced Options

There are many scenarios in which you many need to tweak the way the virtual DOM works or disable it all together. For example tables with significantly varying row height, or very large data sets.

In these cases, have a read of the Virtual DOM Documentation to find out more.

Disabling the Virutal DOM

The classic render mode is also still available to those that wish to use it, but now it can only be enabled by explicitly disabling the virtual DOM

var table = new Tabulator("#example-table", {
    virtualDom:false, //disable virtual DOM rendering
});

For more information on the effect of disabling the virtual DOM please read the Virtual DOM Documentation

Menus

Tabulator now has a range of options for providing context menus and header menus on a table.

In the example below the headerMenu column definition option is used to add a menu to column headers, and the rowContextMenu option is used to add a right click context menu to rows.

Menu Items

Each menu option accepts an array of menu item objects, with each object representing an item in the menu

var table = new Tabulator("#example-table", {
    rowContextMenu: [
        {
            label:"Hide Column",
            action:function(e, column){
                column.hide();
            }
        },
        {
            separator:true,
        },
        {
            disabled:true,
            label:"Move Column",
            action:function(e, column){
                column.move("col");
            }
        }
    ]
});
Labels

The label is a mandatory property for standard menu items and sets the display text for the item

This property can take either a string, HTML or a DOM Node for the labels contents

{
    label:"Hide Column",
}

Alternativly you can pass a function to this property which will be called when the menu is loaded. A Component for the column/cell/row that triggered the menu will be passed in as the first argument. The function should return the contents for the label as outlined above.

{
    label:function(component){
        //component - column/cell/row component that triggered the menu

        return "Delete " . component.getData().name; //customise menu contents with row data
    },
}
Action

The action is a mandatory property for standard menu items and sets a callback that will be triggered when the menu item is clicked

The first argument is the event object for the click event on the menu item. The second argument will be a column/cell/row Component for the component that triggered the menu

{
    action:function(e, component){
        //e - click event from the menu item click
        //component - column/cell/row component that triggered the menu

        return component.delete(); //delete the row the context menu was loaded on
    },
}
e action this is a callback that will be triggered if the user clicks on the menu item, it is passed two arguments

Columns of the table can be set as editable using the editor property in the column definition. (see Define Columns for more details).

Disabled Items

You can disable a menu item by setting the disabled property to true on the item. This will grey out the item in the menu and prevent the user from clicking on it

{
    disabled:true,
}

Alternativly you can pass a function to this property which will be called when the menu is loaded. A Component for the column/cell/row that triggered the menu will be passed in as the first argument. The function should return a boolean to indicate the status of the item, a value of true will disable the item, a value of false will enable the item.

{
    label:function(component){
        //component - column/cell/row component that triggered the menu

        return !component.getData().approved; //disable the menu item if the row data approved property is true
    },
}
Separators

You can add a horizontal separator to a list of menu items by including an object with the separator property set to true

{
    separator:true,
}

Menu Items Generator Function

If you would prefer to generate your menu item layout when the menu is opened you can pass a callback function to any of the menu options.

A Component for the column/cell/row that triggered the menu will be passed in as the first argument. The function should return an array of menu objects for the menu.

If the function returns a value of false or an empty array, the menu will not be shown

var table = new Tabulator("#example-table", {
    rowContextMenu: function(component){

        var menu = [];

        if(!component.getData().approved){
            menu.push({
                label:"Approve User",
                action:function(e, column){
                    component.update({"approved":true});
                }
            })
        }else{
            menu.push({
                label:"Unapprove User",
                action:function(e, column){
                    component.update({"approved":false});
                }
            })
        }

        return menu;
    }
});

Column Header Menus

You can add a menu to any column by passing an array of menu items to the headerMenu option in that columns definition.

Adding a header menu will cause a button to appear to the left of the column header title. clicking on this button will open the menu.

//define row context menu
var headerMenu = [
    {
        label:"Hide Column",
        action:function(e, column){
            column.hide();
        }
    },
]

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

Column Header Context Menus

You can add a right click context menu to any column by passing an array of menu items to the headerContextMenu option in that columns definition.

//define row context menu
var headerContextMenu = [
    {
        label:"Hide Column",
        action:function(e, column){
            column.hide();
        }
    },
]

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

Column Cell Context Menus

You can add a right click context menu to any columns cells by passing an array of menu items to the contextMenu option in that columns definition.

//define row context 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, contextMenu:cellContextMenu}, //add a context menu to the cells in this column
    ]
});

Row Context Menus

You can add a right click context menu to any columns cells by passing an array of menu items to the contextMenu option in that columns definition.

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

Data Trees

Calculations for Data Trees

When you are using the dataTree option with your table, the column calculations will by default only use the data for the top level rows and will ignore any children.

To include child rows in the column calculations set the dataTreeChildColumnCalcs option to true in the table constructor

var table = new Tabulator("#example-table", {
    dataTree:true, //show data in a tree structure
    dataTreeChildColumnCalcs:true, //include child rows in column calculations
});

Visible Children Column calculations will only include the child rows if their tree branch is open, hidden rows on closed branches are not included in calculations.

Child Row Selection

If you are using data trees in a table that also has row selection enabled, the default behaviour will be for selection of each row to be toggled individually as the user clicks on it.

You can now cause the selection/deselection to propagate down to the child rows as well. To do this, set the dataTreeSelectPropagate option to true in the table constructor.

var table = new Tabulator("#example-table", {
    dataTree:true,
    dataTreeSelectPropagate:true, //propagate selection events from parent rows to children
});

Child Row Styling

Each child row is now assigned a class based on its level in the tree. This allows you to differentiate between different tree levels by styling their classes.

For example, all first level children will be assigned the class tabulator-tree-level-1

Open State Update Persistence

Rows will now correctly maintain their open state when they are updated by the update, updateData and replaceData functions

Print Output

Data tree formatting is now included in print output as standard.

If you don't want data trees or child rows displayed in the print output, then you can set the dataTree property to false in the prettyprint setup option:

var table = new Tabulator("#example-table", {
    printConfig:{
        dataTree:false, //do not include data tree in printed table
    },
});

HTML Output

Data tree formatting is now included as standard in the HTML output generated from the getHtml function.

If you don't want data trees or child rows displayed in the HTML output, then you can set the dataTree property to false in the htmlOutputConfig setup option:

var table = new Tabulator("#example-table", {
    htmlOutputConfig:{
        dataTree:false, //do not include data tree in HTML table
    },
});

Clipboard Output

Data tree formatting is now included in clipboard output as standard.

If you don't want data trees or child rows displayed in the clipboard output, then you can set the dataTree property to false in the prettyprint setup option:

var table = new Tabulator("#example-table", {
    clipboardCopyConfig:{
        dataTree:false, //do not include data tree in clipboard table
    },
});

Cell Alignment

The cell contents alignment system has been upgraded in this release, to allow setting of cell alignment on a global scale and to allow vertical alignment of cell contents

Horizontal Alignment

By default table cells have the same horizontal alignment as the containing element for the table. To change this, you can now globally set the horizontal text alignment for all cells in the table using the cellHozAlign option:

var table = new Tabulator("#example-table", {
    cellHozAlign:"center", //center align cell contents
});

The property can take one of three values:

  • left - left align cell contents
  • center - center align cell contents
  • right - right align cell contents

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

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

Vertical Alignment

By default table cells are vertically aligned to the top of the cell. You can now globally set the vertical text alignment for all cells in the table using the cellVertAlign option:

var table = new Tabulator("#example-table", {
    cellVertAlign:"middle", //vertically center cell contents
});

The property can take one of three values:

  • top - align cell contents to the top
  • middle - align cell contents to the middle
  • bottom - align cell contents to the bottom

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

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

Editors

Text Input Masking

Built in editors based on input elements such as the input, number, textarea and autocomplete editors have the ability to mask the users input to restrict it to match a given pattern.

This can be set by passing a string to the the mask option in the columns editorParams

{title:"Name", field:"name", editor:"input", editorParams:{mask:"AAA-999"}}

Each character in the string passed to the mask option defines what type of character can be entered in that position in the editor.

  • A - Only a letter is valid in this position
  • 9 - Only a number is valid in this position
  • * - Any character is valid in this position
  • Any other character - The character in this position must be the same as the mask

For example, a mask string of "AAA-999" would require the user to enter three letters followed by a hyphen followed by three numbers

Autofill Fixed Characters

If you are using fixed characters in your mask (any character other that A, 9 or *), then you can get the mask to automatically fill in these characters for you as you type by setting the maskAutoFill option in the editorParams to true

{title:"Name", field:"name", editor:"input", editorParams:{
    mask:"AAA-999",
    maskAutoFill:true,
}}
Custom Pattern Characters

If you want to use the characters A, 9 or * as fixed characters then it is possible to change the characters looked for in the mask by using the maskLetterChar, maskNumberChar and maskWildcardChar options in the editorParams

{title:"Name", field:"name", editor:"input", editorParams:{
    mask:"A!!-9BBB$",
    maskLetterChar:"B",
    maskNumberChar:"!",
    maskWildcardChar:"$",
}}

In the example the above the input would be masked with the first character being "A" followed by two numbers, followed by a hyphen, followed by the number "9", followed by three numbers, followed by any character

Autocomplete Editor

The autocomplete editor has had a complete rebuild in this release to offer a range of new functions

Search Function

The searchFunc callback will now receive a values array that matches the one provided to the values property of the editor params, and should return an array or object that is formatted to be one of the valid values types.

searchFunc:function(term, values){ //search for exact matches
    var matches = []

    values.forEach(function(item){
        if(item === term){
            matches.push(item);
        }
    });

    return matches;
},

The searchFunc can now also return a promise, to allow for asynchronous value searching, the promise should resolve with a valid value list when ready

searchFunc:function(term, values){
    return new Promise((resolve, reject) => {
        //fetch list items from server
        fetch("http://test.com?search=" + term)
        .then((response){
            resolve(response.json()); //parse json response and resolve promise
        });
    });
},
Searching Placeholder

If you return a promise from the searchFunc callback then a "Searching..." placeholder will be displayed until the promise resolved.

You can customise this placeholder using the searchingPlaceholder option. It will accept either a string, and HTML string or a DOM Node for the contents of the placeholder

searchingPlaceholder:"Filtering ...", //set the search placeholder to "Filtering ..."
Empty Placeholder

If no results match the term searched for by your user, then an empty list will be displayed. In this circumstance it is possible to display place holder to the user to let them know what has happened

You can customise this placeholder using the emptyPlaceholder option. It will accept either a string, and HTML string or a DOM Node for the contents of the placeholder

emptyPlaceholder:"(no matching results found)", //set the empty list placeholder

Clipboard

The clipboard module has been rebuilt in this release to use the export module for content generation. This allows all exported data to come from one place making it easier to maintain. As a result of this there have been several changes to the functionality of the module in this release.

Clipboard Contents

By default Tabulator includes column headers, row groups data trees and column calculations in the clipboard output.

You can choose to remove column headers groups, row groups or column calculations from the output data by setting the values in the clipboardCopyConfig option in the table definition:

var table = new Tabulator("#example-table", {
    clipboardCopyConfig:{
        columnHeaders:false, //do not include column headers in clipboard output
        columnGroups:false, //do not include column groups in column headers for printed table
        rowGroups:false, //do not include row groups in clipboard output
        columnCalcs:false, //do not include column calculation rows in clipboard output
        dataTree:false, //do not include data tree in printed table
    },
});

Show Unformatted Cell Values

Quite often graphical formatters like progress or star do not copy and paste well into spreadsheet applications. If you use these formatters you can set the formatCells property to false in the clipboardCopyConfig option to show only raw unformatted cell values in the clipboard output:

var table = new Tabulator("#example-table",  {
    clipboardCopyConfig:{
        formatCells:false, //show raw cell values without formatter
    },
});

Row Range

The clipboardCopyRowRange option takes a Row Range Lookup value and allows you to choose which rows are included in the clipboard output:

  • visible - Rows currently visible in the table viewport
  • active - Rows currently in the table (rows that pass current filters etc)
  • selected - Rows currently selected by the selection module (this includes not currently active rows)
  • all - All rows in the table regardless of filters

Copy Formatter

You can alter the finished output to the clipboard using the clipboardCopyFormatter callback. The callback function receives two arguments, the first is a string representing the type of content to be formatted (either "plain" or "html" depending on the type of data entering the clipboard). The second argument is the string that is about to be inserted into the clipboard. The function and should return a string that will be inserted into the clipboard:

var table = new Tabulator("#example-table", {
    clipboardCopyFormatter:function(type, output){
        //type - a string representing the type of the content, either "plain" or "html"
        //output - the output string about to be passed to the clipboard

        if(type == "plain"){
            output += "/n Copyright Bob Green 2020";
        }

        return output;
    }
});

These selectors can also be used when programmatically triggering a copy event. in this case if the selector is not specified it will default to the value set in the clipboardCopyRowRange property (which is active by default).

var table = new Tabulator("#example-table", {
    clipboardCopyRowRange:"selected", //change default selector to active
});

Data Trees

Data tree formatting is now included in clipboard output as standard.

If you don't want data trees or child rows displayed in the clipboard output, then you can set the dataTree property to false in the prettyprint setup option:

var table = new Tabulator("#example-table", {
    clipboardCopyConfig:{
        dataTree:false, //do not include data tree in clipboard table
    },
});

Formatters

Cell Formatters

When copying to the clipboard you may want to apply a different formatter from the one usualy used to format the cell, you can do this using the formatterClipboard column definition option.

You can use the formatterClipboardParams to pass in any additional params to the formatter

These properties take the same inputs as the standard formatter property

//define clipboard formatter
function clipboardFormatter(cell, formatterParams, onRendered){
    return cell.getValue() ? "YES" : "NO";
}

//column definition
{title:"Driver", field:"driver", formatter:"tickCross", formatterClipboard:printFormatter} //show "YES"/"NO" in the cell when copying to the clipboard

Passing a value of false into the formatter will cause the value to be shown as plain text without a formatter

Row Formatter

When copying to the clipboard you may want to apply a different formatter from the one usualy used to format the row. You can now do this using the rowFormatterClipboard table option, which takes the same inputs as the standard rowFormatter property.

var table = new Tabulator("#example-table", {
    rowFormatter:function(row){
        //row - row component

        var data = row.getData();

        if(data.col == "blue"){
            row.getElement().style.backgroundColor = "#1e3b20";
        }
    },
    rowFormatterClipboard:function(row){
        //row - row component

        var data = row.getData();

        if(data.col == "blue"){
            row.getElement().style.backgroundColor = "#0000ff"; //use a different shade of blue background when copying to the clipboard
        }
    },
});

Passing a value of false into the formatter prevent the default row formatter from being run when the table is copied to the clipboard

Printing

Styled Printing Option

The printCopyStyle option has been renamed to printStyled to improve naming consistency accross export options

var table = new Tabulator("#example-table", {
    printStyled:true, //copy Tabulator styling to HTML table
});

Remove Column Headers

You can now remove column headers in the printed output by setting the columnHeaders property to false in the printConfig option:

var table = new Tabulator("#example-table",  {
    printConfig:{
        columnHeaders:false, //do not include column headers in printed table
    },
});

Show Unformatted Cell Values

In certain situations you may want to print the raw unformatted cell value instead of any graphical formatters, to do this, set the formatCells property to false in the printConfig option:

var table = new Tabulator("#example-table",  {
    printConfig:{
        formatCells:false, //show raw cell values without formatter
    },
});

Row Range

By default, only the rows currently visible in the table viewport will be added to the HTML table, the printRowRange option takes a Row Range Lookup value and allows you to choose which rows are included in the print output:

  • visible - Rows currently visible in the table viewport
  • active - Rows currently in the table (rows that pass current filters etc)
  • selected - Rows currently selected by the selection module (this includes not currently active rows)
  • all - All rows in the table regardless of filters
var table = new Tabulator("#example-table", {
    printRowRange:"selected", //change default selector to selected
});
Custom Row Range

For custom row ranges it is also possible to pass a function into the printRowRange option that should return an array of Row Components:

var table = new Tabulator("#example-table", {
    printRowRange:function(){
        //only copy rows to print where the age is over 18
        return this.getRows().filter((row) => {
            return row.getData().age > 18;
        });
    },
});

Accessors

You can use the accessorPrint and accessorPrintParams options on a column definition to alter the value of data in a column before it is printed.

The example below will transform all ages into a boolean, showing if they are over 18 or not. The accessorPrintParams is used to pass the age limit to the accessor so the same accessor function can be used on multiple columns with different age limits:

var ageAccessor = function(value, data, type, params, column){
    return value >= params.legalAge;
}

{title:"Under Age", field:"age", accessorPrint:ageAccessor, accessorPrintParams:{legalAge:18} }

Full details of how accessors work can be found in the Accessors Documentation.

Programatic Printing

The first argument of the print function has been changed to now be a Row Range Lookup value to allow a wider range of row configurations to be included in the print output

table.print("active");

Formatter onRendered Callback

The onRendered callback for formatters is now triggered when formatters are called to build the HTML output for printing or the output of the getHTML function.

Because there is no way to know when the HTML generated by this functionality is actualy visible as it is never added to the DOM, the onRendered function is triggered as soon as the formatter returns its contents, which may result in a malfunction for some custom formatters.

If you need your custom formatter to behave differently under these circumstances, you can perform the following check on the cell variable passed into the formatter to see if you need to take any specific action

onRendered(function(){
    if(!(cell instanceof CellComponent)){
        // formatter being called for print or getHTML output
    }
}

Data Trees

Data tree formatting is now included in print output as standard.

If you don't want data trees or child rows displayed in the print output, then you can set the dataTree property to false in the prettyprint setup option:

var table = new Tabulator("#example-table", {
    printConfig:{
        dataTree:false, //do not include data tree in printed table
    },
});

Formatters

Cell Formatters

When printing you may want to apply a different formatter from the one usualy used to format the cell, you can do this using the formatterPrint column definition option.

You can use the formatterPrintParams to pass in any additional params to the formatter

These properties take the same inputs as the standard formatter property

//define print formatter
function printFormatter(cell, formatterParams, onRendered){
    return cell.getValue() ? "YES" : "NO";
}

//column definition
{title:"Driver", field:"driver", formatter:"tickCross", formatterPrint:printFormatter} //show "YES"/"NO" in the cell when printing

Passing a value of false into the formatter will cause the value to be shown as plain text without a formatter

Row Formatter

When printing you may want to apply a different formatter from the one usualy used to format the row. You can now do this using the rowFormatterPrint table option, which takes the same inputs as the standard rowFormatter property.

var table = new Tabulator("#example-table", {
    rowFormatter:function(row){
        //row - row component

        var data = row.getData();

        if(data.col == "blue"){
            row.getElement().style.backgroundColor = "#1e3b20";
        }
    },
    rowFormatterPrint:function(row){
        //row - row component

        var data = row.getData();

        if(data.col == "blue"){
            row.getElement().style.backgroundColor = "#0000ff"; //use a different shade of blue background when printing
        }
    },
});

Passing a value of false into the formatter prevent the default row formatter from being run during print

HTML Output

Row Range

The first argument of the getHtml function now takes a Row Range Lookup value that determines which rows are included in the HTML table.

var htmlTable = table.getHtml("visible", true, {columnGroups:false}); //get styled html for visible rows of table that copies the table style without grouped column headers

Remove Column Headers

You can now remove column headers in the HTML output by setting the columnHeaders property to false in the htmlOutputConfig option:

var table = new Tabulator("#example-table",  {
    htmlOutputConfig:{
        columnHeaders:false, //do not include column headers in HTML table
    },
});

Show Unformatted Cell Values

In certain situations you may want to include the raw unformatted cell value instead of any graphical formatters, to do this, set the formatCells property to false in the htmlOutputConfig option:

var table = new Tabulator("#example-table",  {
    htmlOutputConfig:{
        formatCells:false, //show raw cell values without formatter
    },
});

Data Trees

Data tree formatting is now included as standard in the HTML output generated from the getHtml function.

If you don't want data trees or child rows displayed in the HTML output, then you can set the dataTree property to false in the htmlOutputConfig setup option:

var table = new Tabulator("#example-table", {
    htmlOutputConfig:{
        dataTree:false, //do not include data tree in HTML table
    },
});

Accessors

You can use the accessorHtmlOutput and accessorHtmlOutputParams options on a column definition to alter the value of data in a column before the html is generated.

The example below will transform all ages into a boolean, showing if they are over 18 or not. The accessorHtmlOutputParams is used to pass the age limit to the accessor so the same accessor function can be used on multiple columns with different age limits:

var ageAccessor = function(value, data, type, params, column){
    return value >= params.legalAge;
}

{title:"Under Age", field:"age", accessorHtmlOutput:ageAccessor, accessorHtmlOutputParams:{legalAge:18} }

Formatters

Cell Formatters

When the getHtml function is called you may want to apply a different formatter from the one usualy used to format the cell, you can do this using the formatterHtmlOutput column definition option.

You can use the formatterHtmlOutputParams to pass in any additional params to the formatter

These properties take the same inputs as the standard formatter property

//define html formatter
function htmlFormatter(cell, formatterParams, onRendered){
    return cell.getValue() ? "YES" : "NO";
}

//column definition
{title:"Driver", field:"driver", formatter:"tickCross", formatterHtmlOutput:htmlFormatter} //show "YES"/"NO" in the cell when the getHtml function is called

Passing a value of false into the formatter will cause the value to be shown as plain text without a formatter

Row Formatter

When the getHtml function is called you may want to apply a different formatter from the one usualy used to format the row. You can now do this using the rowFormatterHtmlOutput table option, which takes the same inputs as the standard rowFormatter property.

var table = new Tabulator("#example-table", {
    rowFormatter:function(row){
        //row - row component

        var data = row.getData();

        if(data.col == "blue"){
            row.getElement().style.backgroundColor = "#1e3b20";
        }
    },
    rowFormatterHtmlOutput:function(row){
        //row - row component

        var data = row.getData();

        if(data.col == "blue"){
            row.getElement().style.backgroundColor = "#0000ff"; //use a different shade of blue background when the getHtml function is called
        }
    },
});

Passing a value of false into the formatter prevent the default row formatter from being run ont the output table

Download

Data Trees

Data tree formatting is now included as standard in downloads.

If you don't want data trees or child rows displayed in the HTML output, then you can set the dataTree property to false in the downloadConfig setup option:

var table = new Tabulator("#example-table", {
    downloadConfig:{
        dataTree:false, //do not include data tree in download
    },
});

Frozen Columns

Frozen Column Groups

You can now freeze an entire column group by using the frozen property in the parent group definition

var table = new Tabulator("#example-table", {
    [
        {
            title:"Column Group",
            frozen:true, //frozen column group on left of table
            columns:[
                {title:"Name", field:"name"},
                {title:"Age", field:"age"},
            ]
        },
        {title:"Eye Colour", field:"eyes"},
        {title:"Height", field:"height", frozen:true}, //frozen column on right of table
    ]
});

Note: You cannot freeze individual columns in a column group, either the entire group is frozen or none of the columns are

Auto Columns

Sort/Filter Persistence on Update

The automatic column generation system, enabled using the autoColumns setup option has been improved.

Triggering an ajax request using sort, filter or pagination actions will no longer cause a regeneration of the columns, so existing sorting/filters are no longer reset when any of these actions are performed.

Filters

Real Time Header Filter Delay

when using real time header filtering, Tabulator will wait 300 milliseconds after a keystroke before triggering the filter. You can customise this delay by using the headerFilterLiveFilterDelay table setup option:

var table = new Tabulator("#example-table", {
    headerFilterLiveFilterDelay:600, //wait 600ms from last keystroke before triggering filter
});

Get Header Filter Value

You get the current header filter value of a column by calling the getHeaderFilterValue function, This function takes any of the standard column component look up options as its first argument.

var filterValue = table.getHeaderFilterValue("name"); //get the header filter value for the name column

Alternatively if you have the Column Component of the column containing the header filter, you can call the getHeaderFilterValue function directly on the component.

var filterValue = column.getHeaderFilterValue() //get the header filter value for this column

Column Calculations

Manual Recalculation

You can now manually trigger recalculation of column calculations by calling the recalc function on the table

table.recalc(); //recalculate all column calculations

Key Bindings

The keybindings module can now detect use of the meta key as well as shift and ctrl

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

Bug Fixes

V4.6.0 Release

The following minor bugs have been fixed:

  • The html table export module now correctly maps cell text alignment per column
  • Fixed issue with updateColumnDefinition function not updating the column
  • The rowSelectionChanged callback is now only triggered once when a row is selected with a selectableRandeMode of "click"
  • Text and number editors now use strict comparison to measure value change to prevent issues when setting an empty cell to 0
  • Fixed regression with the mutatorClipboard mutator
  • The "prev" and "next" pagination buttons now correctly persist the current page number when persistant config is in use
  • The regression in the "cookie" persistence mode has been resolved
  • The rowSelection title formatter now correctly updates on row deletion
  • Fixed alignment issue on column calc redraw when using fronzen columns
  • Ghost nested object structures are no longer created in row data if a column's field is set to a nested object property that does not exist in the row data
  • When grouped columns are moved thier updated order is now correctly recorded with the partent column group
  • Column group titles are now correctly sized to match the total widths of the child columns when nested column groups are used
  • Hidding the last column in a column group will no longer result in a 1px right shift occurring in neighborough column headers
  • The tabEndNewRow functionality now works in Firefox and Edge browsers
  • calling the clearHeaderFilter function no longer results in extra ajax calls when filters are next used
  • Row numbers now remain in order when moving, adding or deleting rows
  • Input editors now behave correctly when selecting text with a double click
  • Empty table placeholder heights are now respected on tables without a height defined
  • Bulk undoing of of repeated row deletion now works correctly
  • When running concurrent ajax requests the loading element will not be hidden until all requests have completed
  • Fixed row position issues when using history module to undo or redo a row move
  • Warnings are no longer shown in the console when building a Tabulator from an HTML table with camel case tabulator attributes
  • Ajax sorting or filtering no longer resets the horizontal scroll position of the table

V4.6.1 Release

The following minor bugs have been fixed:

  • Removing row grouping during table use, now correctly propagates to download module
  • The table no longer causes a console error if it is created on an element that is not attached to the DOM
  • Fixed regression in autocomplete editor, it now correctly retains old value when blurring with invalid value
  • The deleteRow function will now delete rows in the order they appear in the table to allow for smoother more predictable undo functionality

V4.6.2 Release

The following minor bugs have been fixed:

  • Fixed issue with object pointer isolation when either paginationDataSent or paginationDataReceived options are used in multiple tables on the same page
  • Improved sorter performance with multi-column sorts
  • Context menu will now load in correct position when page contents does not take up the full viewport height
  • Fixed styling issue with modern theme when frozen columns were in use
  • The scroll bar on the options lists for the select and autocomplete editors now works correctly on Internet Explorer
  • When paginating data without the paginationSize option set on a fixed height table, the styling of the rows is taken into consideration when calculating the correct page size.
  • Navigating the table up and down through editable cells no longer causes editable rows out of view to jump to the center of the table when they gain focus
  • Virtual DOM buffer is now correctly maintained when scrolling from the top and bottom edges of the table. This will prevent visual glitches and navigation issues when vertically scrolling with arrow keys from either end of the table
  • The onRendered callback in formatters is now correctly called after an edit has been successful or been cancelled
  • The progress editor has been improved to allow easier editing with arrow and tab keys

V4.6.3 Release

The following minor bugs have been fixed:

  • Fixed regression in data trees, where editing the cell containing the controls resulted in them being removed
  • Unused legacy CSS from v3.5 has been removed from stylesheets
  • Fixed variable scoping issue in the _buildColumnHeaderContent function
  • Column Components are now correctly passed to menu generator functions
  • The getHeaderFilterValue now correctly returns the filter value
  • Child rows in data trees are now correctly indented when lazy loaded after render
  • Using the selected option in any export function now works correctly
  • If a row is deleted when a cell it contains is being edited, that edit is now cancelled before the row is deleted
  • If a column is deleted when a cell it contains is being edited, that edit is now cancelled before the column is deleted
  • Cells with a value of an empty sting now render the correct height
  • Fix styling regression in bootstrap 4 theme with dark mode classes
  • Row height is now correctly recalculated on row data update
  • Prevent text selection issues on chrome when double clicking on non editable data
  • Fixed typo in deprecation warning
  • Movable rows dragged directly above group headers now have their group key changed to the correct value

Version 4.5 Release Notes

Table Layout

Fit Columns to Data and Stretch Last Column

The new fitDataStretch layout mode functions in the same way as the fitDataFill mode, but instead of stretching the empty row to fill the table it stretches the last visible column.

var table = new Tabulator("#example-table", {
    layout:"fitDataStretch",
});

Persistent Config

Ther persistence system has received an overhaul in this release, providing a more consistent way to configure table persistence and allow even more table options to be persisted between sessions.

Checkout the Upgrade Guide for more information on how to move over to the new system.

By setting the persistence property to true the table will persist the sort, filter, group (groupBy, groupStartOpen, groupHeader), pagination (paginationSize), and column (title, width, visibility, order) configuration of the table

var table = new Tabulator("#example-table", {
    persistence:true, //enable table persistence
});

For more granular control of what is persisted you can pass an object to the persistence property:

var table = new Tabulator("#example-table", {
    persistence:{
        sort: true, //persist column sorting
        filter: true, //persist filter sorting
        group: true, //persist row grouping
        page: true, //persist page
        columns: true, //persist columns
    }
});

Persistent Sort

You can ensure the data sorting is stored for the next page load by setting the sort property of the persistence option to true

This will persist all active column sorts on the table

var table = new Tabulator("#example-table", {
    persistence:{
        sort: true, //persist sort
    }
});

Note: Only built-in sorters can be stored (including module), custom sorter functions cannot be persistently stored.

Persistent Filter

You can ensure the data filtering is stored for the next page load by setting the filter property of the persistence option to true

This will persist all active column filters on the table

var table = new Tabulator("#example-table", {
    persistence:{
        filter: true, //persist filter
    }
});

Note: Only built-in filters can be stored (including module), custom filter functions cannot be persistently stored.

Note: Header filters are not currently stored persistently, this feature will be coming in a future release.

Persistent Row Grouping

You can ensure the row grouping settings are stored for the next page load by setting the group property of the persistence option to true

This will persist the current values of the groupBy, groupStartOpen, groupHeader options

var table = new Tabulator("#example-table", {
    persistence:{
        group: true, //persist row grouping
    }
});

If you want more control over which group options are persisted you can pass an object to the group property:

var table = new Tabulator("#example-table", {
    persistence:{
        group:{
            groupBy: true, //persist only the groupBy setting
            groupStartOpen: false,
            groupHeader: false,
        }
    }
});

Persistent Pagination

You can ensure the pagination settings are stored for the next page load by setting the page property of the persistence option to true

This will persist the current values of the paginationSize option and the currently selected page

var table = new Tabulator("#example-table", {
    persistence:{
        page: true, //persist pagination settings
    }
});

If you want more control over which page options are persisted you can pass an object to the group property:

var table = new Tabulator("#example-table", {
    persistence:{
        page: {
            size:true, //persist the current page size
            page:false, //do not persist the current page
        }
    }
});

Persistent Column Layout

You can ensure the layout of columns is stored for the next page load by setting the columns property of the persistence option to true

This will persist the current values of the title, width, visible options as well as the order of the columns

var table = new Tabulator("#example-table", {
    persistence:{
        columns: true, //persist column layout
    }
});

Note: If you update the column definition array after the the column layout has been stored, Tabulator will attempt to match the stored columns against the new definition. If you have any issues with column definitions updating then you will have to change the persistenceID or delete your cookies/local storage to clear out the old column layout information.

Custom Column Definition Monitoring

If you would prefer to persist additional column definition properties you can instead pass an array of the definition property keys to be watched, these will be stored whenever the column definitions are updated:

var table = new Tabulator("#example-table", {
    persistence:{
        columns: ["width", "visible", "frozen"], //persist changes to the width, visible and frozen properties
    }
});

Note: If you are going to use this mode of operation the property must exist in the column definition when the column is first initialized. Tabulator can only monitor properties that have been changed not those that have been added.

Custom Persistence Functions

If you would like to use an alternative storage method to cookies or local storage, you can override the modules reader and writer functions using the persistenceWriterFunc and persistenceReaderFunc options. It is important that if you use this method that you use both of the options defined below as one is needed to store the config data and the other to retrieve it.

When storing persistence data Tabulator stores one object per type of data being recorded (sort, filter, group, page, columns). This approach ensures itdoes not have to regenerate the entire persistence object when one value changes. The reader and writer functions handle this by being passed in the type as an argument to the functions.

Tabulator will also set a persistence ID for the table to ensure that if you have multiple tables on a page the persistence from one table is not loaded into another, this is passed into the id argument of the functions.

Persistence Data Writer Function

The persistenceWriterFunc function will receive three arguments, the persistance id of the table, the type of data to be written and an object or array representing the data

var table = new Tabulator("#example-table", {
    persistenceWriterFunc:function(id, type, data){
        //id - tables persistence id
        //type - type of data being persisted ("sort", "filter", "group", "page" or "columns")
        //data - array or object of data

        localStorage.setItem(id + "-" + type, JSON.stringify(data));
    },
});
Persistence Data Reader Function

The persistenceReaderFunc function will receive two arguments, the persistance id of the table, and the type of data to be written. This function must synchronously return the data in the format in which it was passed to the persistenceWriterFunc function. It should return a value of false if no data was present

var table = new Tabulator("#example-table", {
    persistenceReaderFunc:function(id, type){
        //id - tables persistence id
        //type - type of data being persisted ("sort", "filter", "group", "page" or "columns")

        var data = localStorage.getItem(id + "-" + type);

        return data ? JSON.parse(data) : false;
    },
});

Table Redraw Blocking

By default Tabulator will redraw part of the table when changes are made to visible data (eg. adding rows, deleting rows, sorting, etc). When carrying out lots of actions in quick succession this can cause a degradation of table performance as the table is redrawn several times.

To get around this you can use the blockRedraw and restoreRedraw functions to temporarily disable all table redraw actions while you are manipulating the table data.

Start by calling the blockRedraw function, this will prevent actions from triggering an update of the Virtual DOM:

table.blockRedraw(); //block table redrawing

When you have completed your required actions, call the restoreRedraw function. This will restore automatic table redrawing and trigger an appropriate redraw if one was needed as a result of any actions that happened while the redraw was blocked.

table.restoreRedraw(); //restore table redrawing

Table Resizing While the table redraw has been disabled, resizing the tables containing element may result in visual corruption of the table until the restoreRedraw function is called

Redraw Block Duration It is recommended that you only block table redrawing for short durations while you are performing update actions. leaving the table redraw blocked for long periods of time may result in visual corruption of the table and a poor user experience.

Finding Tables

When you first create a table, the constructor function returns the instance of that table to a variable:

var table = new Tabulator("#example-table", {
    height:"300px", //set the table height option
});

Sometimes you may want to access this table but not have easy access to the variable that the table was stored in.

The good news is that Tabulator keeps track of all tables that it creates and you can use the findTable function on the Tabulator prototype to lookup the table object for any existing table using the element they were created on.

The findTable function will accept a valid CSS selector string or a DOM node for the table as its first argument.

var table = Tabulator.prototype.findTable("#example-table"); // find table object for table with id of example-table

The findTable function will return an array of matching tables. If no match is found it will return false

Themes

Materialize Theme

Tabulator now comes with a Materialize compatible theme that can be included from:

<link href="/dist/css/materialize/tabulator_materialize.min.css" rel="stylesheet">

The stylesheet maps the standard Materialize table styling onto Tabulator. If you have customised your Materialize theme, then the /src/scss/materialize directory also contains a variables.scss file containing all the standard materialize variables. Make any changes in here to match your custom theme and recompile the tabulator_materialize.css file and Tabulator will now match your theme.

The theme also maps some of the standard table styling classes. You can use any of these classes on your Tabulator element and get the same effect as materialize:

  • striped - alternating row colors

Formatting

Title Formatter

the titleFormatter functions now accept the onRendered callback function as thier fourth argument.

Formatters

Link Formatter

A download property has been added to the link formatter formatterParams object to all setting of the download attribute on the anchor tag.

The property can have one of three values:

  • true - a boolean value of true will mark the link as a download and use the filename provided by the server
  • string - a string for the filename of the downloaded file
  • function - a callback that will be passed in the cell component as an argument and should return the file name for the downloaded file
{title:"Example", field:"example", formatter:"link", formatterParams:{
    download:true, //treat the link as a download
}}
Responsive Collapse Formatter

Updates have been made to the responsive collapse layout option, wheb using a column with the responsiveCollapse formatter to provide a toggle for the collapsed data.

The column with the responsiveCollapse formatter will now automatically be hidden when no columns have been collapsed, and become visible when columns are collapsed.

Row Number Formatter

The rownum formatter will now keep consistent numbering when sorting or filtering rows

Editing

Mobile Editing

Tabulator can now detect when it is being run on a mobile device.

There was previously an issue where if the table was set to a percentage height and an input editor was used, when the input element got focus the virtual keyboard appeard, reszing the table, causing the table to be redrawn, causing the edit to be cancled.

Now when Tabulator detects it is running on a mobile device it will automatically block table redraws when an editor is active to prevent interference from the devices virtual keyboard.

Edit Mutator Data

Edit mutators are now passed the full updated data object for each row when an update is triggered, instead of an object containing just the updated properties.

Editors

Number Editor

The new verticalNavigation option in the editorParam property for the number editor allows you to control what happens when the user presses the up and down arrow keys while using this editor. it can have one of two values:

  • editor - the arrow keys increase/decrease the value in the editor and do not navigate the table(default)
  • table - the arrow keys will navigate to the prev/next row and will not affect the cell value
{title:"Example", field:"example", editor:"number", editorParams:{
    verticalNavigation:"table", //up and down arrow keys navigate away from cell without changing value
}}
Textarea Editor

The new verticalNavigation option in the editorParam property for the textarea editor allows you to control what happens when the user presses the up and down arrow keys while using this editor. it can have one of three values:

  • hybrid - the arrow keys move the cursor around the text area, when the cursor reaches the start or end of the contents of the text area it navigates to the next row of the table (default)
  • editor - the arrow keys move the cursor around the textarea contents but do not navigate round the table
  • table - the arrow keys will navigate to the prev/next row and will not move the cursor in the editor
{title:"Example", field:"example", editor:"textarea", editorParams:{
    verticalNavigation:"editor", //navigate cursor around text area without leaving the cell
}}
Select Editor

The new verticalNavigation option in the editorParam property for the select editor allows you to control what happens when the user presses the up and down arrow keys while using this editor. it can have one of three values:

  • editor - value selection up and down the list, will not navigate round the table (default)
  • table - the arrow keys will navigate to the prev/next row and will not change the selected value in the list
  • hybrid - the arrow keys move the value selection up and down the list, when it reaches the end of the list it moves on to the adjacent row
{title:"Example", field:"example", editor:"select", editorParams:{
    verticalNavigation:"hybrid", //navigate to new row when at the top or bottom of the selection list
}}
Autocomplete Editor

The new verticalNavigation option in the editorParam property for the autocomplete editor allows you to control what happens when the user presses the up and down arrow keys while using this editor. it can have one of three values:

  • editor - value selection up and down the list, will not navigate round the table (default)
  • table - the arrow keys will navigate to the prev/next row and will not change the selected value in the list
  • hybrid - the arrow keys move the value selection up and down the list, when it reaches the end of the list it moves on to the adjacent row
{title:"Example", field:"example", editor:"autocomplete", editorParams:{
    verticalNavigation:"hybrid", //navigate to new row when at the top or bottom of the selection list
}}

Rows

Row Grouping

Click Callbacks

The groupClick, groupDblClick and groupContext callbacks now have a this scope of the table.

Visible Row Range Lookup

Functions for retreiving row and row data such as getRows, getData, and getDataCount now accept a string argument instead of a boolean. By default these functions will return based on all rows held in the table, to restrict the rows returened you can pass a an argument to the functions with one of the following values:

  • active - only return rows that pass the current filters
  • visible - only return rows currently visible in the table viewport
var rows = table.getRows("visible"); //retrieve row components for all rows currently visible in the table viewport

Delete Multiple Rows

You can now delete multiple rows at once by passing an array of row component look up options to the deteleRow function

table.deleteRow([15,7, 9]); //delete rows with ids of 15, 7 and 9

Clipboard

Visible Copy Selector

A new visible cope selector has been added to allow clipboard copying of only the rows currently visisible in the table viewport

var table = new Tabulator("#example-table", {
    clipboardCopySelector:"visible", //copy only the rows currently visible in the table viewport to the clipboard
});

Pagination

Initial Load Page

By default Tabulator will load the first page of data when the table is initially loaded. You can use the paginationInitialPage option to specify that a specific page should be loaded when the table first loads.

var table = new Tabulator("#example-table", {
    pagination:"local", //enable local pagination.
    paginationInitialPage:2, // this option can take any positive integer value (default = 1)
});

Columns

Promise Returns

The addColumn and deleteColumn table functions now return a promise. As does the delete function on the column component.

table.deleteColumn("name")
.then(function(){
    //success
})
.catch(function(error){
    //failure
})

Resize Handle Double Click Propagation

Double click on the column resize handles no longer proagate through to the cell or row to be consistent with the click event handlers.

Assign Class to Column Group Header

The cssClass option is now available on column groups to set classes on the column group header

var table = new Tabulator("#example-table", {
    columnHeaderVertAlign:"bottom", //align header contents to bottom of cell
    columns:[
        {title:"Name", field:"name", width:160},
        {
            title:"Work Info",
            cssClass:"custom-group-class", //add custom class to column group header element
            columns:[
            {title:"Progress", field:"progress", align:"right", sorter:"number", width:100},
            {title:"Rating", field:"rating", align:"center", width:80},
            {title:"Driver", field:"car", align:"center", width:80},
            ],
        },
    ],
});

Vertical Column Header Alignment

The columnVertAlign option has been renamed to columnHeaderVertAlign to make it clearer that it only affects the column headers

var table = new Tabulator("#example-table", {
    columnHeaderVertAlign:"bottom", //align header contents to bottom of cell
});

Update Column Definition

You can update the definition of a column with the updateColumnDefinition function. The first argument can be any any of the standard column component look up options. The second argument should be an object containing the properties of the column that you want to change. Any properties defined on the original column definition and not contained in the update object will be unchanged.

table.updateColumnDefinition("name", {title:"Updated Title"}) //change the title on the name column

Alternatively if you have the Column Component of the column you wish to update, you can call the updateDefinition function directly on the component.

column.updateDefinition({title:"Updated Title"}) //change the column title

New Column Component It is worth noting that using this function actually replaces the old column with a totally new column component, therefor any references to the previous column component will no longer work after this function has been run.

Returned Promise

The updateColumnDefinition and updateDefinition methods return a promise, this can be used to run any other commands that have to be run after the column has been updated. By running them in the promise you ensure they are only run after the table has been redrawn. The promise will resolve with the updated column component for the column as an argument

table.updateColumnDefinition("name", {title:"Updated Title"}) //change the column title
.then(function(column){
    //column - column component for the updated column;
})
.catch(function(error){
    //handle column update error
});

AJAX

URLs with Parameters

The ajaxURL option can now handle urls that contain existing parameters

var table = new Tabulator("#example-table", {
    ajaxURL:"http://www.getmydata.com/now?data=today", //ajax URL with parameter after the "?"
});

Row Selection

Multiple Row Selection

If you want to select multiple rows you can now pass one of 4 options into the selectRow function:

  • array - pass an array of row component look up options into the first parameter
  • "all" - pass a string of all to select all rows in the table
  • "active" - pass a string of active to select only active rows (rows that match the current filters)
  • "visible" - pass a string of visible to select only rows currently visible in the table viewport
table.selectRow("visible"); //select all rows currently visible in the table viewport

If you do not pass any arguments to the selectRow function, all rows will be selected. To select only rows that have been filtered pass true as the first argument.

Downloading

Download Data Set

By default the download function will include only the active rows in the download output (those that match the current filters). An optional fourth argument to the download function now allows you to specify the data set you wish to download, you can choose from one of three options:

  • active - include the active (filtered) rows only in the download output (default)
  • all - include all rows in the download output regardless of whether they are filtered or not
  • visible - include only rows currently visible in the table viewport
table.download("csv", "data.csv", {}, "visible"); //include only rows visible in the table viewport in the download output

Grouped Data
The all option is not available for grouped data. This is because grouping is carried out after filtering in Tabulators data processing pipeline, so only filtered data ever makes it into groups.

HTML Downloader

A new html downloader has been added to allow users to download the table as a simple HTML file

table.download("html", "data.html"); // download table as HTML file
Styling

By default the HTML output is a simple unstyled table. if you would like to match the current table styling you can set the style property to true in the options object

table.download("html", "data.html", {style:true}); //download a html table with matching styling

XLSX Downloader

SheetsJS Options

You can now configure the workbook created by SheetJS using the native SheetJS workbook setup options with the optional documentProcessingcallback. This function is called when the workbook is ready to be created. The first argument is the workbook object complete with all the sheet data. It must return the updated workbook

table.download("xlsx", "data.xlsx",{
    documentProcessing:function(workbook){
        //workbook - sheetJS workbook object

        //set some properties on the workbook file
        workbook.Props = {
            Title: "SheetJS Tutorial",
            Subject: "Test",
            CreatedDate: new Date(2017,12,19)
        };

        return workbook;
    }
}); //download a xlsx file using SheetJS properties

HTML Output

CSS Class Duplication

The HTML Table Export module has been updated, now css classes applied with the cssClass column definition property will be duplicated through to the module output.

In practice this means that the getHtml function and the print styling output will now copy the css classes to cells and column headers.

Callbacks

Scrolling Callbacks

Vertical Scroll

The scrollVertical callback is triggered when the table is vertically scrolled.

var table = new Tabulator("#example-table", {
    scrollVertical:function(top){
        //top - the current vertical scroll position
    },
});

Complex Functions This function is called many times during a scroll. It is strongly recommended that you don't carry out any intensive actions or call any other functions on the table in this function as it will slow down the table rendering and result in a poor user experience.

Horizontal Scroll

The scrollHorizontal callback is triggered when the table is horizontally scrolled.

var table = new Tabulator("#example-table", {
    scrollHorizontal:function(left){
        //left - the current horizontal scroll position
    },
});

Bug Fixes

The following minor bugs have been fixed:

  • The onRendered function is now correctly called on cell formatters when the cell is redrawn
  • Fix progress formatter rendering issues on firefox
  • Fixed missing semi colons in the bulma theme variables.scss file
  • Fixed error when using clipboard functionality on tables with grouped columns
  • The clickable area around the group header arrow toggle has been expanded to make it easier to click on
  • Fixed regression in the jQuery wrapper that was preventing it from working in web browsers
  • Removed duplicate call to the values function on the select editor on initial open
  • Tabbing between editors in IE has now been fixed
  • Fixed passive event listere warning on new row creation
  • Fixed memory leak when clearing header filters
  • Fixed issue with clipboard module not correctly appling accessors to clipboard data

Version 4.4 Release Notes

Columns

Move Columns

Tabulator now provides a way for you to programmatically move rows around your table

Move Column on Table

If you want to programmatically move a column to a new position you can use the moveColumn function.

The first argument should be the column you want to move, and can be any of the standard column component look up options.

The second argument should be the target column that you want to move to, and can be any of the standard column component look up options.

The third argument determines whether the column is moved to before or after the target column. A value of true will cause to the column to be placed after the target column, a value of false will result in the column being placed before the target

table.moveColumn("name", "age", true); //move the name column after the age column
Move Column on Component

You can move a column component next to another column using the move function.

The first argument should be the target column that you want to move to, and can be any of the standard column component look up options.

The second argument determines whether the column is moved to before or after the target column. A value of false will cause to the column to be placed before the target column, a value of true will result in the column being placed after the target

column.move("age", true); //move the current column after the age column

Editors

Editor Element Attributes

All editors now have and additional property on thier editorParams option. The new elementAttributes peoperty allows you to pass in an object of key value pairs to set attributes directly on the editor element. the key of theproperty will represent the attribute name and the value will be set as the attributes value.

{title:"Name", field:"name", editor:"input", editorParams{
    elementAttributes:{
        maxlength:"10", //set the maximum character length of the input element to 10 characters
    }
}}

By default this will automatically replace any existing value on that attribute, which may cause trouble if for example you are trying to update the style attribute of an element. In this case you can prefix the attribute name with a +, this will cause the value to be appended to the end of the existing attribute.

{title:"Name", field:"name", editor:"input", editorParams{
    elementAttributes:{
        "+style":"background-color:#f00;", //set background colour of the element to red and keep existing styles.
    }
}}

Select and Autocomplete Default Values

The defaultValue property can now be set on the editorParams for the select and autocomplete editors.

This property will cause a value from the list to be selected by default when an editor is loaded on a cell with an undefined value.

{title:"Color", field:"col", editor:"select", editorParams{
    values:["red", "green", "blue"]
    defaultValue:"green", //select the value of green in the dropdown list by default if the cell has no value
}}

Select and Autocomplete Generate Values List From Other Column

You can now pass a string representing the field of another column in the table to the values property on the editorParams for the select and autocomplete editors. Tabulator will automatically build the values list out of all unique values in cells in the specified column.

{title:"Example", field:"example", editor:"select", editorParams:{values:"color"}}

Clipboard

Column Visibility

If you don't want to show a particular column in the clipboard output you can set the clipboard property in its column definition object to false:

var table = new Tabulator("#example-table", {
    columns:[
        {title:"Hidden Column", field:"secret", clipboard:false} //hide data in clipboard data
    ]
});

You can also force a hidden column to be visibile in the clipboard output by setting the clipboard property in its column definition object to true:

var table = new Tabulator("#example-table", {
    columns:[
        {title:"Hidden Column", field:"secret", visible:false, clipboard:true} //show hidden column in clipboard output
    ]
});

Row Groups

Get Field of Group Component

The new getField function on the group component returns the string of the field that all rows in this group have been grouped by. (if a function is used to group the rows rather than a field, this function will return false)

var field = group.getField();

New Row on Tab

The new tabEndNewRow option allows you to specifcy the behaviour when the user tabs fro the last editable cell on the last row of the table.

By default nothing will happen when you tab out of the last editable cell on the table. Setting the tabEndNewRow option will cause the table to create a new row and add focus on the first editable cell in that row when you tab out of the last editable cell on the table. You can set it to one of a number of options to determine the data of the new row.

Boolean

Passing a value of true to the option will result in an empty new row being created

var table = new Tabulator("#example-table", {
    tabEndNewRow: true, //create empty new row on tab
});
Data Object

Passing an object to the option will result in a new rown being created with the data object provided

var table = new Tabulator("#example-table", {
    tabEndNewRow: {name:"steve", age:62}, //create new row with this data
});
Function

If you pass a function to the option the function will be called and passed the row component for the row of the current cell, the function should return the data object for the new row.

var table = new Tabulator("#example-table", {
    tabEndNewRow: function(row){
        //row - row component for current last row in table
        return {name:"bob", age:34}; // return data object for new row
    }
});

Sorting

Global Header Sort

The headerSort option can now be set in the table options to affect all columns as well as in column definitions.

var table = new Tabulator("#example-table", {
    headerSort:false, //disable header sort for all columns
});

Global Header Tristate Sort

The headerSortTristate option can now be set in the table options to affect all columns as well as in column definitions.

var table = new Tabulator("#example-table", {
    headerSortTristate:true, //enable tristate header sort for all columns
});

Row Selection

Row Selection Formatter

The new rowSelection formatter allows you to add a column of tickboxes down one side of your table to handle row selection:

var table = new Tabulator("#example-table", {
    columns:[
        {formatter:"rowSelection", titleFormatter:"rowSelection", align:"center", headerSort:false},
    ]
});

Invalid Setup Options

Setting the invalidOptionWarnings option to false will disable console warning messages for invalid properties in the table constructor and column definition objects

var table = new Tabulator("#example-table", {
    invalidOptionWarnings: false, //disable console warnings for invalid table properties
});

Bug Fixes

The following minor bugs have been fixed:

  • Fixed typo in progress formatter
  • Added warning when groupHeader array size is different from groupBy array size
  • Fixed typos in console warning messages
  • Fixed vairable scope issue in redraw function
  • Improved cross browser detection of localStorage functionality
  • Ensured that the getPrevColumn and getNextColumn functions only return visible rows, as per the documentation
  • Fixed issue with column header filters where they were sending empty strings as filter values after the clearHeaderFilter function was called
  • Fixed issue with getData function missing from sudo cell component on getHTML/print formatters
  • Fixed issue with getRow returning empty object from sudo cell component on getHTML/print formatters
  • Fixed missing table level column calcs in getHTML/print output

Version 4.3 Release Notes

Scrolling Performance

A series of updates have been made to move Tabulator over to using passive event listeners for user interaction. This has resulted in improved scrolling performance and smoother scrolling animation.

Columns

Column Header Visibility

By setting the headerVisible option to false you can hide the column headers and present the table as a simple list if needed.

var table = new Tabulator("#example-table", {
    headerVisible:false, //hide column headers
});

Editors

Input Editor

Search type input

the input editor now has an optional editorParams property, search that changes the input type from "text" to "search", this shows the "X" clear button to the right of the input to allow users to clear the cells value easily.

{title:"Example", field:"example", editor:"input", editorParams:{
    search:true, //use search type input box
}}

HTML Table Generation

New Module

Generation of raw HTML tables has been moved into the HtmlTableExport Module to allow the functionality to be reused in the print and clipboard functionality

Updated Output

The output getHtml function will now contain column header groups, row groups, and column calculations.

You can choose to remove column headers groups and row groups in the output data by setting the values in the htmlOutputConfig option in the table definition:

var table = new Tabulator("#example-table", {
    htmlOutputConfig:{
        columnGroups:false, /do not include column groups in column headers for HTML table
        rowGroups:false, //do not include row groups in HTML table
        columnCalcs:false, //do not include column calcs in HTML table
    },
});

New Function Arguments

By default, the getHtml function used to return a table containing all rows in the table. It now returns a table built of all active rows in the table (matching filters and sorts).

There are now three arguments that can be passed into the function to configure the output. the first argument is a boolean that determines whether the output table contains all active rows (false), or just those currently visible (true). By default this is false.

The second argument is a boolean that determines if the output of the function should be styled to match the table (true) or be a blank html table (false), by default this is false

The third argument takes an object that can be used to override the object set on the htmlOutputConfig option

var htmlTable = table.getHtml(true, true, {columnGroups:false}); //get styled html for visible rows of table that copies the table style without grouped column headers

Column Visibility

If you don't want to show a particular column in the HTML output you can set the htmlOutput property in its column definition object to false:

var table = new Tabulator("#example-table", {
    columns:[
        {title:"Hidden Column", field:"secret", htmlOutput:false} //hide data in HTML
    ]
});

You can also force a hidden column to be visibile in the HTML output by setting the htmlOutput property in its column definition object to true:

var table = new Tabulator("#example-table", {
    columns:[
        {title:"Hidden Column", field:"secret", visible:false, htmlOutput:true} //show hidden column in HTML
    ]
});

Printing

Tabulator now offers a range of print styling options, from deciding how your table should look on the page when the site is printed to printing full page tables.

Print Styling

By Default when a page is printed that includes a Tabulator it will be rendered on the page exactly as the table is drawn. While this is useful in most cases, some users prefer tohave more controll over the print output, for example showing all rows of the table, instead of just those visible with the current position of the scroll bar.

Tabulator provides a print styling mode that will replace the Tabulator with an HTML table for the printout giving you much more control over the look and feel of the table for the print out., to enable this mode, set the printAsHtml option to true in the table constructor.

var table = new Tabulator("#example-table", {
    printAsHtml:true, //enable html table printing
});

This will replace the table (in print outs only) with a simple HTML table with the class tabulator-print-table that you can use to style the table in any way you like.

It also has the benifit that because it is an HTML table, if it corsses a page break your browser will uatomatically add the column headers in at the top of the next page.

Table Contents

The HTML table will contain column header groups, row groups, and column calculations.

You can choose to remove any of these from the output data by setting the values in the printConfig option in the table definition:

var table = new Tabulator("#example-table", {
    printConfig:{
        columnGroups:false, /do not include column groups in column headers for HTML table
        rowGroups:false, //do not include row groups in HTML table
        columnCalcs:false, //do not include column calcs in HTML table
    },
});
Table Styling

If you want your printed table to be styled to match your Tabulator you can set the printCopyStyle to true, this will copy key layout styling to the printed table

var table = new Tabulator("#example-table", {
    printAsHtml:true, //enable html table printing
    printCopyStyle:true, //copy Tabulator styling to HTML table
});
Visible Rows

By default, only the rows currently visible in the Tabulator will be added to the HTML table, If you want to inclued all the active data (all currently filted/sorted rows) in the table you can set the printVisibleRows option to false.

var table = new Tabulator("#example-table", {
    printAsHtml:true, //enable html table printing
    printVisibleRows:false, // print all rows in the table
});

Render Time
Because generating a table containing a lot of rows takes a lot of time and consumes a lot of memory, it is not advised to show all rows in your table if there are more than 1000 rows.

Column Visibility

If you don't want to show a particular column in the print table you can set the print property in its column definition object to false:

var table = new Tabulator("#example-table", {
    columns:[
        {title:"Hidden Column", field:"secret", print:false} //hide data in print data
    ]
});

You can also force a hidden column to be visibile in the print by setting the print property in its column definition object to true:

var table = new Tabulator("#example-table", {
    columns:[
        {title:"Hidden Column", field:"secret", visible:false, print:true} //show hidden column when printing
    ]
});

Full Page Printing

You can use the print function to trigger a full page printing of the contents of the table without any other elements from the page.

table.print();

There are three arguments that can be passed into the function to configure the output. the first argument is a boolean that determines whether the output table contains all active rows (false), or just those currently visible (true). By default this is false.

The second argument is a boolean that determines if the output of the function should be styled to match the table (true) or be a blank html table (false), if you leave this argument out it will take the value of the printCopyStyle option

The third argument takes an object that can be used to override the object set on the printConfig option

table.print(true, true, {columnGroups:false}); //full page print the table for visible rows of table that copies the table style without grouped column headers
Header

You can use the printHeader table setup option to define a header to be displayed when the table is printed.

var table = new Tabulator("#example-table", {
    printHeader:"<h1>THIS IS MY COOL TABLE</h1>", // set header content on printed table
});

This option can take one of three types of value:

  • string - you can pass an HTML string to be set as the contents header
  • DOM Node - you can pass DOM Node to be used as the header
  • function - a function that will be called when the table is printed, it should return either a string or DOM Node

The header contents will be placed inside a div with a class of tabulator-print-header to allow you to style your header with CSS

Print Header Placement
The print header will be inserted above the table on the printout, this will only occur on the first page of the print out, this should not be used as a page header.

Footer

You can use the printFooter table setup option to define a footer to be displayed when the table is printed.

var table = new Tabulator("#example-table", {
    printFooter:"<h3>THANKS FOR LOOKING AT MY TABLE</h3>", // set footer content on printed table
});

This option can take one of three types of value:

  • string - you can pass an HTML string to be set as the contents footer
  • DOM Node - you can pass DOM Node to be used as the footer
  • function - a function that will be called when the table is printed, it should return either a string or DOM Node

The footer contents will be placed inside a div with a class of tabulator-print-footer to allow you to style your footer with CSS

Print Footer Placement
The print footer will be inserted below the table on the printout, this will only occur on the last page of the print out, this should not be used as a page footer.

Print Formatting

The printFormatter table setup option allows you to carry out any manipulation of the print output before it is displayed to the user for printing

var table = new Tabulator("#example-table", {
    printFormatter:function(tableHolderElement, tableElement){
        //tableHolderElement - The element that holds the header, footer and table elements
        //tableElement - The table
    }
});

Downloads

Download Titles available in Column Groups

The downloadTitle property is now available in the column definition property for column groups to help with customization of table downloads.

var table = new Tabulator("#example-table", {
    columns:[
        {title:"Name", field:"name", width:160},
        {//create column group
            title:"Work Info",
            downloadTitle:"INFORMATION", //add custom title for use in downloads
            columns:[
                {title:"Progress", field:"progress", align:"right", sorter:"number", width:100},
                {title:"Rating", field:"rating", align:"center", width:80},
                {title:"Driver", field:"car", align:"center", width:80},
            ],
        },
    ],
});

PDF Document Processing Option

An optional callback documentProcessing can be set on the download config object, that is passed the jsPDF document object after the auto-table creation to allow full customisation of the PDF, see the jsPDF document for a full list of methods that can be called on this object

table.download("pdf", "data.pdf", {
    documentProcessing:function(doc){
        //carry out an action on the doc object
    }
});

Table Setup Warnings

Table Constructor Warnings

Tabulator will now produce console warnings if options are set on the table constructor using parameters that are not valid.

Column Definition Warnings

Tabulator will now produce console warnings if options are set on the a column definition using parameters that are not valid.

Typescript Typings

Thanks to the great work of @Jojoshua Tabulator now has a full script of TypeScript typings for any developers that need them.

They can be brought into your project with npm

npm install @types/tabulator-tables

An example of how to use the typings on your project can be found at: https://github.com/Jojoshua/TypedTabulator

Vue Component

Thanks to the hard work of @angeliski there is now a Vue.js component for Tabulator, to make it even easier to install in your Vue.js project

Full documentation on this component can be found at: https://vue-tabulator.netlify.com/

Bug Fixes

The following minor bugs have been fixed:

  • jQuery wrapper has been updated to include jquery-ui dependency
  • getDataCount function argument behaviour has been updated to match documentation
  • Fixed missing variable definition in the clipboard copy function
  • Added support for the cmd key on a mac instead of the ctrl key when selecting rows
  • Fixed typo in column calcs preventing bottom calcs from rendering
  • Fixed bitwise comaprison issue in the required validator
  • Fixed typo in the navigateDown function
  • Updated the dev dependencies in the package.lock and yarn.lock files
  • Fixed readonly issues on the select editor when used as a header filter
  • Improved console logging to remove unnecessary logs
  • Memory leak fixed when using column calculations and grouped rows in a table in classic render mode
  • Column calculations are now correctly hidden on hidden row groups when table is in classic render mode
  • Column calculations are now correctly updated in all modes when using row groups
  • "undefined" text no longer appears when an undefined value is passed into a textarea editor
  • The getNetColumn and getPrevColumn functions now return false if no matching column is available
  • The click row selection mode now respects the selectable row limit
  • Text selection no longer interferes with movable rows
  • Double clicking on a cell now only selects the text in that cell rather than other text in the row
  • The selection list from select and autocomplete editors is automatically hidden on scroll to prevent visual corruption
  • The getFilters function now correctly outputs complex filters

Version 4.2 Release Notes

Reactive Data

The reactivity systems allow Tabulator to watch arrays and objects passed into the table for changes and then automatically update the table.

This approach means you no longer need to worry about calling a number of different functions on the table to make changes, you simply update the array or object you originally passed into the table and Tabulator will take care of the rest.

You can enable reactive data by setting the reactiveData option to true in the table constructor, and then passing your data array to the data option.

Once the table is built any changes to the array will automatically be replicated to the table without needing to call any functions on the table itself

//define array of table data
var tableData = [
    {id:1, name:"Billy Bob", age:"12", gender:"male", height:1, col:"red", dob:"", cheese:1},
    {id:2, name:"Mary May", age:"1", gender:"female", height:2, col:"blue", dob:"14/05/1982", cheese:true},
    {id:3, name:"Christine Lobowski", age:"42", height:0, col:"green", dob:"22/05/1982", cheese:"true"},
    {id:4, name:"Brendon Philips", age:"125", gender:"male", height:1, col:"orange", dob:"01/08/1980"},
    {id:5, name:"Margret Marmajuke", age:"16", gender:"female", height:5, col:"yellow", dob:"31/01/1999"},
]

//create table and assign data
var table = new Tabulator("#example-table", {
    reactiveData:true, //enable reactive data
    data:tableData, //assign data array
});
Local Data Only

Reactive data functionality is only available with local data arrays set on the data property or the setData function. It is not available on ajax data sources

Framework Compatibility

The data reactivity module has been built to be compatible with all other reactive front end frameworks like vue, react and angular. This means that when you include Tabulator in your framework project you only need to pass the data array to it when you instantiate the table. you can then manipulate the array and data objects through the framework and Tabulator will automatically update

Automatic Column Generation

If you are building a simple table that only uses strings and numbers for data, and you don't need any interactivity or formatting on the table, then you can get Tabulator to define your columns for you.

If you set the autoColumns option to true, every time data is loaded into the table through the data option or through the setData function, Tabulator will examine the first row of the data and build columns to match that data.

//define data
var tabledata = [
    {id:1, name:"Billy Bob", age:12, gender:"male", height:95, col:"red", dob:"14/05/2010"},
    {id:2, name:"Jenny Jane", age:42, gender:"female", height:142, col:"blue", dob:"30/07/1954"},
    {id:3, name:"Steve McAlistaire", age:35, gender:"male", height:176, col:"green", dob:"04/11/1982"},
];

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

Tabulator will iterate through each property of the object in the order that they are defined (not alphabetical order), it will use the name of the property as the columns title and will attempt to set the most appropriate sorter for column based on the value of the property (Currently limited to string, number, alphanum, boolean and array).

Load Data from Local File

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

table.setDataFromLocalFile(); //load data into table from local file

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.

Valid File Types

By default Tabulator will only allow files with a .json extension to be loaded into the table.

You can allow any other type of file into the file picker by passing the extension or mime type into the first argument of the setDataFromLocalFile function as a comma separated list. This argument will accept any of the values valid for the accept field of an input element

table.setDataFromLocalFile(".txt"); //only allow files with a .txt extension in the file picker

Virtual DOM

The virtual DOM has undergone an number of improvements in this release.

Adaptive Buffer Size

In previous versions the table would struggle to render scrolling through a table if the row height was close to or greater than the table height. This version introduces an adaptive row buffer that will resize to fit any size of row, preventing the table from skipping when scrolled

Efficiency Improvements

This release sees some minor efficiency improvements in virtual DOM, setting things up for a more substatial set of improvements in version 4.3

Scroll Smoothness

A number of small bugs have been ironed out that were causing jerky or glitchy scrolling under certain circumstances.

Ajax Data Loading

Cross Origin Requests

If you are making ajax requests to URL's not on the same origin as your site, Tabulator will now attempt to setup the CORS headers for you to allow the request to succeed.

Pagination

Page Size Select Element

If you would like the user to be able to set the number of rows on each page, you can use the paginationSizeSelector option, which will add a page size selection select element to the table footer.

Auto Generate Page Size List

Setting this option to true will cause Tabulator to create a list of page size options, that are multiples of the current page size. In the example below, the list will have the values of 5, 10, 15 and 20.

When using the page size selector like this, if you use the setPageSize function to set the page size to a value not in the list, the list will be regenerated using the new page size as the starting value

var table = new Tabulator("#example-table", {
    pagination:"local",
    paginationSize:5,
    paginationSizeSelector:true, //enable page size select element and generate list options
});
Sepecifying the Page Size List

If you want to specific the available page sizes you can pass an array of integers to the paginationSizeSelector option.

var table = new Tabulator("#example-table", {
    pagination:"local",
    paginationSize:10,
    paginationSizeSelector:[10, 25, 50, 100], //enable page size select element with these options
});

When using the page size selector like this, if you use the setPageSize function to set the page size to a value not in the list, it will be added to the top of the list

Load Page for a Specific Row

You can now load the page for a specific row using the setPageToRow function and passing in any of the standard row component look up options for the row you want to scroll to.

table.setPageToRow(12); // load the previous page

The setPageToRow method returns a promise, this can be used to run any other commands that have to be run after the data has been loaded into the table. By running them in the promise you ensure they are only run after the table has loaded the data.

table.setPageToRow(12)
.then(function(){
    //run code after table has been successfully updated
})
.catch(function(error){
    //handle error loading data
});

If you have a Row Component for a specific row, you can call the pageTo function on the component to load the page for that row.

row.pageTo(); //load page that contains row

Local Pagination Only
This functionality is only available on local pagination. when using remote pagination Tabulator has ow way to lookup which page the requested row is on.

Mouse Events

A range of callbacks have been added to allow you to take action on a variety of mouse events.

Cell Events

Cell Mouse Enter

The cellMouseEnter callback is triggered when the mouse pointer enters a cell, it can be set on a per column basis using the option in the columns definition object.

{title:"Name", field:"name", cellMouseEnter:function(e, cell){
    //e - the event object
    //cell - cell component
    },
}

The cellMouseEnter callback can also be set globally.

var table = new Tabulator("#example-table", {
    cellMouseEnter:function(e, cell){
    //e - the event object
    //cell - cell component
    },
});
Cell Mouse Leave

The cellMouseLeave callback is triggered when the mouse pointer leaves a cell, it can be set on a per column basis using the option in the columns definition object.

{title:"Name", field:"name", cellMouseLeave:function(e, cell){
    //e - the event object
    //cell - cell component
    },
}

The cellMouseLeave callback can also be set globally.

var table = new Tabulator("#example-table", {
    cellMouseLeave:function(e, cell){
    //e - the event object
    //cell - cell component
    },
});
Cell Mouse Over

The cellMouseOver callback is triggered when the mouse pointer enters a cell or one of its child element, it can be set on a per column basis using the option in the columns definition object.

{title:"Name", field:"name", cellMouseOver:function(e, cell){
    //e - the event object
    //cell - cell component
    },
}

The cellMouseOver callback can also be set globally.

var table = new Tabulator("#example-table", {
    cellMouseOver:function(e, cell){
    //e - the event object
    //cell - cell component
    },
});
Cell Mouse Out

The cellMouseOut callback is triggered when the mouse pointer leaves a cell or one of its child element, it can be set on a per column basis using the option in the columns definition object.

{title:"Name", field:"name", cellMouseOut:function(e, cell){
    //e - the event object
    //cell - cell component
    },
}

The cellMouseOut callback can also be set globally.

var table = new Tabulator("#example-table", {
    cellMouseOut:function(e, cell){
    //e - the event object
    //cell - cell component
    },
});
Cell Mouse Move

The cellMouseMove callback is triggered when the mouse pointer moves over a cell, it can be set on a per column basis using the option in the columns definition object.

{title:"Name", field:"name", cellMouseMove:function(e, cell){
    //e - the event object
    //cell - cell component
    },
}

The cellMouseMove callback can also be set globally.

var table = new Tabulator("#example-table", {
    cellMouseMove:function(e, cell){
    //e - the event object
    //cell - cell component
    },
});

Row Events

Row Mouse Enter

The rowMouseEnter callback is triggered when the mouse pointer enters a row.

var table = new Tabulator("#example-table", {
    rowMouseEnter:function(e, row){
    //e - the event object
    //row - row component
    },
});
Row Mouse Leave

The rowMouseLeave callback is triggered when the mouse pointer leaves a row.

var table = new Tabulator("#example-table", {
    rowMouseLeave:function(e, row){
    //e - the event object
    //row - row component
    },
});
Row Mouse Over

The rowMouseOver callback is triggered when the mouse pointer enters a row or any of its child elements.

var table = new Tabulator("#example-table", {
    rowMouseOver:function(e, row){
    //e - the event object
    //row - row component
    },
});
Row Mouse Out

The rowMouseOut callback is triggered when the mouse pointer leaves a row or any of its child elements.

var table = new Tabulator("#example-table", {
    rowMouseOut:function(e, row){
    //e - the event object
    //row - row component
    },
});
Row Mouse Move

The rowMouseMove callback is triggered when the mouse pointer moves over a row.

var table = new Tabulator("#example-table", {
    rowMouseMove:function(e, row){
    //e - the event object
    //row - row component
    },
});

Touch Interaction

Columns

Movable Columns

When movableColumns is set to true you can now use touch events to move columns as well as the mouse.

Column Resize

Columns can now be resized using touch events as well as the mouse.

Rows

Movable Rows

When movableRows is set to true you can now use touch events to move rows as well as the mouse.

Row Resize

When resizableRows is set to true you can now use touch events to resize rows as well as the mouse.

Movable Rows

Programmatic Row Moving

If you want to programmatically move a row to a new position you can use the moveRow function.

The first argument should be the row you want to move, and can be any of the standard row component look up options.

The second argument should be the target row that you want to move to, and can be any of the standard row component look up options.

The third argument determines whether the row is moved to above or below the target row. A value of false will cause to the row to be placed below the target row, a value of true will result in the row being placed above the target

table.moveRow(1, 12, true); //move the row with an index of 1 above the row with an index of 12

Alternatively if you have the row component for the row you want to move, you can call the move function on it.

In this instance first argument should be the target row that you want to move to, and can be any of the standard row component look up options.

The second argument determines whether the row is moved to above or below the target row. A value of false will cause to the row to be placed below the target row, a value of true will result in the row being placed above the target

row.move(12, true); //move the current row above the row with an index of 12

Move Row Into Empty Group

You can now drag rows into empty groups to add them to the group. To do this simply drag the row onto the group header.

Data Tree

Sorting

Sorters applied to the table are now applied to all child rows, not just to top level parent rows.

Filtering

Filters applied to the table are now applied to all child rows, not just to top level parent rows.

Updating

When you use the update function on a row component to update the _children array it will now redraw the rows children to match the new data

row.update({_children:[
    {name:"Christine Lobowski", location:"France", gender:"female", col:"green", dob:"22/05/1982"},
    {name:"Mary May", location:"Germany", gender:"female", col:"blue", dob:"14/05/1982"},
]});

Toggle Element Column

By default the toggle element will be inserted into the first column on the table. If you want the toggle element to be inserted in a different column you can pass the feild name of the column to the dataTreeElementColumn setup option

var table = new Tabulator("#example-table", {
    dataTree:true,
    dataTreeElementColumn:"name", //insert the collapse/expand toggle element in the name column
});

Formatting

New Traffic Light Formatter

The traffic formatter displays a coloured circle that changes colour depending on the numeric value of the cell. No image will be displayed if the cells value is undefined or not a valid number

{title:"Example", field:"example", formatter:"traffic", formatterParams:{
    min:0,
    max:10,
    color:["green", "orange", "red"],
}}

The formatter has optional properties for the formatterParams object:

  • min - minimum value for progress bar (default 0)
  • max - minimum value for progress bar (default 100)
  • color - colour of progress bar (default ["red", "orange", "green"]), this can be:
    • array of strings - an array of color strings, that will divide the background colour across the min-max range of values(eg ["green", "orange", "#ff0000"])
    • function - a callback that is passed the value of the cell and must return the color (eg function(value){return "red"})

Link Formatter

Data Sanitization

The link formatter no longer sanitizes the cell value before it is loaded into the href attribute, thisis to prevent corruption of the link.

Downloading

Column Calculations Now In Downloads

Column calculation rows are now included in the pdf and xlsx downloaders

To disable this new functionality you can use the columnCalcs download config property

var table = new Tabulator("#example-table", {
    downloadConfig:{
        columnCalcs:false, //do not include column calculation rows in download
    },
});

Download To New Browser Tab

If you want to open the generated file in a new browser tab rather than downloading it straight away, you can use the downloadToTab function. This is particularly useful with the PDF downloader, as it allows you to preview the resulting PDF in a new browser tab

table.downloadToTab("pdf"); //convert table to PDF and open in new tab

Include Hidden Column in Download

By default hidden columns are not included in the download, If you want to force a particular column to show in the download, even if it is hidden, you can set the download property in its column definition object to true:

var table = new Tabulator("#example-table", {
    columns:[
        {title:"id", field:"id", visible:false, download:true} //force hidden field to show in download
    ]
});

PDF Downloader

Autotable Depedency Version Change

The PDF downloader now uses the 3.0.5 version of the jspdf-autotable plugin to allow even more featers for PDF downloading.

<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.5/jspdf.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf-autotable/3.0.5/jspdf.plugin.autotable.js"></script>
Grouped Column Headers Available

Grouped column headers are now available with the PDF downloader.

CSV Downloader

Byte Order Mark Added to CSV

If you need the output CSV to include a byte order mark (BOM) to ensure that output with UTF-8 characters can be correctly interpreted across different applications, you should set the bom option to true

table.download("csv", "data.csv", {bom:true}); //include BOM in output

Clipboard

Column Calculations Now In Clipboard Data

Column calculation rows are now included by default when copying the table to the clipboard.

To disable this new functionality you can use the clipboardCopyConfig download config property

var table = new Tabulator("#example-table", {
    clipboardCopyConfig:{
        columnCalcs:false, //do not include column calculation rows in clipboard output
    },
});

Editors

Autocomplete Editor

Clear Value

The autocomplete input has been changed into a search box, so there is now a cross icon on the right hand side to clear the value

Set Values List Sort Order

If you are using the values:true option in the editorParams to generate the list from other values in the column, it will be default be in the order of the rows in the table.

The new sortValuesList option allows you to choose to sort this list, either in ascending or decending order:

{title:"Example", field:"example", editor:"autocomplete", editorParams:{
    values:true, //create list of values from all values contained in this column
    sortValuesList:"desc", //if creating a list of values from values:true then choose how it should be sorted
}}

Select Editor

Set Values List Sort Order

If you are using the values:true option in the editorParams to generate the list from other values in the column, it will be default be in the order of the rows in the table.

The new sortValuesList option allows you to choose to sort this list, either in ascending or decending order:

{title:"Example", field:"example", editor:"select", editorParams:{
    values:true, //create list of values from all values contained in this column
    sortValuesList:"asc", //if creating a list of values from values:true then choose how it should be sorted
}}

Components

Column Component

Get Next Column

The getNextColumn function returns the Column Component for the next visible column in the table, if there is no next column it will return a value of false.

var nextColumn = column.getNextColumn();
Get Previous Column

The getPrevColumn function returns the Column Component for the previous visible column in the table, if there is no previous column it will return a value of false.

var prevColumn = column.getPrevColumn();

Sorting

Tristate Column Header Sorting

By default once you click on a header to sort it the header will then toggle between sorting in ascending and descending order.

If you would prefer a third option of returning the column to its original unsorted order, the you can set the headerSortTristate option to true in the column definition. The sort will the toggle between the original order, ascending and descending order

{title:"Name", field:"name", sorter:"string", headerSortTristate:true} //enable tristate sorting on this column

Filtering

Initial Column Header Filter Values

When the table is first created it can be defined with an initial set of header filter values. These can be set using the initialHeaderFilter option. This will take an array of objects with the value for the filter and the column header it should be set on.

var table = new Tabulator("#example-table", {
    initialHeaderFilter:[
        {field:"color", value:"red"} //set the initial value of the header filter to "red"
    ],
});

Filter Function Extension

Two additional arguments are now passed into filter functions when extending the filter module. the rowData argument contains the data object for the row being filtered and the filterParams argument contains the filter object set in the headerFilterFuncParams property of the column definition object.

Tabulator.prototype.extendModule("filter", "filters", {
    "===":function(headerValue, rowValue, rowData, filterParams){
        //headerValue - the value of the header filter element
        //rowValue - the value of the column in this row
        //rowData - the data for the row being filtered
        //filterParams - params object passed to the headerFilterFuncParams property

        return rowVal === headerValue ? true : false;
    }
});

Themes

Bulma Theme

A new theme CSS has been added to make the styling of Tabulator match the look and feel of the Bulma UI toolkit.

Bug Fixes

The following minor bugs have been fixed:

  • values passed to the setPage, setMaxPage and setPageSize functions are now parsed to integers
  • the select and autocomplete editors now lookup initial values in an identical manner
  • if a cell edit is inprogress when data in the table is loaded, by example changing page, the edit is now cancelled to prevent incomplete validation blocking further editing
  • if the table header is horizontally scrolled by tabbing through header filter inputs the table body now scrolls with it
  • using the dataTree option no longer results in visual corruption when used with frozen columns
  • a regression preventing value selection in the star editor has been fixed
  • column calculations now correctly updated when the update function is called on a row component
  • use of the home/end keys while in the autocomplete editor no longer results in scrolling of the table
  • clicking the responsive collapse toggle no longer also triggers row selection if enabled
  • data sanitixation removed from the link formatter url value to prevent link corruption
  • validation failure no longer causes a focus/blur event loop on Internet Explorer
  • attributes imported from an HTML table are now correctly matched by case
  • an error in the navigateNext and navigatePrev functions has been fixed
  • fixed a typo in the virtual DOM rendering system
  • readonly typo in select editor has been resolved
  • number sorter can now parse numbers with multiple separators
  • the nextPage and prevPage functions now correctly return promises

Version 4.1 Release Notes

Data Tree Layout

For nested data sets Tabulator now allows you to structure your rows as a tree, allowing users to collapse and expand nested sets of rows.

To enable data trees in your table, set the dataTree property to true in your table constructor:

var table = new Tabulator("#example-table", {
    dataTree:true,
});

In order to build a table with nested data you must structure your data in a certain way.

If a row is to have child rows, these child data objects must be provided as an array to the rows _children property:

[
    {id:1, name:"Billy Bob", age:"12" "_children":[
        {id:2, name:"Mary May", age:"1"}, //child rows nested under billy bob
        {id:3, name:"Christine Lobowski", age:"42"},
        {id:4, name:"Brendon Philips", age:"125", "_children":[
            {id:5, name:"Margret Marmajuke", age:"16"}, //child rows nested under brendon philps
            {id:6, name:"Frank Peoney", age:"12"},
        ]},
    ]},
    {id:7, name:"Jenny Jane", age:"1"},
    {id:8, name:"Martha Tiddly", age:"42", "_children":[
        {id:9, name:"Frasier Franks", age:"125"}, //child row nested under martha tiddly
    ]},
    {id:10, name:"Bobby Green", age:"11"},
]

For full details checkout the Tree Structure and Nested Data Documentation.

Vertical Column Headers

Table headers can now be set to have a vertical text orientation.

To enable this, set the headerVertical column definition property to true

{title:"Name", field:"name", headerVertical:true},

The headerVertical property can take one of three values:

  • false - vertical columns disabled (default value)
  • true - vertical columns enabled
  • "flip" - vertical columns enabled, with text direction flipped by 180 degrees

React Component

There is now a react component available for Tabulator to make it even easier to integrate interactive tables with your react project.

For full details checkout the Framework Documentation.

Search Table Data

A couple of new search functions have been added to allow you to looup row components and row data by the data it contains.

Each search function allows you to specify filters, exactly like those used by the setFilter function, any matching data or row components are then returned

Search for Row Components

The searchRows function allows you to retrieve an array of row components that match any filters you pass in. it accepts the same arguments as the setFilter function.

var rows = table.searchRows("age", ">", 12);//get row components for all rows with an age greater than 12
Search for Row Data

The searchData function allows you to retrieve an array of table row data that match any filters you pass in. it accepts the same arguments as the setFilter function.

var data = table.searchData("age", ">", 12);//get row data for all rows with an age greater than 12

Sorting

Sort Order

The new sortOrderReverse option lets you reverse the sort ordering when applying multiple sorters to match the sorting order of other table systems like excel.

var table = new Tabulator("#example-table", {
    sortOrderReverse:true,
});

Disable Multi Column Header Sort

You can now disable multi column header sorting by setting the columnHeaderSortMulti option to false

var table = new Tabulator("#example-table", {
    columnHeaderSortMulti:false,
});

Row Components

New Functions

The row component has been updated to include some additional functionality

Get Next Row

The getNextRow function returns the Row Component for the next visible row in the table, if there is no next row it will return a value of false.

var nextRow = row.getNextRow();
Get Previous Row

The getPrevRow function returns the Row Component for the previous visible row in the table, if there is no previous row it will return a value of false.

var prevRow = row.getPrevRow();

Formatters

Updated Formatters

Tick Cross

The tickCross formatter now has param tickElement and crossElement params to allow for easier customisation of the formatter

{title:"Example", field:"example", formatter:"tickCross", formatterParams:{
    tickElement:"<i class='fa fa-check'></i>",
    crossElement:"<i class='fa fa-times'></i>",
}}

Setting either of these properties to false will prevent that icon being shown.

The formatter has optional properties for the formatterParams object:

Depricated Formatters

Tick

The tick formatter has been depricated, you should now use the tickCross formatter with the crossElement formatterParams set to false to replicate its functionality.

Editors

New Editors

autocomplete

The new autocomplete editor allows users to lookup values from an autocomplete list

{title:"Example", field:"example", editor:"autocomplete", editorParams:{values:["red", "green", "blue", "orange"]}}

Updated Editors

Tick Cross

The tickCross editor now has tristate functionality built in, great for wheny ou want to use it as a header filter.

Tristate functionality can be enabled by setting the new tristate parameter to true, you can also choose the default value for the indeterminate state with the intederminateState param (defaults to null)

{title:"Driver", field:"driver", editor:"tickCross", editorParams:{tristate:true, indeterminateValue:"unsure"}}
Select

The select editor has been rebuilt, and no longer uses a standard select element. This allows it to open the moment a user clicks on the cell, rather than requiring a second click to open the list

You can now pass a boolean value of true to the values property of the editorParams object to auto populate the select list with all the values of the cells column.

{title:"Example", field:"example", editor:"select", editorParams:{values:true}}

When passing values into the select editor, they must now be passed into the values property rather than directly into the editorParams object.

{title:"Name", field:"name", editor:"select", editorParams:{
    values:{
        "steve":"Steve Boberson",
        "bob":"Bob Jimmerson",
        "jim":"Jim Stevenson",
    }
}}
Number

The number formatter has been updated so success is now strictly triggered, (eg, changing the cells value from undefined to 0 will now trigger a successful edit)

Text Area

The textarea formatter has been updated so success is now strictly triggered, (eg, changing the cells value from undefined to 0 will now trigger a successful edit)

Depricated Editors

Tick

The tick editor has been depricated, you should now use the tickCross editor.

Table Download

Download Grouped Column Headers and Row Groups

Tabulator will now include column groups and row groups in download output (some downloaders will not be able to show allfeatures due to the limitiations of the file formats)

You can choose to remove column headers groups and row groups in the output data by setting the values in the downloadConfig option in the table definition:

var table = new Tabulator("#example-table", {
    downloadConfig:{
        columnGroups:false, //include column groups in column headers for download
        rowGroups:false, //do not include row groups in download
    },
});

PDF jsPDF Param

A new jsPDF property has been added to the downloader params for the pdf downloader, this allows you to configure the setup object that is passed into the jsPDF constructor

table.download("pdf", "data.pdf", {
    orientation:"portrait", //set page orientation to portrait
    title:"Dynamics Quotation Report", //add title to report
    jsPDF:{
        unit:"in", //set units to inches
    },
});

Clipboard

Tabulator will now include column headers groups and row groups in the clipboard output.

You can choose to remove column headers groups and row groups in the output data by setting the values in the clipboardCopyConfig option in the table definition:

var table = new Tabulator("#example-table", {
    clipboardCopyConfig:{
        columnHeaders:false, //don't include column headers in clipboard output
        rowGroups:false, //do not include row groups in clipboard output
    },
});

Filters

Disable Live Filtering of Header Filters

By default if an input element is used as a header filter element, the table will be filtered in real time as the user types in the input element.

If you would prefer that the input element behave like a standard editor without live updating the table, you can now set the headerFilterLiveFilter column definition property to false

{title:"Name", field:"name", headerFilter:"input", headerFilterLiveFilter:false}

Ajax

Default Ajax Headers and Cookies

By default Tabulator will now send the following headers with any ajax request:

Header Value
X-Requested-With XMLHTTPRequest
Accept application/json

Any credentials stored in cookies with the page will also be sent with the request.

Content Type

When using a request method other than "get" Tabulator will now send any parameters with a content type of form data. You can change the content type with the ajaxContentType option. This will ensure parameters are sent in the format you expect, with the correct headers.

var table = new Tabulator("#example-table", {
    ajaxURL:"http://www.getmydata.com/now", //ajax URL
    ajaxConfig:"post", //ajax HTTP request type
    ajaxContentType:"json", // send parameters to the server as a JSON encoded string
});

The ajaxContentType option can take one of two values:

  • "form" - send parameters as form data (default option)
  • "json" - send parameters as JSON encoded string

Group Values

By default Tabulator will create groups for rows based on the values contained in the row data. if you want to explicitly define which field values groups should be created for at each level, you can now use the groupValues option.

This option takes an array of value arrays, each item in the first array should be a list of acceptable field values for groups at that level

var table = new Tabulator("#example-table", {
    groupBy:["color", "age"],
    groupValues:[
        ["red", "blue", "green"], //create groups for color values of "red", "blue", and "green",
        [10, 20, 30], //create sub groups for ages of 10, 20 and 30
    ],
});

Rows with values not in the arrays will not be show in the table. In this mode empty groups will remain visible in the table.

If you want to only specify groups for some of the levels, you can pass a value of false into the levels where you want Tabulator to decide on the grouping.

var table = new Tabulator("#example-table", {
    groupBy:["color", "age"],
    groupValues:[
        false, //createany groups needed for the colors field
        [10, 20, 30], //create sub groups for ages of 10, 20 and 30
   ],
});

Row Selection

The new selectableRangeMode option allows you choose a new click mode of row range selection.

If you would prefere to select a range of row by clicking on the first row then holding down shift and clicking on the end row then you can achieve this by setting the selectableRangeMode to click

var table = new Tabulator("#example-table", {
  selectableRangeMode:"click",
});

Nested Data Custom Field Separator

When using nested data, if you need to use the . character as part of your field name, you can change the separator to any other character using the nestedFieldSeparator option

var table = new Tabulator("#example-table", {
    nestedFieldSeparator:"|", //change the field separator character to a pipe
    columns:[
        {title:"Name", field:"user|name"},  //link column to name property of user object
    ],
});

By setting the nestedFieldSeparator to false you can disable nested data parsing. In this case all fields will be assumed to be directly on the row object regardless of characters in the field name

var table = new Tabulator("#example-table", {
    nestedFieldSeparator:false, //disable nested data parsing
});

Styling

the footerActiveColor SCSS vairable has been added to all themes to make it possible to set the text color for active pagination buttons.

Return Type Warnings

Console warning have been added notify developers when the wrong tepe of objects are returned from editors and formatters.

Bug Fixes

The following minor bugs have been fixed:

  • html sanitization has been removed from the image formatter to prevent corruption of links
  • image formatter no longer sanitizes url string
  • fixed row deselection on deletion
  • validators now correctly pull in parameters
  • arrays in row data are no longer converted to objects when retured from the getData function
  • a typo preventing the keybindings extension from being pulled in on npm run on linux has been resolved
  • the clopboard module now correctly handles text selection
  • option groups in the select editor how display correctly

Version 4.0 Release Notes

  • Extensions Renamed to Modules
  • Callback Context
  • Param Object Lookup Functions
  • Clipboard Styling
  • SCSS Default Variables
  • Formatters
  • Filtering
  • History Availability
  • Pagination URL
  • PDF Downloads
  • Column Headers
  • Row Component
  • Column Component
  • Cell Component
  • Group Component
  • Bug Fixes
  • Removal of deprecated Functionlaity
  • Removal of jQuery

    The biggest change of this update is that Tabulator is now dependency free!

    The core code of version 4.0 of Tabulator is no longer dependent jQuery, which means you can now instantiate your tables and store them in a JavaScript variable. The first argument should be either a CSS selector for the table holding element or the DOM node of the table holding element The second argument should be your usual configuration object:

    var table = new Tabulator("#example-table", {
    	//table setup options
    });

    You can now call functions directly on your table object:

    table.getRow(1);

    Callbacks that previously accepted jQuery objects as return values will now expect DOMNodes

    For those of you that want to continue using Tabulator as a jquery widget, there is now a jQuery wrapper that you can include in your project to keep old functionality. For full details on how to use the wrapper checkout the Upgrade Guide.

    Core Files Package

    In addition to the standard install options, Tabulator now comes with another option for developers that are really conscious of package size.

    The core js files provide the minimal JavaScript needed to create a basic table, these are perfect for environments where optimal file sizes are needed.

    Minified
    <script type="text/javascript" src="dist/js/tabulator_core.min.js"></script>
    Unminified
    <script type="text/javascript" src="dist/js/tabulator_core.js"></script>

    If you need any of the modules in addition to the core files (for example you want to include formatters with your table), then you should include these files after the core js file. The module distributions can be found in the /dist/js/modules folder.

    <script type="text/javascript" src="dist/js/tabulator_core.min.js"></script>
    <script type="text/javascript" src="dist/js/modulesformat.min.js"></script>

    Promises

    Tabulator now takes full advantage of the Promise API to make it easier than ever to run asynchronouscommands in the correct order.

    Commands that load data into the table now return a promise that you can use to run further commands once the table has been updated.

    table.setData("/mydata.php")
    .then(function(){
    	//success;
    })
    .catch(function(error){
    	//failure
    })
    

    At the moment promise based functionality is available on the following table functions:

    • setData
    • replaceData
    • setPage
    • nextPage
    • previousPage
    • updateData
    • addData
    • updateOrAddData
    • deleteRow
    • addRow
    • updateOrAddRow
    • updateRow
    • scrollToRow
    • scrollToColumn

    Promises are also now returned from some component object functions, which will be covered later in the release notes.

    Over the next few releases you will see promises being returned from more and more functions.

    Ajax

    The Ajax module has been completely overhauled to give you even more options for how you load your table data.

    Fetch

    Tabulator now uses the built in fetch API to make its ajax requests for data.

    This makes little difference to the exposed api endpoints but does now mean that any configuration options passed in for the request should now be compatible with the Fetch API

    URL Generator Function

    The new ajaxURLGenerator gives you more control over the url of the request that you can get from the ajaxURL and ajaxParams properties alone, you can pass in a callback to generate any URL you like.

    The callback should return a string representing the URL to be requested.

    var table = new Tabulator("#example-table", {
        ajaxURLGenerator:function(url, config, params){
            //url - the url from the ajaxURL property or setData function
            //config - the request config object from the ajaxConfig property
            //params - the params object from the ajaxParams property, this will also include any pagination, filter and sorting properties based on table setup
    
            //return request url
            return url + "?params=" + encodeURI(JSON.stringify(params)); //encode parameters as a json object
        },
    });

    Request Function

    The ajax module now uses a replaceable promise to make ajax requests.

    This means that the built in request functionality can easily be replaced to route the request to a different handler.

    In the example below we want to query a local JS realm db rather than makiing an ajax request so we pass a function that returns a promise to the ajaxRequestFunc option.

    function queryRealm(url, config, params){
    	//return promise
    	return new Promise(function(resolve, reject){
    		//do some async data retrieval then pass the array of row data back into Tabulator
    		resolve(data);
    	});
    }
    
    var table = new Tabulator("#example-table", {
    	ajaxRequestFunc:queryRealm,
    });

    Extensions Renamed to Modules

    In preparation for future updates to Tabulator the modular extensions that allow Tabulator to be packed full of features have now been renamed to Modules, and means that modules are now extended using the extendModule function:

    Tabulator.extendModule("format", "formatters", {
    	bold:function(cell, formatterParams){
    		return "" + cell.getValue() + ""; //make the contents of the cell bold
    	},
    });

    This is part of a bigger change that will be coming over the next year, on the roadmap to v5.0 where modules will become self contained pages of functionality that can inject functions onto the core Tabulator object and listen to lifecycle events from the table allowing anyone to write a module that can add awesome new features to Tabulator.

    Callback Context

    All callbacks now have the context of the Tabulator object so you can make calls to the table directly on the this variable.

    var table = new Tabulator("#example-table", {
        dataLoaded:function(data){
            var firstRow = this.getRows()[0];
    
            if(firstRow){
                firstRow.freeze();
            }
        },
    });

    Param Object Lookup Functions

    in all column definition parameter options you can now pass in a lookup function that returns an object instead of the object itself. This function will then be called any time the object is needed, this allows for parameters to be changed after table instantiation:

    //define lookup function
    function paramLookup(){
    	return {target:"_blank"};
    }
    
    //column definition
    {title:"Website", field:"url", formatter:"link", formatterParams:paramLookup}

    Currently this is available on the following column definition params:

    • sorterParams
    • formatterParams
    • editorParams
    • mutatorParams
    • mutatorDataParams
    • mutatorEditParams
    • mutatorClipboardParams
    • accessorParams
    • accessorDataParams
    • accessorDownloadParams
    • accessorClipboardParams
    • topCalcParams
    • topCalcFormatterParams
    • bottomCalcParams
    • bottomCalcFormatterParams
    • titleFormatterParams
    • headerFilterParams
    • headerFilterFuncParams

    Clipboard Styling

    The clipboard module has been update and now copies the tables style along with the data to give a better visual appearance when pasted into other documents.

    This functionality is included by default, if you want to only copy the unstyled data then you should set the clipboardCopyStyled option to false in the table options object:

    var table = new Tabulator("#example-table", {
    	clipboard:true,
    	clipboardCopyStyled:false,
    });

    SCSS Default Variables

    All SCSS file variables now use the !default property so you can override them from outside the imported source file.

    $backgroundColor:#f00; //change background color of table
    
    @import  "tabulator_simple"; //import table scss
    

    Formatters

    A number of changes have been made to the Formatters Module.

    onRendered Callback Function

    A new onRendered function is now passed into formatter functions, working in the same was as it does with editors, a function passed into this function will be triggered when the formatted cell is added to the DOM. This is useful when instantiating widgets that need the element to be visible before they are used.

    The example below uses the jQuery sparkline widget to format data into a chart

    var sparklineFormatter = function(cell, formatterParams, onRendered){
        onRendered(function(){
            $(cell.getElement()).sparkline(cell.getValue(), {width:"100%", type:"bar"});
        });
    };

    New Formatters

    Date Time Formatter

    The new datetime formatter has been added to allow conversion of data or time formats.

    This formatter requires the moment.js library to use

    {title:"Date of Birth", field:"dob", formatter:"datetime", formatterParams:{inputFormat:"DD/MM/YYYY hh:mm:ss", outputFormat:"YYYY-MM-DD hh:mm:ss", invalidPlaceholder:"Invalid Date"}}
    Date Time Diff Formatter

    The new datetimediff formatter will display in human readable terms the difference between two dates.

    This formatter requires the moment.js library to use

    {title:"Last Service", field:"service_date", formatter:"datetimediff", formatterParams:{inputFormat:"DD/MM/YYYY hh:mm:ss", humanize:true, suffix:true, nvalidPlaceholder:"Invalid Date"}}

    Updated Formatters

    A number of formatters have been updated

    Link Formatter

    The link formatter now takes a new target parameter to set the target for the anchor tag

    //open link in new tab
    {title:"Website", field:"url", formatter:"link", formatterParams:{target:"_blank"}}
    TickCross Formatter

    The tickCross formatter now takes two new formatterParams:

    The allowEmpty param will make the tick cross formatter show an empty cell instead of a cross if the cell has a value of undefined null or ""

    The allowTruthy param will make the tick cross formatter show a tick if the cell has any value that can be considered truthy

    {title:"Likes Cheese", field:"cheese", formatter:"tickCross", formatterParams:{allowEmpty:true, allowTruthy:true}}
    Image Formatter

    The image formatter now takes two new parameters, heigh and width to specify the dimensions of the image. they take any valid CSS value

    {title:"Logo", field:"logo", formatter:"image", formatterParams:{height:25, width:"50%"}}

    Filtering

    The filter module has had a number of upgrades:

    Initial Filters

    You can now set the initial filters to be applied to the table when it is first created, by passing an array of filters to the initialFilter table setup option:

    var table = new Tabulator("#example-table", {
    	initialFilter:[
    		{field:"color", type:"=", value:"red"}
    	],
    });

    Header Filter Empty Function

    The behaviour of empty header filters has been tweaked to improve usability. By default Tabulator will clear the filter when it considers the header filter value to be empty, in the case of most filters that is if the value is undefined, null, or "", or in the case of check boxes that is if the value is not either true or false.

    If you are using a custom filter or want to alter what an existing filter considers empty, you can pass a function to the headerFilterEmptyCheck column definition property. This function will be passed in the value of the filter as an argument and should return a boolean where true represents an empty filter

    {title:"Allowed", field:"allowed", headerFilter:"tick", headerFilterEmptyCheck:function(value){
        return !value; //only filter when the value is true
    }},
    

    New Filters

    Regex Filter

    The new regex filter function allows you to use the power of regular expressions to filter the data in your table.

    table.setFilter("name", "regex", /[a-z]/);

    History Availability

    This history module has been updated to include two new functions.

    Get Count of Available Undo Operations

    You can now use the getHistoryUndoSize function to get a count of the number of history undo actions available.

    var undoCount = table.getHistoryUndoSize();

    Get Count of Available Redo Operations

    You can now use the getHistoryRedoSize function to get a count of the number of history redo actions available.

    var redoCount = table.getHistoryRedoSize();

    Pagination URL

    The paginator property for generating the pagination URL has been removed, to be replaced with the more general purpose ajaxURLGenerator function.

    details of the new function can be found in the Ajax Documentation

    PDF Downloads

    The pdf downloader has been updated to allow a function to be passed to the autoTable option in its params object.

    This function should return the AutoTable options object. The jsPDF document object will be passed in as the first argument of this function which will allow you to call any of the jsPDF API functions on the document, so you can for example add additional text to your PDF or set the font.

    table.download("pdf", "data.pdf", {
        orientation:"portrait", //set page orientation to portrait
        autoTable:function(doc){
            //doc - the jsPDF document object
    
            //add some text to the top left corner of the PDF
            doc.text("SOME TEXT", 1, 1);
    
            //return the autoTable config options object
            return {
                styles: {
                    fillColor: [200, 00, 00]
                },
            };
        },
    });

    Column Headers

    The event binding order for click and touch events in the column header has now been changed so that events bound from the column definition like headerClick are now bound before any internal events like the click that triggers a header sort. This means you can now block other event bindings after the click using the events stopImmediatePropagation function

    {title:"Name", field:"name", headerClick:function(e){
    	e.stopImmediatePropagation(); //block header sort or other click triggered events from happening
    }},

    Row Component

    The row component has had been updated

    Promises

    The following row component functions now return a promise

    • update
    • delete
    • scrollTo

    New Component Functions

    The following new functions have been added to the row component.

    getTable function

    The new getTable function will return the Tabulator instance for the table that contains the row.

    var table = row.getTable();
    isSelected function

    The new isSelected function will return a boolean representing the current selection state of the row

    var selected = row.isSelected();

    Column Component

    The column component has had been updated

    Component Lookup

    getColumn function

    You can now call the getColumn function to look up a column component by either its field or header DOM element

    var column = table.getColumn("age");

    Promises

    The following column component functions now return a promise

    • scrollTo

    New Component Functions

    getTable function

    The new getTable function will return the Tabulator instance for the table that contains the column.

    var table = column.getTable();
    headerFilterFocus function

    The new headerFilterFocus function will put focus on the header filter element for this column.

    column.headerFilterFocus();
    setHeaderFilterValue function

    The new setHeaderFilterValue function will change the value of header filter element for this column.

    column.setHeaderFilterValue("Bob");
    reloadHeaderFilter function

    The new reloadHeaderFilter function will rebuild the header filter, updating any params passed into the editor used to generate the filter.

    column.reloadHeaderFilter();

    Cell Component

    The cell component has had been updated

    getTable function

    The new getTable function will return the Tabulator instance for the table that contains the cell.

    var table = cell.getTable();

    Group Component

    The group component has had been updated

    getTable function

    The new getTable function will return the Tabulator instance for the table that contains the group.

    var table = group.getTable();

    Bug Fixes

    The following minor bugs have been fixed:

    • The groupStartsOpen function is now correctly passed the component object
    • Header filters in frozen columns are now correctly counted when calculating the header height
    • The data mutator is now only triggered on updated data fields when a row is updated, rather than on all row data
    • Ajax sorting and filtering now expect the correct returned data format when triggering an ajax request
    • Render issues when columns were frozen on the right hand side of the table have been resolved
    • The rowDeselected callback is nor correctly triggered for each row when all rows are deselected at once
    • An incorrect event binding in the olumn resize module has been fixed
    • Validators now correctly handle paramerters that include the : character
    • The textarea formatter now correctly handles null and undefined values
    • Fixed the force argument on the Cell Component edit function
    • Column movement by mouse drag is now only triggered off of left click instead of any mouse clicks
    • Row movement by mouse drag is now only triggered off of left click instead of any mouse clicks
    • Bug in row height normalization on row shrinking fixed
    • Fixed an issue with tabbing out of the number editor on IE reseting the cells value
    • Fixed issue in progress formatter color params
    • Pasting into empty tables on Chrome now works
    • Graphical corruption of certain arrangements of grouped headers has now been resolved
    • Row height normalization calculations now correctly take into account any row contents other than cells

    Removal Of Deprecated Functionality

    All functionality marked as deprecated in version 3.5 has now been removed. If you are still using any of the functionality outlined below you will need to update it to the new methodology.

    Download Data Mutator

    Deprecated Function

    Setting the data download mutation function using the downloadDataMutator option:

    $("#example-table").tabulator({
    	downloadDataMutator:function(){},
    });
    Replacement Function

    This has been replaced with the downloadDataFormatter option:

    new Tabulator("#example-table", {
    	downloadDataFormatter:function(){},
    });

    Mutation Type

    Deprecated Function

    Binding the mutator callback to a given type of mutation using the mutateType option:

    {title:"age", field:"age", mutator:ageMutator, mutatorParams:{limit:18}, mutateType:"edit"}
    Replacement Function

    You should now use the mutator option matching the type of event you want to bind to:

    {title:"age", field:"age", mutatorEdit:ageMutator, mutatorEditParams:{limit:18}}

    Persistence ID

    Deprecated Function

    Setting the persistent storage ID using the persistentLayoutID option:

    $("#example-table").tabulator({
    	persistentLayoutID:"table1",
    });
    Replacement Function

    This has been replaced with the persistenceID option:

    new Tabulator("#example-table", {
    	persistenceID:"table1",
    });

    Persistence Mode

    Deprecated Function

    Enabling column layout persistence and setting the persistent storage mode using the persistentLayout option:

    $("#example-table").tabulator({
    	persistentLayout:"cookie", //enable persistent column layout and set id
    });
    Replacement Function

    You should now set the storage mode using the persistenceMode option and enable persistent column layouts with the persistentLayout option:

    new Tabulator("#example-table", {
    	persistenceMode:"cookie", //set persistent storage mode
    	persistentLayout:true, //enable persistent column layout
    });

    Email Formatter

    Deprecated Function

    Creating a mailto link using the email formatter:

    {title:"Email", field:"email", formatter:"email"}
    Replacement Function

    This has been replaced with the link formatter with the new formatterParams of urlPrefix set to mailto::

    {title:"Email", field:"email", formatter:"link", formatterParams:{urlPrefix:"mailto:"}}

    fitColumns Setup Option

    Deprecated Function

    Setting the layout mode to fitColumns using the fitColumns option:

    $("#example-table").tabulator({
    	fitColumns:true, //enable fit columns layout mode
    });
    Replacement Function

    This has been replaced with the layout option which allows the mode to be set to a number of different options including fitColumns:

    new Tabulator("#example-table", {
    	layout:"fitColumns", //enable fitColumns layout mode
    });

    Get Filters

    Deprecated Function

    Getting the current filters using the getFilter function:

    var filters = $("#example-table").tabulator("getFilter");
    Replacement Function

    This has been replaced with the getFilters function:

    var filters = table.getFilters();

    Get Sorters

    Deprecated Function

    Getting the current sorters using the getSort function:

    var sorters = $("#example-table").tabulator("getSort");
    Replacement Function

    This has been replaced with the getSorters function:

    var sorters = table.getSorters();

    Header Tooltip

    Deprecated Function

    Setting a columns header tooltip using the tooltipHeader property in its column definition array:

    {title:"name", field:"name", width:40, align:"center", tooltipHeader:true},
    Replacement Function

    This has been replaced with the headerTooltip property:

    {title:"name", field:"name", width:40, align:"center", headerTooltip:true},

    Ajax Sort Parameters

    Ajax sorting now sends all current sorts instead of just the first, for more information checkout the Ajax Sorting Documentation

    Deprecated Function

    Setting the sort and sort_dir properties in the paginationDataSent option:

    $("#example-table").tabulator({
    	paginationDataSent:{
    		"sort":"sort",
    		"sort_dir":"sort_dir",
    	}
    });
    Replacement Function

    Sort data is now passed as an array to the sorters property of the paginationDataSent option:

    new Tabulator("#example-table", {
    	paginationDataSent:{
    		"sorters":"sorters",
    	}
    });

    Ajax Filter Parameters

    Ajax sorting now sends all current filters instead of just the first, for more information checkout the Ajax Filtering Documentation

    Deprecated Function

    Setting the filter, filter_value and filter_type properties in the paginationDataSent option:

    $("#example-table").tabulator({
    	paginationDataSent:{
    		"filter":"filter",
    		"filter_value":"filter_value",
    		"filter_type":"filter_type",
    	}
    });
    Replacement Function

    Filter data is now passed as an array to the filters property of the paginationDataSent option:

    new Tabulator("#example-table", {
    	paginationDataSent:{
    		"filters":"filters",
    	}
    });