lightning:treeGrid

Displays a hierarchical view of data in a table. This component requires API version 42.0 and later.

Attributes

A lightning:treeGrid component displays hierarchical data in a table. Its appearance resembles lightning:datatable, with the exception that each row can be expanded to reveal a nested group of items. Rows that contain nested data display a chevron icon to denote that they can be expanded or collapsed. Each column can be displayed based on the data type. For example, a phone number is displayed as a hyperlink with the tel: URL scheme by specifying the phone type. The default type is text.

This component inherits styling from trees in the Lightning Design System.

Inline editing and sorting of columns are not supported. Supported features include:

  • Displaying and formatting of columns with appropriate data types
  • Header-level actions
  • Infinite scrolling of rows
  • Row-level actions
  • Resizing of columns
  • Selecting of rows
  • Text wrapping and clipping

Initialize your data using the data, columns, and keyField attributes via the init handler. This example creates a table with 5 columns, where the first column displays a checkbox for row selection. Selecting the checkbox enables you to select the entire row of data and triggers the onrowselection event handler. The expandedRows attribute is optional, which expands nested items on a row when provided.

<aura:component>
    <aura:handler name="init" value="{!this}" action="{!c.init}" />
    <aura:attribute name="gridColumns" type="List" />
    <aura:attribute name="gridData" type="Object" />
    <aura:attribute name="gridExpandedRows" type="Object" />
    <lightning:treeGrid
        columns="{! v.gridColumns }"
        data="{! v.gridData }"
        expandedRows="{! v.gridExpandedRows }"
        keyField="name"
        aura:id="mytree"
    />
</aura:component>

The client-side controller creates selectable rows with or without nested data. The Account Owner column displays labels with an associated URL.

({
    init: function (cmp) {
        var columns = [
            {
                type: 'text',
                fieldName: 'accountName',
                label: 'Account Name'
            },
            {
                type: 'number',
                fieldName: 'employees',
                label: 'Employees'
            },
            {
                type: 'phone',
                fieldName: 'phone',
                label: 'Phone Number'
            },
            {
                type: 'url',
                fieldName: 'accountOwner',
                label: 'Account Owner',
                typeAttributes: {
                    label: { fieldName: 'accountOwnerName' }
                }
            }
        ];
        cmp.set('v.gridColumns', columns);
        var nestedData = [
            {
                "name": "123555",
                "accountName": "Rewis Inc",
                "employees": 3100,
                "phone": "837-555-1212",
                "accountOwner": "http://sfdc.co/jane-doe",
                "accountOwnerName": "Jane Doe"
            },
            {
                "name": "123556",
                "accountName": "Acme Corporation",
                "employees": 10000,
                "phone": "837-555-1212",
                "accountOwner": "http://sfdc.co/john-doe",
                "accountOwnerName": "John Doe",
                "_children": [
                    {
                        "name": "123556-A",
                        "accountName": "Acme Corporation (Bay Area)",
                        "employees": 3000,
                        "phone": "837-555-1212",
                        "accountOwner": "http://sfdc.co/john-doe",
                        "accountOwnerName": "John Doe",
                        "_children": [
                            {
                                "name": "123556-A-A",
                                "accountName": "Acme Corporation (Oakland)",
                                "employees": 745,
                                "phone": "837-555-1212",
                                "accountOwner": "http://sfdc.co/john-doe",
                                "accountOwnerName": "John Doe"
                            },
                            {
                                "name": "123556-A-B",
                                "accountName": "Acme Corporation (San Francisco)",
                                "employees": 578,
                                "phone": "837-555-1212",
                                "accountOwner": "http://sfdc.co/jane-doe",
                                "accountOwnerName": "Jane Doe"
                            }
                        ]
                    }
                ]
            },
        ];
        cmp.set('v.gridData', nestedData);
        var expandedRows = ["123556"];
        cmp.set('v.gridExpandedRows', expandedRows);
    }
})

To retrieve which rows are currently expanded, use the getCurrentExpandedRows() method.

({
    getExpandedRows: function(cmp, event, helper) {
        cmp.set('v.currentExpandedRows', "");
        var treeGridCmp = cmp.find('mytree');
        cmp.set('v.currentExpandedRows', treeGridCmp.getCurrentExpandedRows().toString());
    }
})

Additionally, you can toggle nested items using expandAll() and collapseAll(). For example, you want to expand all nested items.

({
    expandAllRows: function(cmp, event) {
        var tree = cmp.find('mytree');
        tree.expandAll();
    }
})
Retrieving Data Using an Apex Controller
The tree grid can be used to display accounts with contacts as nested items. Create an Apex controller that queries the fields you want to display. In this case, the controller returns the contacts for each account.
public with sharing class AccountController {
    @AuraEnabled
    public static List<Account> getAccountContacts(){
        List<Account> accountcontacts =
            [SELECT Id, Name, Phone, (SELECT Contact.Name, Phone FROM contacts) FROM Account]; 

        return accountcontacts;
    }
}
Wire this up to your component via the controller attribute. Make sure keyField is set to Id since this is the unique identifier for accounts.
<aura:componentcontroller="AccountController">
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    <aura:attribute name="gridColumns" type="List" />
    <aura:attribute name="gridData" type="Object" />
    <lightning:treeGrid columns="{! v.gridColumns }"
        data="{! v.gridData }"
        keyField="Id"
        aura:id="mytree"
    />
</aura:component>
The client-side controller defines the columns and calls a helper function to load the accounts and contact data.
({
    doInit: function (cmp, event, helper) {
        cmp.set('v.gridColumns', [
            {label: 'Account Name', fieldName: 'Name', type: 'text'},
            {label: 'Phone', fieldName: 'Phone', type: 'phone'},
            ]);
        helper.getAcctContacts(cmp);
    }
})
The helper function calls the Apex controller to query record data and set the response data on the gridData attribute.
({
    getAcctContacts : function (cmp) {
        var action = cmp.get("c.getAccountContacts");
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                var data = response.getReturnValue();
                //Change "Contacts" key to "_children"
                for(var i=0; i<data.length;i++) {
                    data[i]._children = data[i]['Contacts'];
                    delete data[i].Contacts; 

                }
                cmp.set('v.gridData', data);
            }
            // error handling when state is "INCOMPLETE" or "ERROR"
         });
         $A.enqueueAction(action);
    }
})

The table displays two columns, Account Name and Phone. Accounts with contacts are displayed with a chevron to denote that they can be expanded to reveal those contacts.

Working with Column Data

Use the following column properties to customize your data.

Property Type Description
label string Required. The text label displayed in the column header.
fieldName string Required. The name that binds the columns properties to the associated data. Each columns property must correspond to an item in the data array.
type string Required. The data type to be used for data formatting. For more information, see Formatting with Data Types.
initialWidth integer The width of the column when it's initialized, which must be within the minColumnWidth and maxColumnWidth values, or within 50px and 1000px if they are not provided.
typeAttributes object Provides custom formatting with component attributes for the data type. For example, currencyCode for the currency type. For more information, see Formatting with Data Types.
cellAttributes object Provides additional customization, such as appending an icon to the output. For more information, see Appending an Icon to Column Data
actions object Appends a dropdown menu of actions to a column. You must pass in a list of label-name pairs.
iconName string The Lightning Design System name of the icon. Names are written in the format standard:opportunity. The icon is appended to the left of the header label.
Formatting with Data Types

The table determines the format based on the type you specify. Each data type is associated to a base Lightning component. For example, specifying the text type renders the associated data using a lightning:formattedText component. Some of these types allow you to pass in the attributes via the typeAttributes property to customize your output.

The first column in the table supports the following data types.

Type Description Supported Type Attributes
currency Displays a currency using lightning:formattedNumber currencyCode, currencyDisplayAs
date Displays a date and time based on the locale using lightning:formattedDateTime N/A
number Displays a number using lightning:formattedNumber minimumIntegerDigits, minimumFractionDigits, maximumFractionDigits, minimumSignificantDigits, maximumSignificantDigits
percent Displays a percentage using lightning:formattedNumber Same as number type
text Displays text using lightning:formattedText N/A
url Displays a URL using lightning:formattedUrl label, target

All other columns support the following data types.

Type Description Supported Type Attributes
action Displays a dropdown menu using lightning:buttonMenu with actions as menu items rowActions (required), menuAlignment (defaults to right)
button Displays a button using lightning:button disabled, iconName, iconPosition, label, name, title, variant
currency Displays a currency using lightning:formattedNumber currencyCode, currencyDisplayAs
date Displays a date and time based on the locale using lightning:formattedDateTime N/A
email Displays an email address using lightning:formattedEmail N/A
location Displays a latitude and longitude of a location using lightning:formattedLocation latitude, longitude
number Displays a number using lightning:formattedNumber minimumIntegerDigits, minimumFractionDigits, maximumFractionDigits, minimumSignificantDigits, maximumSignificantDigits
percent Displays a percentage using lightning:formattedNumber Same as number type
phone Displays a phone number using lightning:formattedPhone N/A
text Displays text using lightning:formattedText N/A
url Displays a URL using lightning:formattedUrl label, target

To customize the formatting based on the data type, pass in the attributes for the corresponding base Lightning component. For example, pass in a custom currencyCode value to override the default currency code.

var columns = [
    {label: 'Amount', fieldName: 'amount', type: 'currency', typeAttributes: { currencyCode: 'EUR' }}
    // other column data
]

When using currency or date and time types, the default user locale is used when no locale formatting is provided. For more information on attributes, see the corresponding component documentation.

Creating Header-Level and Row-Level Actions

Header-level actions refer to tasks you can perform on a column of data, while row-level actions refer to tasks you can perform on a row of data, such as updating or deleting the row. Creating actions in lightning:treeGrid is similar to creating actions in lightning:datatable. For more information, see the lightning:datatable documentation.

Asynchronous Loading of Nested Items

If you have a large number of nested items that would delay the loading of your data, consider loading your nested items asynchronously. The nested items are displayed only when you expand the particular row. To do so, initialize your data without nested items.

var mydata = [
    {
        "name": "123556-A",
        "accountName": "Acme Corporation (Bay Area)",
        :
        :
        "_children": []
    }, //more data
];

Define the nested items separately.

childrenData: {
        "123556-A": [
            {
                "name": "123556-A-A",
                "accountName": "Acme Corporation (Oakland)",
                :
                :
            },
            {
                "name": "123556-A-B",
                "accountName": "Acme Corporation (San Francisco)",
                :
                :
            }
        ],

Handle asynchronous loading of nested items when a row is expanded using the ontoggle action. Find the name of the row being expanded and check if data for the nested items is already available before retrieving and displaying the nested items.

({
    handleRowToggle: function(cmp, event, helper) {
        var rowName = event.getParam('name');
        var hasChildrenContent = event.getParam('hasChildrenContent');
        if (!hasChildrenContent) {
            // Retrieve and display the nested items
            // by passing in the original data, row name, and data for the nested items
        }
    }       
})

The ontoggle action returns these parameters.

Parameter Type Description
name String The unique ID for the row that's toggled.
isExpanded Boolean Specifies whether the row is expanded or not.
hasChildrenContent Boolean Specifies whether any data is available for the nested items of this row.
row Object The toggled row data.
Text Wrapping and Clipping

You can wrap or clip text within columns, which either expands the rows to reveal more content or truncate the content to a single line within the column.

To toggle between the two views, select Wrap text or Clip text from the dropdown menu on the column header.

If the number of characters is more than what the column width can hold, content is clipped by default. Text wrapping is supported only for the following data types.
  • currency
  • date
  • email
  • location
  • number
  • percent
  • phone
  • text
  • url
Accessibility

This component supports navigation mode and action mode using the keyboard. To enter navigation mode, tab into the table, which triggers focus on the first data cell in the table body. Use the arrow keys to move around the table.

To enter action mode, press the Enter key or Space Bar. Columns can be resized in action mode. To resize a column, navigate to the header by pressing the Up Arrow key. Then, press the Tab key to activate the column divider, and resize the column using the Left Arrow and Right Arrow key. To finish resizing the column and return to navigation mode, press the Tab key.

When focus is on a cell that contains a link, pressing enter to navigate to the link is currently not supported. This limitation applies to cells that contain data of type url, phone, and email.

Methods

This component supports the following methods.

collapseAll(): Collapses all rows with nested items.

expandAll(): Expands all rows with nested items.

getCurrentExpandedRows(): Returns an array containing the IDs for all rows that are marked as expanded.

getSelectedRows(): Returns an array containing the data for each selected row.

Attribute Name Attribute Type Description Required?
body Component[] The body of the component. In markup, this is everything in the body of the tag.
class String A CSS class for the outer element, in addition to the component's base classes.
columns List Array of the columns object that's used to define the data types. Required properties include 'label', 'dataKey', and 'type'. The default type is 'text'.
data Object The array of data to be displayed.
expandedRows List The array of unique row IDs that are expanded.
hideCheckboxColumn Boolean Hides or displays the checkbox column for row selection. To hide the checkbox column, set hideCheckboxColumn to true. The default is false.
isLoading Boolean Specifies whether more data is being loaded and displays a spinner if so. The default is false.
keyField String Required for better performance. Associates each row with a unique ID. Yes
maxColumnWidth Integer The maximum width for all columns. The default is 1000px.
minColumnWidth Integer The minimum width for all columns. The default is 50px.
onresize Action The action triggered when the table renders columns the first time and every time its resized an specific column.
onrowaction Action The action triggered when an operation its clicked. By default its to closes the actions menu.
onrowselection Action The action triggered when a row is selected.
ontoggle Action The action triggered when a row is toggled (expanded or collapsed).
ontoggleall Action The action triggered when all rows are toggled (expanded or collapsed).
resizeColumnDisabled Boolean Specifies whether column resizing is disabled. The default is false.
rowNumberOffset Integer Determines where to start counting the row number. The default is 0.
selectedRows List The array of unique row IDs that are selected.
showRowNumberColumn Boolean Hides or displays the row number column. To show the row number column, set showRowNumberColumn to true. The default is false.
title String Displays tooltip text when the mouse moves over the element.