Tree Structure and Nested Data
Overview
For nested data sets Tabulator allows you to structure your rows as a tree, allowing users to collapse and expand nested sets of rows.
To enable data trees in your table, set the dataTree property to true in your table constructor:
var table = new Tabulator("#example-table", { dataTree:true, });
Data Structure
In order to build a table with nested data you must structure your data in a certain way.
If a row is to have child rows, these child data objects must be provided as an array to the rows _children property:
[ {id:1, name:"Billy Bob", age:"12", "_children":[ {id:2, name:"Mary May", age:"1"}, //child rows nested under billy bob {id:3, name:"Christine Lobowski", age:"42"}, {id:4, name:"Brendon Philips", age:"125", "_children":[ {id:5, name:"Margret Marmajuke", age:"16"}, //child rows nested under brendon philps {id:6, name:"Frank Peoney", age:"12"}, ]}, ]}, {id:7, name:"Jenny Jane", age:"1"}, {id:8, name:"Martha Tiddly", age:"42", "_children":[ {id:9, name:"Frasier Franks", age:"125"}, //child row nested under martha tiddly ]}, {id:10, name:"Bobby Green", age:"11"}, ]
Custom Child Rows Field
By default Tabulator will look for child rows in the _children field of a row data object. You can change this to look in a different field using the dataTreeChildField property in your table constructor:
var table = new Tabulator("#example-table", { dataTree:true, dataTreeChildField:"childRows", //look for the child row data array in the childRows field });
Data Management
Filtering Child Rows
When you are filtering rows in the table, Tabulator will by default apply the filter to all child rows, showing only child rows that match the filter.
If you would prefer that only the top level rows are filtered and the child rows left unfiltered, you can set the dataTreeFilter option to false in your table constructor:
var table = new Tabulator("#example-table", { dataTree:true, dataTreeFilter:false, //disable child row filtering });
Sorting Child Rows
When you are sorting rows in the table, Tabulator will by default apply the sort to all child rows as well.
If you would prefer that only the top level rows are sorted and the child rows left unsorted, you can set the dataTreeSort option to false in your table constructor:
var table = new Tabulator("#example-table", { dataTree:true, dataTreeSort:false, //disable child row sorting });
Layout
Tabulator provides a number of ways to customise the layout of the data tree.
Collapse and Expand Elements
The toggle button that allows users to collapse and expand the column can be customised to meet your needs. There are two options, dataTreeExpandElement and dataTreeCollapseElement, that can be set to replace the default toggle elements with your own.
Both options can take either an html string representing the contents of the toggle element
var table = new Tabulator("#example-table", { dataTree:true, dataTreeCollapseElement:"<i class='fas fa-minus-square'></i>", //fontawesome toggle icon });
Or a DOM element representing the toggle
//create font awesome icon var expandEl = document.createElement("i"); expandEl.classList.add("fas"); expandEl.classList.add("fa-plus-square"); var table = new Tabulator("#example-table", { dataTree:true, dataTreeExpandElement:expandEl, //assign element as expand element });
Toggle Element Column
By default the toggle element will be inserted into the first column on the table. If you want the toggle element to be inserted in a different column you can pass the feild name of the column to the dataTreeElementColumn setup option
var table = new Tabulator("#example-table", { dataTree:true, dataTreeElementColumn:"name", //insert the collapse/expand toggle element in the name column });
Branch Element
The branch element is the right angled line running from parent to child to indicate its position in the tree.
Hide the branch element
The branch element can be turned off by setting the dataTreeBranchElement propety to false in the table constructor:
var table = new Tabulator("#example-table", { dataTree:true, dataTreeBranchElement:false, //hide branch element });
Replace the Branch Element
Alternatively the branch element can be replaced with one of your choosing. As with the other tree elements this can be provided either as HTML or as a DOM element.
var table = new Tabulator("#example-table", { dataTree:true, dataTreeBranchElement:"<img class='branch-icon' src='/branch.png'/>", //show image for branch element });
Child Indentation
When a child row is displayed under its parent it is indented to make the distinction clearer. The size of the indent can be set by passing an integer representing the number of pixels for the indent to the dataTreeChildIndent property in the table constructor:
var table = new Tabulator("#example-table", { dataTree:true, dataTreeChildIndent:15, //indent child rows by 15 px });
Initial Expansion State
By default all nodes on the tree will start collapsed, you can customize the initial expansion state of the tree using the dataTreeStartExpanded option.
This option can take one of three possible value types, either a boolean to indicate whether all nodes should start expanded or collapsed:
var table = new Tabulator("#example-table", { dataTree:true, dataTreeStartExpanded:true, //start with an expanded tree });
An array of booleans to indecate how each level of the tree should be expanded:
var table = new Tabulator("#example-table", { dataTree:true, dataTreeStartExpanded:[true, false], //start with first level expanded, second level collapsed });
Or a function that will be passed in a row component and the level of that row in the table (starting at 0), it should return a boolean value to indicate the rows expansion state:
var table = new Tabulator("#example-table", { dataTree:true, dataTreeStartExpanded:function(row, level){ return row.getData().driver; //expand rows where the "driver" data field is true; }, });
Child Row Styling
Each child row is assigned a class based on its level in the tree. This allows you to differentiate between different tree levels by styling their classes.
For example, all first level children will be assigned the class tabulator-tree-level-1
Row Selection
If you are using data trees in a table that also has row selection enabled, the default behaviour will be for selection of each row to be toggled individually as the user clicks on it.
You may want the selection/deselection to propagate down to the child rows as well. To do this, set the dataTreeSelectPropagate option to true in the table constructor.
var table = new Tabulator("#example-table", { dataTree:true, dataTreeSelectPropagate:true, //propagate selection events from parent rows to children });
Component Actions
You can use the Row Component
passed into any of Tabulator's callbacks to trigger tree events on that row.table.on("rowClick", function(e, row){ //e - the click event object //row - row component row.treeCollapse(); //collapse the rows children });
Expand Row
The treeExpand function will expand current row and show its children.
row.treeExpand();
Collapse Row
The treeCollapse function will collapse current row and hide its children.
row.treeCollapse();
Toggle Row
The treeToggle function will toggle the collapsed state of the current row.
row.treeToggle();
Get Parent Row
The getTreeParent function will return the Row Component for the parent of this row. If no parent exists, a value of false will be returned.
var parent = row.getTreeParent();
Get Child Rows
The getTreeChildren function will return an array of Row Components for this rows children.
var children = row.getTreeChildren();
Add Row Child
You can add child rows any row using the addTreeChild function on the Row Component
The first argument should be a row data object. If you do not pass data for a column, it will be left empty. To create a blank row (ie for a user to fill in), pass an empty object to the function.
row.addTreeChild({name:"Billy Bob", age:"12", gender:"male", height:1});
The second argument is optional and determines whether the row is added to the top or bottom of the array of child rows. A value of true will add the row to the top of the array, a value of false will add the row to the bottom of the array. If the parameter is not set the row will be placed according to the addRowPos global option.
row.addTreeChild({name:"Billy Bob", age:"12", gender:"male", height:1}, true); //add child row to the top of the array
If you want to add the row next to an existing row you can pass an optional third argument to the function that will position the new row next to the specified row (above or below based on the value of the second argument). This argument will take any of the standard row component look up options. This must be a row that has the same parent as the row you want to add
row.addTreeChild({name:"Billy Bob", age:"12"}, true, 3); //add new row above existing row with index of 3
Events
A range of events are available for tracking tree update events. See the Data Tree Events section for more information.