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 Compatability

The data reactivity module has been built to be compatable 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 itterate 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 successfuly 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

Alternativly 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 formater 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 interpereted across didfferent 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 returing 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 beween 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 seperators
  • the nextPage and prevPage functions now correctly return promises