Easy Data Table Generator with JSON - Tabulator

File Size: 3.52 MB
Views Total: 48206
Last Update:
Publish Date:
Official Website: Go to website
License: MIT
   
Easy Data Table Generator with JSON - Tabulator

The tabulator currently is a PURE JavaScript plugin since 4.0.

Tabulator is a feature-rich jQuery/JavaScript plugin used for generating simple or complex data tables from any JSON data, with the following additional features:

  • JSON, array or AJAX data loading
  • High performant large table based on virtual DOM
  • Column sorting
  • Custom data formatting
  • Resizable columns
  • Auto scaling to fit data/element
  • Many theming options
  • Custom click and context Events
  • Callbacks at every stage of data processing and rendering
  • Data filtering.

How to use it (4.0+):

1. Install it with package managers.

# Yarn
$ yarn add tabulator-tables

# NPM
$ npm i tabulator-tables

2. Import the Tabulator library and optional stylesheet as follows:

<!-- Core -->
<link href="dist/css/tabulator.min.css" rel="stylesheet">
<script src="dist/js/tabulator.min.js"></script>
<!-- jQuery Wrapper Optional -->
<script src="dist/js/jquery_wrapper.min.js"></script>
// OR As An ES Module
mport {TabulatorFull as Tabulator} from 'tabulator-tables';
@import  "~/tabulator-tables/dist/css/tabulator.min.css"; 
// OR Use ESM Import
import {Tabulator} from 'https://unpkg.com/tabulator-tables@/dist/js/tabulator_esm.min.js';

3. Create a container to place the generated table.

<div id="myTable"></div>

4. Define your tabular data in an array.

var myData = [
    {id:1, name:"Oli Bob", age:"12", col:"red", dob:""},
    {id:2, name:"Mary May", age:"1", col:"blue", dob:"14/05/1982"},
    {id:3, name:"Christine Lobowski", age:"42", col:"green", dob:"22/05/1982"},
    {id:4, name:"Brendon Philips", age:"125", col:"orange", dob:"01/08/1980"},
    {id:5, name:"Margret Marmajuke", age:"16", col:"yellow", dob:"31/01/1999"},
 ];

5. Generate a basic data table from the data you provide.

var table = new Tabulator("#myTable", {
    data: myData,
    columns:[
      {title:"Name", field:"name", maxWidth:200},
      {title:"Age", field:"age"},
      {title:"Gender", field:"gender"},
      {title:"Height", field:"height", maxWidth:80},
      {title:"Favourite Color", field:"col"},
      {title:"Date Of Birth", field:"dob"},
      {title:"Likes Cheese", field:"cheese"},
      {title:"Example", field:"example", formatter:"image", formatterParams:{urlPrefix:"http://website.com/images/"}}
    ]
    // configuration options here
});

6. Append multi-level context menus to the table.

var table = new Tabulator("#myTable", {
    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
              }
            }, ]
          }
        ]
      }
    ]
});

7. All possible configuration options.

var table = new Tabulator("#myTable", {    

    // height of tabulator
    height: false, 

    // minimum height of tabulator
    minHeight: false, 

    // maximum height of tabulator
    maxHeight: false, 

    // "fitColumns" | "fitData" | "fitDataTable"
    layout: "fitData", 

    // update column widths on setData
    layoutColumnsOnNewData: false, 

    // minimum global width for a column
    columnMinWidth: 40, 

    // minimum global width for a column
    columnMaxWidth: false, 

    // vertical alignment of column headers
    columnHeaderVertAlign: "top", 

    // resizable columns
    resizableColumns: true, 

    // resizable rows
    resizableRows: false, 

    // auto resize table
    autoResize: true, 

    // column header here
    columns: [], 

    // horizontal alignment
    cellHozAlign: "", 

    // vertical alignment
    cellVertAlign: "",

    // tabular data here
    data: [],

    // auto-build columns from data row structure
    autoColumns: false, 

    // enable data reactivity
    reactiveData: false, 

    // seperatpr for nested data
    nestedFieldSeparator: ".", 

    // enable tooltips
    tooltips: false,

    // enable tooltips on headers
    tooltipsHeader: false,

    // when to generate tooltips
    tooltipGenerationMode: "load", 

    // initial sorting criteria
    initialSort: false, 

    // initial filtering criteria
    initialFilter: false, 

    // initial header filtering criteria
    initialHeaderFilter: false, 

    // multiple or single column sorting
    columnHeaderSortMulti: true,

    // reverse internal sort ordering
    sortOrderReverse: false, 

    // set default global header sort
    headerSort: true, 

    // set default tristate header sorting
    headerSortTristate: false, 

    // hold footer element
    footerElement: false, 

    // filed for row index
    index: "id", 

    // array for keybindings
    keybindings: [], 

    // create new row when tab to end of table
    tabEndNewRow: false, 

    // allow toggling of invalid option warnings
    invalidOptionWarnings: true, 

    // enable clipboard
    clipboard: false, 

    // formatted table data
    clipboardCopyStyled: true, 

    // clipboard config
    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
      formatCells:false, //show raw cell values without formatter
    },

    // restrict clipboard to visible rows only
    clipboardCopyRowRange: "active", 

    // convert pasted clipboard data to rows
    clipboardPasteParser: "table", 

    // how to insert pasted data into the table
    clipboardPasteAction: "insert", 

    // data has been copied to the clipboard
    clipboardCopied: function clipboardCopied() {}, 

    // data has been pasted into the table
    clipboardPasted: function clipboardPasted() {}, 

    // data has not successfully been pasted into the table
    clipboardPasteError: function clipboardPasteError() {}, 

    // function to manipulate table data before it is downloaded
    downloadDataFormatter: false, 

    // function to manipulate download data
    downloadReady: function downloadReady(data, blob) {
      return blob;
    }, 

    // function to manipulate download data
    downloadComplete: false, 

    // download configs
    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
    }, 

    // restrict download to active rows only
    downloadRowRange: "active", 

    // enable data tree
    dataTree: false, 

    dataTreeElementColumn: false,

    // show data tree branch element
    dataTreeBranchElement: true, 

    //data tree child indent in px
    dataTreeChildIndent: 9, 

    //data tree column field to look for child rows
    dataTreeChildField: "_children", 

    // data tree row collapse element
    dataTreeCollapseElement: false, 

    // data tree row expand element
    dataTreeExpandElement: false, 

    // data tree start expand element
    dataTreeStartExpanded: false,

    // row has been expanded
    dataTreeRowExpanded: function dataTreeRowExpanded() {}, 

    // row has been collapsed
    dataTreeRowCollapsed: function dataTreeRowCollapsed() {}, 

    // include visible data tree rows in column calculations
    dataTreeChildColumnCalcs: false, 

    // seleccting a parent row selects its children
    dataTreeSelectPropagate: false, 

    // enable print as html
    printAsHtml: false, 

    // print formatter
    printFormatter: false, 

    // page header
    printHeader: false, 

    // page footer
    printFooter: false, 

    // enable styles while priting
    printStyled: true, //enable print as html styling

    // restrict print to visible rows only
    printRowRange: "visible", 

    // print configs
    printConfig: {
      columnHeaders:false, //do not include column headers in printed table
      columnGroups:false, //do not include column groups in column headers for printed table
      rowGroups:false, //do not include row groups in printed table
      columnCalcs:false, //do not include column calcs in printed table
      dataTree:false, //do not include data tree in printed table
      formatCells:false, //show raw cell values without formatter
    }, 

    // or 'top'
    addRowPos: "bottom",

    // highlight rows on hover
    selectable: "highlight", 

    // highlight rows on hover
    selectableRangeMode: "drag", 

    // roll selection once maximum number of selectable rows is reached
    selectableRollingSelection: true, 

    // maintain selection when table view is updated
    selectablePersistence: true, 

    // check wheather row is selectable
    selectableCheck: function selectableCheck(data, row) {
      return true;
    }, 

    // delay before updating column after user types in header filter
    headerFilterLiveFilterDelay: 300, 

    // placeholder text to display in header filters
    headerFilterPlaceholder: false,

    // hide header
    headerVisible: true, 

    // enable edit history
    history: false,

    // current system language
    locale: false, 

    langs: {
      "en":{
        "pagination":{
          "all":"All",
        }
      },
    },

    // enable virtual DOM
    virtualDom: true, 

    // set virtual DOM buffer size
    virtualDomBuffer: 0, 

    // key for persistent storage
    persistenceID: "", 

    // mode for storing persistence information
    persistenceMode: true, 

    // function for handling persistence data reading
    persistenceReaderFunc: false, 

    // function for handling persistence data writing
    persistenceWriterFunc: false, 

    // enable persistence
    persistence: false,

    // enable responsive layout
    responsiveLayout: false, 

    // show collapsed data on start
    responsiveLayoutCollapseStartOpen: true, 

    // collapse formatter
    responsiveLayoutCollapseUseFormatters: true, 

    // responsive layout collapse formatter
    responsiveLayoutCollapseFormatter: false, 

    // set pagination type: "remote", or "local"
    pagination: false, 

    // number of rows per page
    paginationSize: false, 

    // initial page on page load
    paginationInitialPage: 1,

    // set count of page button
    paginationButtonCount: 5, 

    // add pagination size selector element
    paginationSizeSelector: false, 

    // element to hold pagination numbers
    paginationElement: false,

    // pagination data sent to the server
    paginationDataSent: {}, 

    // pagination data received from the server
    paginationDataReceived: {}, 

    // add rows on table or page
    paginationAddRow: "page", 

    // url for ajax loading
    ajaxURL: false, 

    // called with the scope of the table so you can now access the parent table on the this variable
    ajaxURLGenerator: function(url, config, params){},

    // params for ajax loading
    ajaxParams: {}, 

    // ajax request type
    ajaxConfig: "get", 

    // ajax request type
    ajaxContentType: "form", 

    // promise function
    ajaxRequestFunc: false, 

    // show loader
    ajaxLoader: true, 

    // loader element
    ajaxLoaderLoading: false, 

    // loader element
    ajaxLoaderError: false, 

    ajaxFiltering: false,

    ajaxSorting: false,

    // progressive loading
    ajaxProgressiveLoad: false, 

    // delay between requests
    ajaxProgressiveLoadDelay: 0, 

    // margin before scroll begins
    ajaxProgressiveLoadScrollMargin: 0, 

    // enable table grouping and set field to group by
    groupBy: false, 

    // starting state of group
    groupStartOpen: true, 

    groupValues: false,

    // header generation function
    groupHeader: false, 

    groupHeaderPrint: null,

    groupHeaderClipboard: null,

    groupHeaderHtmlOutput: null,

    groupHeaderDownload: null,

    // html output configs
    htmlOutputConfig: false, 

    // enable movable columns
    movableColumns: false, 

    // enable movable rows
    movableRows: false, 

    // tables for movable rows to be connected to
    movableRowsConnectedTables: false, 

    // other elements for movable rows to be connected to
    movableRowsConnectedElements: false, 

    movableRowsSender: false,

    movableRowsReceiver: "insert",

    movableRowsSendingStart: function movableRowsSendingStart() {},

    movableRowsSent: function movableRowsSent() {},

    movableRowsSentFailed: function movableRowsSentFailed() {},

    movableRowsSendingStop: function movableRowsSendingStop() {},

    movableRowsReceivingStart: function movableRowsReceivingStart() {},

    movableRowsReceived: function movableRowsReceived() {},

    movableRowsReceivedFailed: function movableRowsReceivedFailed() {},

    movableRowsReceivingStop: function movableRowsReceivingStop() {},

    movableRowsElementDrop: function movableRowsElementDrop() {},

    scrollToRowPosition: "top",

    scrollToRowIfVisible: true,

    scrollToColumnPosition: "left",

    scrollToColumnIfVisible: true,

    rowFormatter: false,

    rowFormatterPrint: null,

    rowFormatterClipboard: null,

    rowFormatterHtmlOutput: null,

    placeholder: false,

    // table building callbacks

    tableBuilding: function tableBuilding() {},

    tableBuilt: function tableBuilt() {},

    // render callbacks

    renderStarted: function renderStarted() {},

    renderComplete: function renderComplete() {},

    // row callbacks

    rowClick: false,

    rowDblClick: false,

    rowContext: false,

    rowTap: false,

    rowDblTap: false,

    rowTapHold: false,

    rowMouseEnter: false,

    rowMouseLeave: false,

    rowMouseOver: false,

    rowMouseOut: false,

    rowMouseMove: false,

    rowContextMenu: false,

    rowAdded: function rowAdded() {},

    rowDeleted: function rowDeleted() {},

    rowMoved: function rowMoved() {},

    rowUpdated: function rowUpdated() {},

    rowSelectionChanged: function rowSelectionChanged() {},

    rowSelected: function rowSelected() {},

    rowDeselected: function rowDeselected() {},

    rowResized: function rowResized() {},

    // cell callbacks

    // row callbacks

    cellClick: false,

    cellDblClick: false,

    cellContext: false,

    cellTap: false,

    cellDblTap: false,

    cellTapHold: false,

    cellMouseEnter: false,

    cellMouseLeave: false,

    cellMouseOver: false,

    cellMouseOut: false,

    cellMouseMove: false,

    cellEditing: function cellEditing() {},

    cellEdited: function cellEdited() {},

    cellEditCancelled: function cellEditCancelled() {},

    // column callbacks

    columnMoved: false,

    columnResized: function columnResized() {},

    columnTitleChanged: function columnTitleChanged() {},

    columnVisibilityChanged: function columnVisibilityChanged() {},

    // HTML import callbacks

    htmlImporting: function htmlImporting() {},

    htmlImported: function htmlImported() {},

    // data callbacks

    dataLoading: function dataLoading() {},

    dataLoaded: function dataLoaded() {},

    dataEdited: function dataEdited() {},

    // ajax callbacks

    ajaxRequesting: function ajaxRequesting() {},

    ajaxResponse: false,

    ajaxError: function ajaxError() {},

    // filtering callbacks

    dataFiltering: false,

    dataFiltered: false,

    // sorting callbacks

    dataSorting: function dataSorting() {},

    dataSorted: function dataSorted() {},

    // grouping callbacks

    groupToggleElement: "arrow",

    groupClosedShowCalcs: false,

    dataGrouping: function dataGrouping() {},

    dataGrouped: false,

    groupVisibilityChanged: function groupVisibilityChanged() {},

    groupClick: false,

    groupDblClick: false,

    groupContext: false,

    groupContextMenu: false,

    groupTap: false,

    groupDblTap: false,

    groupTapHold: false,

    columnCalcs: true,

    // pagination callbacks

    pageLoaded: function pageLoaded() {},

    // localization callbacks

    localized: function localized() {},

    // validation callbacks

    validationMode: "blocking",

    validationFailed: function validationFailed() {},

    // history callbacks

    historyUndo: function historyUndo() {},

    historyRedo: function historyRedo() {},

    // scroll callbacks

    scrollHorizontal: function scrollHorizontal() {},

    scrollVertical: function scrollVertical() {}
    
});

7. API methods.

// replace data
table.replaceData([{id:1, name:"bob", gender:"male"}, {id:2, name:"Jenny", gender:"female"}]) 
table.replaceData("data.php") 
table.replaceData() // reload
table.replaceData(tableData)
.then(function(){
    //run code after table has been successfuly updated
})
.catch(function(error){
    //handle error loading data
});

// update data
table.updateData([{id:1, name:"bob", gender:"male"}, {id:2, name:"Jenny", gender:"female"}]);
table.updateData([{id:1, name:"bob"}])
.then(function(){
    //run code after data has been updated
})
.catch(function(error){
    //handle error updating data
});

// add data
table.addData([{id:6, name:"bob", gender:"male"}, {id:7, name:"Jenny", gender:"female"}], true, 3); //add new data above existing row with index of 3
table.addData([{id:1, name:"bob", gender:"male"}, {id:2, name:"Jenny", gender:"female"}], true)
.then(function(rows){
    //rows - array of the row components for the rows updated or added

    //run code after data has been updated
})
.catch(function(error){
    //handle error updating data
});

// update or add data
table.updateOrAddData([{id:1, name:"bob"}, {id:3, name:"steve"}]);
table.updateOrAddData([{id:1, name:"bob"}, {id:3, name:"steve"}])
.then(function(rows){
    //rows - array of the row components for the rows updated or added

    //run code after data has been updated
})
.catch(function(error){
    //handle error updating data
});

// clear data
table.clearData();

// get data
table.getData();
table.getData("active");
table.getDataCount();
table.getDataCount("active");
row.getData();
table.getRows();
able.getRows("active");

// add row
table.addRow({name:"Billy Bob", age:"12", gender:"male", height:1}, true)
.then(function(row){
  // ...
})
.catch(function(error){
  ...
});

// update row
table.updateRow(1, {id:1, name:"bob", gender:"male"});
row.update({"name":"steve"})
.then(function(){
  // ...
})
.catch(function(error){
  // ...
});

// update or add row
table.updateOrAddRow(3, {id:3, name:"steve", gender:"male"});
table.updateOrAddRow(3, {id:3, name:"steve", gender:"male"})
.then(function(){
  // ...
})
.catch(function(error){
  // ...
});

// get row element
table.getRow(1);
row.getElement();

// delete row
table.deleteRow(15);
table.deleteRow([15,7, 9]);
row.delete();
table.deleteRow(15)
.then(function(){
  // ...
})
.catch(function(error){
  // ...
});
row.delete()
.then(function(){
  // ...
})
.catch(function(error){
  // ...
});

// set order
table.setSort("age", "asc");
table.setSort([
    {column:"age", dir:"asc"}, //sort by this first
    {column:"height", dir:"desc"}, //then sort by this second
]);

// get sorters
table.getSorters();

// clear all sorters
table.clearSort();

// table validation
table.validate();
row.validate();
column.validate();
cell.validate();

// get invalid cells
table.getInvalidCells();

// check if is valid
cell.isValid();

// clear cell validation
cell.clearValidation();
table.clearCellValidation();
table.clearCellValidation([cell1, cell2]);

// set filter
table.setFilter("age", ">", 10);
table.setFilter("name", "like", "teve");
table.setFilter("age", "in", ["steve", "bob", "jim"]);
table.setFilter("age", "regex", /[a-z]/);
table.setFilter(customFilter, {height:3});
table.setFilter([
    {field:"age", type:">", value:52}, //filter by age greater than 52
    [
        {field:"height", type:"<", value:142}, //with a height of less than 142
        {field:"name", type:"=", value:"steve"}, //or a name of steve
    ]
]);

// add filter
table.addFilter("age", ">", 22);

// remove filter
table.removeFilter("age", ">", 22);

// get filters
table.getFilters();

// refresh current filter
table.refreshFilters();

// clear history
table.clearHistory();

// get header filters
table.getHeaderFilters();

// clear all filters
table.clearFilter();
table.clearFilter(true);
table.clearHeaderFilter();

// set header filter value
table.setHeaderFilterValue("name", "Steve");

// get header filter value
table.getHeaderFilterValue("name");
table.getHeaderFilterValue();

// focus On Header Filter
table.setHeaderFilterFocus("name");

// search data
table.searchRows("age", ">", 12);
table.searchData("age", ">", 12);

// get row position
table.getRowPosition(row, true);
table.getRowFromPosition(5, true)

// retrieve data as HTML Table
table.getHtml();
table.getHtml("visible", true, {columnGroups:false});

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

// get calculation results
table.getCalcResults();

How to use it (jQuery):

1. Load the necessary jQuery and Tabulator libraries in the html page.

<link href="dist/css/tabulator.min.css" rel="stylesheet">
<script src="dist/js/tabulator.min.js"></script>

2. Just load the jQuery Tabulator wrapper after jQuery library and we're ready to go.

<script src="jquery_wrapper.min.js"></script>

3. Generate a simple data table inside the container 'demo' from the JSON data you specify during initialization.

$("#demo").tabulator({
  data:[
    {id:1, name:"Oli Bob", age:"12", col:"red", dob:""},
    {id:2, name:"Mary May", age:"1", col:"blue", dob:"14/05/1982"},
    {id:3, name:"Christine Lobowski", age:"42", col:"green", dob:"22/05/1982"},
    {id:4, name:"Brendon Philips", age:"125", col:"orange", dob:"01/08/1980"},
    {id:5, name:"Margret Marmajuke", age:"16", col:"yellow", dob:"31/01/1999"},
  ],
  columns:[
    {title:"Name", field:"name", maxWidth:200},
    {title:"Age", field:"age"},
    {title:"Gender", field:"gender"},
    {title:"Height", field:"height", maxWidth:80},
    {title:"Favourite Color", field:"col"},
    {title:"Date Of Birth", field:"dob"},
    {title:"Likes Cheese", field:"cheese"},
    {title:"Example", field:"example", formatter:"image", formatterParams:{urlPrefix:"http://website.com/images/"}}
  ]
});

Changelog:

v6.2.5 (2024-09-30)

  • Improved Dependency Management
  • Loads of new Import functionality
  • Adaptive Formatters & Editors
  • Improved Sorters
  • New Formatters
  • Import Mutators

v6.2.5 (2024-07-22)

  • Updates and Fixes

v6.2.4 (2024-07-17)

  • Add fixed size for group div to fix alignment with not default window browser zoom

v6.2.2 (2024-07-15)

  • Fixed alignment issues when browser is zoomed into table

v6.2.1 (2024-04-29)

  • Range selection with column moving now works correctly
  • Focus is now correctly restored after range selection
  • Range selection will no longer accidentally select the row header when using keyboard navigation
  • The getCells function on the range component now correctly returns cell components
  • Improved cell range jump navigation in large data sets
  • Navigation focus maintained when scrolling
  • Fixed node version issue in linter config
  • Fixed issue with popup lists not fitting on screen

v6.2.0 (2024-03-29)

  • Toggle Formatter, AutoColumns Updates & Events

v6.1.0 (2024-03-25)

  • Spreadsheet Importer

v6.0.0 (2024-03-20)

  • Fix regression breaking autoColumns on initial load of ajax data

v6.0.0 (2024-03-17)

  • ESM Tree Shaking is fully working now!
  • Build tools have been upgraded to the latest versions
  • New features for module builders
  • Row headers
  • Spreadsheet module, grid generation, array format data handling
  • Resize guides
  • Editor empty value handling
  • Improved range exporting
  • Rownum accessor for export
  • New Events
  • Performance improvements for data trees
  • A load of bug fixes

v5.6.1 (2024-02-19)

  • Bugfixes

v5.6.0 (2024-02-13)

v5.5.4 (2024-01-28)

  • The link formatter now correctly handles nested data lookup from the urlField formatter param

v5.5.3 (2024-01-22)

  • The link formatter now correctly handles nested data lookup from the urlField formatter param
  • The tabEndNewRow option will now not create a new row if there is a validation failure on the last table cell when it is bing edited
  • Fixed issue with row management pipeline not being fully initialized with remote data loading
  • Ensure nestedFieldSeparator option is correctly applied when handling row updates
  • The setColumnLayout function now correctly applies all settings passed into the function, not just those currently set in a columns definition
  • Ajax params passed to the setData function now correctly override those set in the ajaxParams setup option
  • Removed incorrect mouse pointer from disabled pagination buttons
  • The setPageToRow function will no longer throw an error when called

v5.5.2 (2023-08-28)

  • Bugfixes

v5.5.1 (2023-07-24)

  • The data argument of the groupHeader callback is now passed an array of all data included in that group, including child rows when using nested groups
  • Fixed console error when redrawing the table with the dataTree option enabled
  • If a table is destroyed, any outstanding ajax request responses are ignored
  • Fixed function mapping issue on jQuery wrapper
  • The placeholder element is now visible on empty tables with no fixed height
  • The history module undo and redo actions for row movement, now move the row to the correct position
  • The history module undo and redo actions for row movement, now correctly redraw the table after the action is performed
  • The groupClick and groupDblClick events are now correctly triggered when the groupToggleElement option is set to header and the group header element is clicked
  • Fixed visual corruption when using frozen columns and the materialize theme
  • Fixed visual corruption when using frozen columns and the semantic-ui theme
  • Fixed regression in onRendered function passed into formatters, it is now correctly called after a cell has been added to the DOM
  • Fixed regression in cell height calculation for basic vertical renderer
  • Row indentation now works correctly when using the dataTree option with the dataTreeBranchElement option set to false

v5.5.0 (2023-05-22)

  • Tap events are no longer erroneously triggered when scrolling the table
  • Hover styling for all elements has been suppressed on mobile devices
  • Using a horizontal scroll wheel in the table header will now cause the table to scroll horizontally
  • The list eidtor now handles tab behaviour in a similar fashion to other editors, selecting the currently focused element in the list when the tab key is pressed
  • Fixed a header alignment issue in the modern theme CSS
  • Fixed console error when destroying tables with selected rows
  • Fix typo in datatree module getRows function
  • The table will correctly scroll to focus on cells being edited when they are tabbed to.
  • Calling the updateDefinition function on a Column Component will no longer cause a console error when changing the frozen column option

v5.4.4 (2023-02-20)

  • Prevent recursive issue of cell generation when rapidly calling updateData function
  • Fix incorrect content type passed to component function binder for GroupComponent
  • Fixed issue with incorrect data being passed to the second argument of the internal row-added event
  • Improve experience of data and time pickers while editing
  • Fix regression in last patch release causing unusual focus behaviour on header filters on table initialization
  • Left and right navigation keys are now usable in the list editor when auatocomplete mode is enabled
  • Odd/Even row styling is now correctly maintained when new rows are added to the top of the table
  • The rownum formatter now works correctly when new rows are added to the top of the table
  • Custom column definition options are now available via the getDefinition function on the column component.
  • Fixed regression in debugInvalidOptions setup option
  • The rowSelectionChanged event is no longer needlessly fired on table initialization
  • Fixed issue with new rows being added to the table causing a miscalculation in grouped headers
  • Fixed regression in the tabEndNewRow option
  • Deleting a row during the focus process of an editor no longer results in a console error
  • Vertical positioning of the placeholder element has been corrected
  • Fixed redraw issue when using the basic renderer
  • Moving a row between groups should no longer cause a console exception when the start group is now empty
  • When the updateData function is called on a row, only mutators on the changed fields will be called
  • the fitColumns layout now correctly renders without a gap to the side of the table when the table has a variable height
  • Table height and scrollbars are now correctly calculated when both the minHeight and maxHeight options are used together
  • Adding new rows to the table no longer results in a change in vertical scroll position
  • Fixed visual glitch when using frozen rows on a table with a large number of columns
  • Fixed visual glitch when using top calculation on a table with a large number of columns
  • Triggering a focus event inside an editor while it is in use will no longer reinitialize the editor
  • The tickCross editor now works correctly on the Safari browser
  • Improved console warning messaging for date, time and datetime editors
  • Fixed formatted editor output for date, time and datetime editors when format param is set to true
  • Fixed formatted editor output for date, time and datetime editors when format param is set to iso
  • Enabled up/down arrow keys to increment/decrement values in date editors

v5.4.3 (2022-12-05)

  • When using a mask on an editor, ctrl and meta key actions are now allowed through
  • Improved efficiency of row formatting in export module
  • The updateData function now correctly rejects its returned promise if invalid row data is passed to it.
  • The addRow function now correctly adds rows to the table in the position defined
  • Updating the headerFilterPlaceholder column definition option with the updateDefinition function on the column component now works correctly
  • Row selection is now correctly restricted to actual rows only, not calculation rows or group headers
  • The onRendered callback is now correctly triggered for editors when used as header filters
  • The export module will now only map default styles over an element if it does not already have those styles set
  • When formatting a row on export, the getElement function on row component passed to the formatter will now correctly return the exported element
  • Bugfixes

v5.4.2 (2022-10-17)

  • Fixed regression in grouped rows module that resulted in a console error when editing a cell when the groupUpdateOnCellEdit option was used
  • Movable columns now correctly scroll the header when moving columns off the visible area of the table
  • The scrollToColumn function and column component scrollTo function now work when using grouped columns
  • The default columnCalcs option value of true now correctly hides the table column calculations when grouping is enabled, even when the group by value isnt in an array
  • When using the columnCalcs option with value of true and row grouping enabled, when you add or remove grouping using the setGroupBy function, the table level calculation rows will now be correctly added and removed as needed

v5.4.1 (2022-10-09)

  • The list editor now correctly filters on the first character when a user types
  • Fixed a render glitch in the horizontal virtual DOM where scrolling in a circle round the table would result in column misalignment
  • The Group Rows module now cleans up old row components when the groups are regenerated
  • Fixed a regression in last release that prevented header filters from scrolling into view when tabbed into focus

v5.4.0 (2022-10-04)

  • Big Performance Improvements

v5.3.4 (2022-09-08)

  • Fixed regression in row lookup functionality that prevented the legacy value of true from returning the current rows array
  • The minimum table holder width is now correctly removed even if no placeholder is set
  • Minimum column header height is now correctly applied to the headers container element rather than the header element, which was hiding frozen rows
  • Frozen rows are now visible on paginated tables with no height set

v5.3.3 (2022-09-05)

  • Removed legacy display index functionality from modules
  • Fixed scope issue in persistence module when tracking column definition props
  • Making changes to the table now works without exception after disabling grouping by passing a value of false to the setGroupBy function
  • The column headers now correctly maintain their height when only frozen columns are visible
  • Table holder min-width is now correctly cleared when the empty table placeholder is removed
  • Update getRows function to return an empty array when an invalid row range lookup value is used
  • Fix issue with row selection on an invalid string type index causing all rows to be selected
  • Striping of rows in the bootstrap themes is correctly applied when the table-striped class is applied to the table

v5.3.2 (2022-08-22)

  • Fixed issue with unresolved promise returned from updateData function when data has a length of 0
  • Fixed issue with table attempting to redraw data while it is being destroyed
  • Interaction events in child nested tables no longer cause an exception in the parent table when triggered
  • Using the headerSortElement option with the headerSort column definition option no longer causes an exception
  • Double clicking on editable cells no longer prevent editing of cell contents
  • Calling the moveColumn function on the table no longer breaks column resize handle poisitioning
  • The columnHeaderSortMulti option and the headerSortTristate column definition options now work correctly together
  • Fixed issue with row display pipline not correctly persisting first registered pipeline handler

v5.3.1 (2022-07-25)

  • Fixed regression in list editor deprecated functionality check
  • Prevent list editor blur when mobile keyboard is shown
  • Removed unessisary console logging from the list editor
  • Fixed issue with column calculation updates when new row added while row grouping is enabled
  • Fixed issue with data tree row parent lookup on uninitialized rows
  • Console warning will now be displayed if a columns maxWidth is set to be smaller than its minWidth
  • Added compatibility console warning for the dataTree option and movableRows
  • Fixed issue when a grouped row is deleted when the history module is in use
  • Fixed issue with the interaction monitor not correctly identifying which column header had been clicked when using grouped columns
  • When finding a column based off its DOM element, grouped columns are now correctly traversed to find matching child columns
  • Fixed width calculation rounding issue in fitColumns layout function that resulted in horizontal scrollbar appearing
  • Double clicking on a non-editable cell now correctly selects only the contents of that cell rather than the entire row
  • fixed issue with internal render mode check not returning current render mode
  • Row group visibility toggles now function correctly with the basic vertical renderer
  • Collapsed row data is now correctly updated when row data is updated

v5.3 (2022-07-08)

  • Bugfixes

v5.2.7 (2022-06-05)

  • Fixed regression in previous release that prevented column header sort arrows from being styled correctly

v5.2.6 (2022-05-31)

  • Fixed regression in previous release that prevented column header sort arrows from being styled correctly

v5.2.5 (2022-05-27)

  • Fix null comparison logic issues in modules
  • Fixed file import issue in interaction module
  • Fixed error in list editor when used as a headerFilter with the muliselect headerFilterParams option
  • Fixed padding issue in bootstrap5 theme when used with table-sm class
  • Fixed row styling issues in the bootstrap5 theme
  • Fixed popup and list editor styling on bulma theme
  • The aria-sort attribute on column headers is now set to the correct values
  • Removed unneeded rowgroup aria tag from .tabulator-tableholder element
  • Fixed regression in the scrollToRow function, preventing the bottom mode from working correctly
  • Column header click and tap event bindings in the column definition are now correctly called only once
  • Resize handles are no longer appended to the DOM for hidden columns
  • Popups are now hidden when the table is destroyed

v5.2.4 (2022-05-08)

  • Grouped column calculations are now correctly updated when a data tree child row has a cell edited
  • When using autoColumns and remote mode sorting or filtering, the columns will not be regenerated on a change in filter or sort, preventing an incorrect reset of the current sort/filter values
  • Fixed context issue in the list editor
  • Fixed regression in the resize columns module that was preventing resizing of frozen columns if there were more than one

v5.2.3 (2022-05-02)

  • The renderStarted and renderCompete are now fired for render in place actions like sorting and filtering
  • Fixed regression in Validation module, preventing the rowValidate and columnValidate functions from working correctly
  • The persistance module will now automatically include column visibility persistenace if the columns option is set to true
  • Fixed issues on bootstrap 5 theme, with popups, menus and list editors having a transparent background
  • Fixed visual corruption of rows outside of virtual render buffer when scrolling with frozen columns
  • Grouped column moving has been correctly disabled to prevent visual corruption
  • The scrollToRow functionality now correctly positions the row when there are variable height rows and the top position is used
  • Child rows are now redrawn when the table.redraw(true) function is called

v5.2.2 (2022-04-23)

  • Further improved column resize handle styling for last column
  • Fixed typo in ISO parsing in datetime sorter
  • Fixed exception thrown from list editor when repeatedly switching between editors when used as a header filter

v5.2.1 (2022-04-21)

  • Fixed regression in datetime sorter in last release
  • Fixed issue with resize handles causing horizontal scroll bar in fitColumns layout mode

v5.2.0 (2022-04-21)

  • A console warning will be generated if Tabulator is instatiated on an empty table tag instead of a div.
  • A new internal popup management tool has been added to the Module class to ensure a consistent behaviour and look and feel when creating popup elements for things like menus, tooltips, popups and editors.
  • Access to the internal table alert functionality has been added to the Module class to allow modules to more directly message users when needed.
  • The footer manager has been decoupled from the modules that use the footer, making it more extensible and easier to manage.
  • This release includes a new theme for the v5 release of the bootstrap framework.
  • Maintain Column Fit When Resizing.
  • As a result of the introduction of the built in popup functionality in this release, the menu module is no longer responsible for creation of its own popups.
  • When you insert a header menu, Tabulator will add a button to the header element with an ⋮ icon. You can now change the contents of this button using headerMenuIcon column definition option.
  • You can use the new rowHeight option to force a height for all rows in the table. This should be set to an integer value in pixels. 
  • The date sorter will now accept a luxon DateTime object as the cell value. If this is the case then you can ignore the format option in the sorterParams.
  • The time sorter will now accept a luxon DateTime object as the cell value. If this is the case then you can ignore the format option in the sorterParams.
  • The datetime sorter will now accept a luxon DateTime object as the cell value. If this is the case then you can ignore the format option in the sorterParams.
  • The labelField option of the formatterParams object for the link formatter has been updated to handle accessing data in nested column fields. This will use the same seperator as the tables nestedFieldSeparator option.
  • The thousand option of the formatterParams object for the money formatter will now accept a boolean value of false to disable the thousand separator.
  • The datetime formatter will now accept a luxon DateTime object as the cell value. If this is the case then you can ignore the inputFormat option in the formatterParams.
  • The humanize option of the formatterParams object for the datetimediff formatter has been restored to functionality in this release, using the toHuman functionality introduced in the 2.3 release of Luxon.
  • The tickCross formatter has a new trueValue param that allows you to define the exact value that causes the tick to be shown.
  • The input, number and textarea editors have been update to include the new selectContents editor param.
  • The tickCross editor has had two new params added. The trueValue and falseValue options allow you to define that values retured from the editor.
  • The select editor has been removed and replaced with the new list editor.
  • The autocomplete editor has been removed and replaced with the new list editor.
  • The new list editor replaces the existing select and autocomplete and provides a wide range of options for all your list based editing needs.
  • Update events.
  • The ResizeColumns module has been completely rebuilt for this release.
  • The mouseLeave event now fires with the correct cell component
  • Columns loading large amount of data while using frozen columns will no longer take a long time to load
  • When adding or updating a column, recalculate frozen column positions so column is added in correct position

v5.1.8 (2022-04-03)

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

v5.1.7 (2022-03-11)

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

v5.1.6 (2022-03-10)

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

v5.1.5 (2022-03-09)

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

v5.1.4 (2022-03-07)

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

v5.1.3 (2022-02-28)

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

v5.1.2 (2022-02-20)

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

v5.1.1 (2022-02-20)

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

v5.1.0 (2022-01-31)

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

v5.0.10 (2021-12-30)

  • Fixed browser freeze when responsiveLayout is set to collapse
  • Cell edit validation error borders are now correctly removed when cell a edit is cancelled
  • Fixed regression in horizontal virtual DOM renderer that was causing columns to build up and corrupt the display
  • The table can now handle large number of rows (>700,000) without throwing a "Maximum call stack size exceeded" error
  • Frozen columns in calculation rows are now correctly aligned when row grouping is enabled
  • The interaction monitor has been optimized

v5.0.9 (2021-12-30)

  • Column header tooltip no longer defaults to tooltip option if headerTooltip not set
  • Fixed issue with params specified in the setData function not being passed to a request if ajaxParams option not set
  • Fixed margin issues with data tree elements on redraw
  • Data tree module now waits for columns to be loaded into the table before calculating the first column
  • Data tree elements are now correctly regenerated when a cell value is changed
  • The interaction monitor now correctly clears event listeners when the table is destroyed
  • The interaction monitor now correctly handles mouseenter and mouseleave events
  • The interaction monitor now correctly handles events generated on calculation rows
  • The scrollToRowPosition function now resolves if the row is already visible
  • Pagination console warning about missing response params, now pull their contents from the correct table options
  • The header sorter arrow is now correctly aligned in RTL mode
  • The VerticalVirtualDOM renderer no longer clears the minWidth of the table element on redraw
  • Bulk select/deselect of rows now triggers the rowSelected or rowDeselected events for each affected row, then triggers the rowSelectionChanged once when all selections have been changed
  • XLSX downloads now only contain merged cell data if the table contains merged cells
  • PDF downloader now correctly handles grouped column headers
  • Optimised the getElement function on the Group component, to prevent unnecessary regeneration of the component on every call.

v5.0.8 (2021-12-20)

  • Table now correctly maintains horizontal scroll position when header sort is triggered
  • Rows are now dethatched from groups when table is wiped, preventing console error messaging
  • The movableColumns table option now correctly respects its default value
  • Luxon based formatters now cast values to strings to allow correct format processing without errors
  • Luxon based sorters now cast values to strings to allow correct format processing without errors
  • Selectable Row persistence on sort/filter is now correctly enabled by default
  • The interaction monitor now correctly handles mouse events on the table when the table is created from an HTML table element
  • The GroupRow module now reinitializes when the setGroupBy function is called
  • Column header hr tags are now correctly parsed for tabulator- prefixed attributes when loading table from HTML table element
  • Exception no longer thrown when calling updateRow function
  • Option chaining has been removed from the code base to improve ESM importing for older environments
  • 'CalcCompononet' is now correctly bound to row component so functions like getData can now be successfully called on it
  • Ajax progressive loading in scroll mode no longer throws a console error when the table has been scrolled to the last page
  • An unneeded initialisation warning has been removed from the getRows function

v5.0.7 (2021-11-01)

  • Added console warnings on functions that are unsafe to call on an uninitialized table
  • Moving columns while a row is frozen now works correctly
  • History module now handles row deletion correctly
  • Fix issue with duplicated row groups when the setGroupBy function is called
  • The addColumn function now correctly adds all new columns as top level columns when column grouping is in use
  • Initial filters no longer try to refresh the table when it is uninitialized
  • The select module now correctly handles row-retrieve internal events

v5.0.6 (2021-10-26)

  • Fix ESM import bug in HTML Import module when processed for minified UMD dist file
  • Improve formatting of negative values in money formatter

v5.0.5 (2021-10-25)

  • Fixed missing reference to helper function in edit module
  • Fixed context regression in ajax module
  • Moved table element parsing into core table initialization logic, to allow HTML import module to initialize in the correct order
  • Prevented progress formatter from throwing an error when used as a header filter
  • Ensure that header filters that return no matches clear down the table
  • Ensure column header height is always recalculated on redraw
  • Fixed stripped row styling issues in bootstrap3, semanticui and bulma themes
  • The addRow function, when used in conjunction with the group rows module now correctly adds rows to their matching group
  • The onRendered function is now correctly called in a columnTitleFormatter when the row is inserted after initialization
  • Accessibility attributes for table headers have been improved to make them more intelligible to screen readers
  • The onRendered function is now correctly triggered when cell values are updated by the undo or redo actions
  • Mock onRendered function is passed into responsive collapse formatters to prevent exception when collapsing heavily formatted columns
  • Widths and margins of group calculation rows are now correctly recalculated on table initialization
  • The data tree module will now only reinitialize a row if the element cell is edited, rather than reinitializing the whole row
  • The edit module now correctly calls navigation functions on the cell component instead of the cell itself

v5.0.4 (2021-10-22)

  • Fixed regression in deep clone function and optimized to handle complex objects

v5.0.3 (2021-10-21)

  • Fixed scope issue in the Accessor Module
  • Ensured that the this context of event callbacks is set to the table that called them
  • The row data array is now correctly passed to the dataLoaded callback when triggered by an ajax request
  • A warning console message is now displayed when setColumns is called before the table is initialized
  • A scoping issue has been fixed in the Reactive Data module
  • The bootstrap 4 theme has been updated to prevent graphical collision of even rows when frozen columns are enabled
  • Header filters are now correctly applied when grouped rows are in use
  • Added the mock deinitializeHeight function to the Group class to prevent rendering errors
  • Updated the deepClone helper function to prevent an infinite loop when recursive data structures are used

v5.0.2 (2021-10-20)

  • Fixed issue with tableBuilt event being fired before the initial table data had been loaded
  • Fixed issue with footerElement option not accepting HTML string inputs correctly
  • Fixed issue with page size selector being created before the initial page size is set
  • Fixed issue with persistence module not initializing correctly when the autoColumns option was set
  • Restored functionality to the extendModule function
  • Row height on variable height columns is now corr

    This awesome jQuery plugin is developed by olifolkerd. For more Advanced Usages, please check the demo page or visit the official website.