Table Layout
- Overview
- Column Layout Modes
- Responsive Column Layout
- Resizable Elements
- Frozen Elements
- Redrawing the table
- The Virtual DOM
- Empty Table Placeholder
- Table Footer Element
- Callbacks
Overview
Tabulator has loads of different ways of customizing the layout the table, have a look through the next few sections to see how you can configure your tables to meet your use case.
Column Layout Modes
You can choose how your table should layout its columns by setting the layout mode, in the configuration options:
var table = new Tabulator("#example-table", { layout:"fitData", });
Tabulator has a number of different layout modes to choose from
Fit Columns to Data
By default Tabulator will use the fitData layout mode, which will resize the tables columns to fit the data held in each column, unless you specify a width or minWidth in the column constructor. If the width of all columns exceeds the width of the containing element, a scroll bar will appear.
var table = new Tabulator("#example-table", { layout:"fitData", });
Fit Columns to Data and Fill
The fitDataFill layout mode functions in the same way as the fitData mode, but ensures that rows are always at least the full width of the table.
var table = new Tabulator("#example-table", { layout:"fitDataFill", });
Fit Columns to Data and Stretch Last Column
The 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", });
Fit Columns to Table Width
As an alternative to the default data fit, you can use the fitColumns layout mode to cause Tabulator to resize columns so they fit perfectly in the available table width.
In this layout mode, columns without a width set are resized to fill any remaining space on the table. If all columns cannot fit on the table then a scrollbar will appear.
var table = new Tabulator("#example-table", { layout:"fitColumns", });
You can adjust the behaviour of the layout using the widthGrow and widthShrink properties on a column definition
The widthGrow property should be used on columns without a width property set. The value is used to work out what fraction of the available will be allocated to the column. The value should be set to a number greater than 0, by default any columns with no width set have a widthGrow value of 1.
The widthGrow function works by dividing the available space by the sum total of widthGrow values and then allocating it out to the columns based on their value.
var table = new Tabulator("#example-table", { layout:"fitColumns", columns:[ {title:"Name", field:"name", width:100}, //column has a fixed width of 100px; {title:"Age", field:"age", widthGrow:1}, //column will be allocated 1/5 of the remaining space {title:"Color", field:"color", widthGrow:3}, //column will be allocated 3/5 of the remaining space {title:"location", field:"location"}, // column has a default widthGrow of 1 and will be allocated 1/5 of the remaining space ] });
The widthShrink property should be used on columns with a width property set. The value is used to work out how to shrink columns with a fixed width when the table is too narrow to fit in all the columns. The value should be set to a number greater than 0, by default columns with a width set have a widthShrink value of 0, meaning they will not be shrunk if the table gets too narrow, and may cause the horizontal scrollbar to appear.
The widthShrink function works by dividing the excess horizontal space by the sum total of widthShrink values and then allocating it out to the columns based on their value.
var table = new Tabulator("#example-table", { layout:"fitColumns", columns:[ {title:"Name", field:"name", width:100}, //column will not be shrunk {title:"Age", field:"age", width:200, widthShrink:2}, //column will be shrunk by 2/3 of the excess space {title:"Color", field:"color", width:200, widthShrink:1}, //column will be shrunk by 1/3 of the excess space {title:"location", field:"location"}, //column has no width set so will be set at the tables minWidth value ] });
Update Column Widths On New Data
To keep the layout of the columns consistent, once the column widths have been set on the first data load (either from the data property in the constructor or the setData function) they will not be changed when new data is loaded.
If you would prefer that the column widths adjust to the data each time you load it into the table you can set the layoutColumnsOnNewData property to true.
var table = new Tabulator("#example-table", { layoutColumnsOnNewData:true, });
Responsive Layout
Responsive layout will automatically hide/show columns to fit the width of the Tabulator element. This allows for clean rendering of tables on smaller mobile devices, showing important data while avoiding horizontal scroll bars. You can enable responsive layouts using the responsiveLayout option.
There are two responsive layout modes available:
- hide - hide columns that no longer fit in the table
- collapse - collapse columns that no longer fit on the table into a list under the row
var table = new Tabulator("#example-table", { responsiveLayout:"hide", // hide rows that no longer fit });
Hide Extra Columns
By default, columns will be hidden from right to left as the width of the table decreases. You can choose exactly how columns are hidden using the responsive property in the column definition object.
When responsive layout is enabled, all columns are given a default responsive value of 1. The higher you set this value the sooner that column will be hidden as the table width decreases. If two columns have the same responsive value then they are hidden from right to left (as defined in the column definition array, ignoring user moving of the columns). If you set the value to 0 then the column will never be hidden regardless of how narrow the table gets.
var table = new Tabulator("#example-table", { responsiveLayout:true, // enable responsive layouts columns:[ //set column definitions for imported table data {title:"Name", field:"name", responsive:0}, // this column wil never be hidden {title:"Age", field:"age" , responsive:3}, // hidden first {title:"Gender", field:"gender" }, // hidden fifth {title:"Height", field:"height" , responsive:2}, // hidden third {title:"Favourite Color", field:"color" , responsive:2}, // hidden second {title:"Date of Birth", field:"dob" }, // hidden fourth ], });
Note: If you are using the fitColumns feature, you will need to set a minWidth property on the columns you want to respond responsively to ensure they are hidden when necessary, otherwise Tabulator will keep on reducing the width of the columns instead.
Collapsed Extra Columns To List
If you set the responsiveLayout option to collapse the values from hidden columns will be displayed in a title/value list under the row.
var table = new Tabulator("#example-table", { responsiveLayout:"collapse", // collapse columns that no longer fit on the table into a list under the row });
In this mode an object containing the title of each hidden column and its value is generated and then used to generate a list displayed in a div .tabulator-responsive-collapse under the row data.
The inbuilt collapse formatter creates a table to neatly display the hidden columns. If you would like to format the data in your own way you can use the responsiveLayoutCollapseFormatter, it takes an array of objects of the column titles and values as an argument and must return the HTML content of the div.
This function should return an empty string if there is no data to display.
var table = new Tabulator("#example-table", { responsiveLayoutCollapseFormatter:function(data){ //data - an array of objects containing the column title and value for each cell var list = document.createElement("ul"); data.forEach(function(col){ let item = document.createElement("li"); item.innerHTML = "<strong>" + col.title + "</strong> - " + col.value; list.appendChild(item); }); return Object.keys(data).length ? list : ""; } });
The data argument is an array of objects of the column titles and values, it takes the following format:
[ { title:"Name", value:"Steve Green", }, { title:"Age", value:53, } ]
Collapsed List Column Formatting
By default any formatter set on the column is applied to the value that will appear in the list. while this works for most formatters it can cause issues with the progress formatter which relies on being inside a cell.
If you would like to disable column formatting in the collapsed list, you can use the responsiveLayoutCollapseUseFormatters option:
var table = new Tabulator("#example-table", { responsiveLayoutCollapseUseFormatters:false, });
Dummy Cell Component
Because the collapsed data is not based in a cell, a dummy cell component is passed into the formatters to allow them to function as normal. This dummy component only has the getValue, getData, getElement, getRow and getColumn functions rather than the full set of component functions.
Collapsed List Show/Hide
If you would like your users to be able to interact with the list and hide/show it as needed you can add a column that uses the built-in responsiveCollapse formatter that provides a control for toggling the visibility of the collapsed list
{formatter:"responsiveCollapse", headerSort:false}
The column using this formatter will be automatically hidden when there are no collapsed columns to display.
Default List Visibility
Collapsed lists are displayed to the user by default, if you would prefer they start closed so the user can open them you can use the responsiveLayoutCollapseStartOpen option
var table = new Tabulator("#example-table", { responsiveLayoutCollapseStartOpen:false, });
Resizable Elements
Table Resizing
Tabulator will automatically attempt to redraw the data contained in the table if the containing element for the table is resized. To disable this functionality, set the autoResize property to false
var table = new Tabulator("#example-table", { autoResize:false, // prevent auto resizing of table });
Note: Tabulator uses the ResizeObserver JavaScript API to watch for resizing of the table, at present this is only available on the Chrome browser in versions 64 and above. In browsers without this functionality, Tabulator will fallback to using the window resize event which will only be able to detect changes on the window size, not on the table element itself.
Resizable Rows
You can allow the user to manually resize rows by dragging the top or bottom border of a row. To enable this functionality, set the resizableRows property to true
var table = new Tabulator("#example-table", { resizableRows:true, // this option takes a boolean value (default = false) });
Resizable Columns
By default it is possible to manually resize columns by dragging the borders of the column in both the column headers and the cells of the column.
If you want to alter this behaviour you can use the resizableColumns to choose where the resize handles are available. It supports four possible options:
- true - enable column resizing from both cells and headers
- "header" - enable column resizing from headers only
- "cell" - enable column resizing from cells only
- false - disable column resizing
var table = new Tabulator("#example-table", { resizableColumns:false, // this option takes a boolean value (default = true) });
Note: If you double click on a resizable border it will resize the column to fit the data it contains.
Column Specific Resizing
You can also set column resizability on a per column basis by passing a boolean value to the resizable property in a columns definition object.
{title:"name", field:"name", resizable:false} //prevent this column from being resized
Minimum Column Width
It is possible to set a minimum column width to prevent resizing columns from becoming too small.
This can be set globally, by setting the columnMinWidth option to the column width when you create your Tabulator.
This option can be overridden on a per column basis by setting the minWidth property on the column definition.
var table = new Tabulator("#example-table", { columnMinWidth:80, //Minimum column width in px (default = 40) });
Wrap Column Header Title Text
By default Tabulator will try and keep column header titles on one line, truncating the text with ellipsis if it gets wider that the column.
If you would like to wrap the text instead then you will need to edit the CSS white-space value for the column headers and set it to normal.
.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title { white-space: normal; }
Frozen Elements
Frozen Columns
You can freeze the position of columns on the left and right of the table using the frozen property in the column definition array. This will keep the column still when the table is scrolled horizontally.
var table = new Tabulator("#example-table", { [ {title:"Name", field:"name", frozen:true}, //frozen column on left of table {title:"Age", field:"age"}, {title:"Eye Colour", field:"eyes"}, {title:"Height", field:"height", frozen:true}, //frozen column on right of table ] });
You can freeze any number of columns on the left or right of the table, but they must be next to each other in the column definition array.
Tabulator builds the frozen columns by looking through the column definition array from both sides, building up the frozen columns as it see the frozen property. Once a non-frozen column is reached it stops building the frozen list for that side of the table.
Note: Frozen columns are locked in place and cannot be reordered by dragging and dropping the column header. It is also not possible to freeze a column that is part of a column group.
Note: At lease one column must not be frozen for the table to render correctly. If you want to freeze all your columns then you will achieve the same effect by not freezing any.
Frozen Rows
You can freeze a row at the top of the table by calling the freeze function on the Row Component of any row. This will insert the row above the scrolling portion of the table in the table header.
row.freeze();
A frozen row can be unfrozen using the unfreeze function on the Row Component of any row. This will remove the row from the table header and re-insert it back in the table.
row.unfreeze();
Note: Freezing or unfreezing a row will redraw the table.
Redrawing the table
If the size of the element containing the Tabulator changes (and you are not able to use the in built auto-resize functionality) or you create a table before its containing element is visible, it will necessary to redraw the table to make sure the rows and columns render correctly.
This can be done by calling the redraw method. For example, to trigger a redraw whenever the viewport width is changed:
window.addEventListener('resize', function(){ table.redraw(); });
The redraw function also has an optional boolean argument that when set to true triggers a full rerender of the table including all data on all rows.
window.addEventListener('resize', function(){ table.redraw(true); //trigger full rerender including all data and rows });
Virtual DOM
As of version 3.0 tabulator renders its table using a Virtual DOM, this means that it only renders the rows you seen 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.
A detailed description of how the Virtual DOM works can be found in the Architecture Concepts Section
In order for the virtual DOM to function correctly you must ensure that the table element has a height you can either define this 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. If no height is set the table will revert to the standard DOM mode and try and render all rows at once, which will have a performance impact on tables with a large number of rows.
var table = new Tabulator("#example-table", { height:"100%", });
Note: In version 3.3 and below you were required to set the height option to use the virtual DOM, as of 3.4 this is no longer the case and you can define the height inline on the element or in the CSS and the virtual DOM will still work.
Note: It is not possible to externally add event bindings to elements in the table because they are created and destroyed by Tabulator as needed. The good news is there are callbacks and options to register almost every binding through the setup options.
Standard DOM Exceptions
When pagination is enabled Tabulator will revert to using classic DOM rendering as it will only be displaying one page at a time.
Render Buffer
The virtual DOM renders a number of rows above and below the visible rows to ensure a smooth scrolling experience. This buffer will be set at the current of the height of table so there is always and additional tables height worth of rows above and beyond the view.
In some situations, where you have a full screen table with a large number of columns, this can result in slow rendering performance in older browsers. In these situations it is possible to manually set the height of the buffer in pixels using the virtualDomBuffer option. By setting this to a smaller number than the height you can reduce the number of rows that are rendered and increase the performance on older browsers.
var table = new Tabulator("#example-table", { virtualDomBuffer:300, //set virtual DOM buffer to 300px });
Note: The virtualDomBuffer should only be used as a last resort, by default its value is automatically set by Tabulator to suit the size of the table, the default value should work for 99% of usage cases. If you are experiencing rendering issues it is likely that your table has changed sizes and the redraw function needs to be called (see below).
Redraw Management
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.
Table Resizing
Changing Table Height
If you want to manually change the height of the table at any time, you can use the setHeight function, which will also redraw the virtual DOM if necessary.
table.setHeight(500); //set table height to 500px
Note: The setHeight function is not available in classic render mode
Resizing The Table
If the table element changes height or width at any point (for example the height is set at a percentage and the user resizes the window), or if the table data is set while the table element is hidden, Tabulator needs to be told that it should redraw its contents to fit its new size.
Tabulator uses the JavaScript Resize Observer functionality to do this automatically where possible, but this feature has yet to be implemented in all browsers. you can see a list of browser that support this functionality here.
If you want to use Tabulator on a browser that does not yet support resize observers, you will need to call the redraw function when resizing/showing your table to ensure that the virtual DOM updates to display the correct number of rows.
table.redraw();
Disabling the Virtual DOM
f you need to disable virtual rendering for any reason you can set the virtualDom option to false to force classic rendering.
var table = new Tabulator("#example-table", { virtualDom:false, //disable virtual DOM rendering });
Empty Table Placeholder
You can use the placeholder option to display a message to your users when the table has no data set. The function can either take a string to display or, the HTML or DOM Node to display in the empty table.
var table = new Tabulator("#example-table", { placeholder:"No Data Available", //display message to user on empty table });
Table Footer
The footer element that the tables uses for holding pagination elements etc, is automatically generated by Tabulator.
If you want to use your own element for any reason, for example you want to add additional elements to the footer, you can use the footerElement option to pass either a CSS selector, a DOM node, or the HTML for the contents of footer element into the table.
var table = new Tabulator("#example-table", { footerElement:"<button>Custom Button</button>", //add a custom button to the footer element });
Note: To ensure correct functioning of the table, it is recommended that you apply the tabulator-footer class to the footer element
Callbacks
A range of callbacks are available for tracking progress of table rendering. See the Layout Callbacks section for more information.