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.

Loading Example...
Source Code

HTML

<div id="example-table"></div>

JavaScript

var table = new Tabulator("#example-table", {
    height:"311px",
    data:tableDataNested,
    dataTree:true,
    dataTreeStartExpanded:true,
    columns:[
    {title:"Name", field:"name", width:200, responsive:0}, //never hide this column
    {title:"Location", field:"location", width:150},
    {title:"Gender", field:"gender", width:150, responsive:2}, //hide this column first
    {title:"Favourite Color", field:"col", width:150},
    {title:"Date Of Birth", field:"dob", hozAlign:"center", sorter:"date", width:150},
    ],
});

Nested Table Data

var tableDataNested = [
    {name:"Oli Bob", location:"United Kingdom", gender:"male", col:"red", dob:"14/04/1984", _children:[
        {name:"Mary May", location:"Germany", gender:"female", col:"blue", dob:"14/05/1982"},
        {name:"Christine Lobowski", location:"France", gender:"female", col:"green", dob:"22/05/1982"},
        {name:"Brendon Philips", location:"USA", gender:"male", col:"orange", dob:"01/08/1980", _children:[
            {name:"Margret Marmajuke", location:"Canada", gender:"female", col:"yellow", dob:"31/01/1999"},
            {name:"Frank Harbours", location:"Russia", gender:"male", col:"red", dob:"12/05/1966"},
        ]},
    ]},
    {name:"Jamie Newhart", location:"India", gender:"male", col:"green", dob:"14/05/1985"},
    {name:"Gemma Jane", location:"China", gender:"female", col:"red", dob:"22/05/1982", _children:[
        {name:"Emily Sykes", location:"South Korea", gender:"female", col:"maroon", dob:"11/11/1970"},
    ]},
    {name:"James Newman", location:"Japan", gender:"male", col:"red", dob:"22/03/1998"},
];

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
});

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, //propagte 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.

var table = new Tabulator("#example-table", {
    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

Callbacks

A range of callbacks are available for tracking tree update events. See the Data Tree Callbacks section for more information.