Table Layout
- Overview
- Table Height
- Column Layout Modes
- Responsive Column Layout
- Text Direction
- Resizable Elements
- Frozen Elements
- Redrawing the table
- Virtual DOM
- Horizontal 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.
Table Height
Fixed Height Tables
Tabulator works most efficiently when the table has a fixed height, either defined in the CSS for the element or set using the height option in the table constructor, this can be set to any valid CSS value
var table = new Tabulator("#example-table", { height:"100%", });
By setting the height on the table, you allow Tabulator's virtual DOM to optimize the tables memory and processor usage. It does this by only rendering the rows you see in the table (plus a few above and below the current view) and creates and destroys the rows as you scroll through the table.
This allows tabulator to handle thousands of rows with no overhead as it only processes the information it needs to display.
If a height is set on the table then it will display vertical scroll bars when the number of row exceeds the table height. If there are less rows than the height of the table then the background of the table will be visible.
Variable Height Tables
If you would rather that your table takes up as much space as is needed to show all the available rows, then simply don't specify a height on your table element or in your table constructor.
Without a height the table will keep expanding to fit the number of available rows and will never display a vertical scroll bar.
Slow Rendering: It is worth noting that if you are loading a lot of rows into your table without a height set then it may result is blocking of the browser and slow render speeds as it takes a lot of memory to draw 100's of rows onto the screen.
Maximum Table Height
With a variable table height you can set the maximum height of the table either defined in the max-height CSS property for the element or set it using the maxHeight option in the table constructor, this can be set to any valid CSS value
var table = new Tabulator("#example-table", { maxHeight:"100%", //do not let table get bigger than the height of its parent element });
By setting this you can allow your table to expand to fit the data, but not overflow its parent element. When there are too many rows to fit in the available space, the vertical scroll bar will be shown. This has the added benefit of improving load times on larger tables
Minimum Table Height
With a variable table height you can set the minimum height of the table either defined in the min-height CSS property for the element or set it using the minHeight option in the table constructor, this can be set to any valid CSS value
var table = new Tabulator("#example-table", { minHeight:300, //do not let table get smaller than 300 px heigh });
Advanced Options
There are many scenarios in which you many need to tweak the way the virtual DOM works or disable it all together. For example tables with significantly varying row height, or very large data sets.
In these cases, have a read of the Virtual DOM Documentation to find out more.
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 Table and Columns to Data
The fitDataTable layout mode, will set the column widths in the same way as the fitData mode, but it will also then resize the width of the table to match the total width of the columns
var table = new Tabulator("#example-table", { layout:"fitDataTable", });
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, });
Text Direction
Tabulator supports both "Right to Left" and "Left To Right" text directions.
By default Tabulator will attempt determine the correct text direction for the table based on the direction CSS property inherited from its parent element.
If you want to force the direction of the table, you can use the textDirection setup option. This can take one of three string values:
- auto - this will automatically detect text direction from the direction CSS property inherited from its parent element (default)
- ltr - this will force the table into left to right layout mode
- rtl - this will force the table into right to left layout mode
var table = new Tabulator("#example-table", { textDirection:"rtl", // force table into right to left text direction });
Frozen Column Support
Frozen columns are currently not supported in RTL mode, this functionality will be coming in a future release
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.
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 Column Groups
If you are using grouped columns, then you can freeze an entire group by using the frozen property in the parent group definition
var table = new Tabulator("#example-table", { [ { title:"Column Group", frozen:true,//frozen column group on left of table columns:[ {title:"Name", field:"name"}, {title:"Age", field:"age"}, ] } {title:"Eye Colour", field:"eyes"}, {title:"Height", field:"height", frozen:true}, //frozen column on right of table ] });
Note: You cannot freeze individual columns in a column group, either the entire group is frozen or none of the columns are
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
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
Slow Rendering: It is worth noting that if you are loading a lot of rows into your table without a height set then it may result is blocking of the browser and slow render speeds as it takes a lot of memory to draw 100's of rows onto the screen.
External Event Bindings: 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. This will render all rows at once with no vertical scroll bar.
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
If 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 });
Poor User Experience
Disabling the virtual DOM will render all rows at once with no vertical scroll bar, which could lead to very poor performance in the browser if you are loading a lot of rows into the table.
Without the Virtual DOM, the table may need to be completely redrawn when certain actions are performed (eg. sorting and filtering), this could lead to a poor user experience. It may take significant time to redraw all the rows in large tables, and may also result in the table changing height during the redraw, which could affect the scroll position of the browser.
Note: It is strongly recommended that you DO NOT disable the virtual DOM, this functionality is included to help legacy users and those with very specific usage cases
Horizontal Virtual DOM
By default, tabulator will use the standard virtual DOM to ensure that the table can process any number of rows passed to it. This works well for most usage cases, but on tables with a large number of columns, the rendering time for each row can result in sluggish rendering and scroll performance.
To get round this Tabulator also has a horizontal virtual DOM that can be enabled in such circumstances. which generates only the visible columns for each row, improving row rendering performance.
The horizontal virtual DOM is disabled by default, if you want to enable it you can use the virtualDomHoz option
var table = new Tabulator("#example-table", { virtualDomHoz:true, //enable horizontal virtual DOM });
Compatibility
The horizontal virtual DOM is not compatible with other table features that also work to limit the number of scrollable columns. When these features are enabled, the horizontal virtual DOM will be automatically disabled. These features include:
- The fitDataTable layout mode
- Responsive Columns
- Classic Render Mode
Row Formatters
Use of row formatters with the horizontal DOM is permitted if they only involve styling the row or its cells. Row formatters that manipulate the contents of the row element will likely malfunction when used with the horizontal virtual DOM
Frozen Columns
Use of frozen columns with the horizontal DOM is currently not supported. The horizontal virtual DOM will be automatically disabled if frozen columns are detected. This limitation will be removed in a future release
Column Calculations
Use of Column Calculations with the horizontal DOM is currently not supported. The horizontal virtual DOM will be automatically disabled if Column Calculations are detected. This limitation will be removed in a future release
RTL
Use of RTL text direction with the horizontal DOM is currently not supported. The horizontal virtual DOM will be automatically disabled if RTL detected. This limitation will be removed in a future release
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.