function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Ragul MRagul M 

TreeView in lightning

I am facing issue when creating a Tree view using Nested Components with LockerService Activated.

Following error msg thrown.
Uncaught TypeError: Cannot read property 'expando' of undefined throws at /resource/jquery224:5:8057
 
Disable the locker service fixing this issue. But i need the output without disabling.

Step-1: AccConListController.apxc
 
public class AccConListController {
    @AuraEnabled
    public static List<Account> getAccounts() {
        List<Account> accounts=[SELECT Id, Name, (select name, Phone, Email FROM Contacts) FROM Account limit 1000];
        return accounts;
    }
}
In this class we create a funtion which is used for getting accounts and its related contacts.
Step-2: AccountRow.cmp​
 
<aura:component >
    <aura:attribute name="acc" type="Account" />
    <aura:attribute name="ext" type ="String" default="plus"/>
    <li  id="tree0-node0" class="slds-tree__branch slds-is-open" role="treeitem" aria-level="1" aria-expanded="true">
        <div class="slds-tree__item">
            <aura:if isTrue="{!v.acc.Contacts[0] != null}">
                <aura:if isTrue="{!v.ext=='plus'}">
                    <div id="plus" ><img draggable="false" class="emoji" alt="➕" src="https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/svg/2795.svg"></div>
                    <aura:set attribute="else">
                        <div id="minus"><img draggable="false" class="emoji" alt="➖" src="https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/svg/2796.svg"></div>
                    </aura:set>
                </aura:if> 
                &nbsp;
                <aura:set attribute="else">
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                </aura:set>
            </aura:if> 
            <a id="tree0-node0-0-link"  tabindex="-1" onclick="{!c.showHidePanel}" role="presentation">{!v.acc.Name}</a>
        </div>

        <ul aura:id="{!v.acc.Id}" id="{!v.acc.Id}" style="display:none;" class="slds-tree__group slds-nested" role="group" aria-labelledby="tree0-node0-link">
            <aura:iteration items="{!v.acc.Contacts}" var="con">
                <li id="tree0-node0-1" class="slds-tree__item" role="treeitem" aria-level="2" style="margin-left: 20px;">
                    <a href="#" role="presentation" class="slds-truncate" style="color: darkgoldenrod;">{!con.Name}</a>     
                </li>
            </aura:iteration>
        </ul>
    </li>
</aura:component>
This is a Child component and it is used for show an account name and its related contacts.

Step-3: AccountRowController.js​
({
    showHidePanel : function(component, event, helper) {
        var id=component.get("v.acc.Id");        
        var e=document.getElementById(id);      
        if (e.style.display == 'block' || e.style.display==''){
            e.style.display = 'none';
            component.set("v.ext","plus");
        }else{
            e.style.display = 'block';
            component.set("v.ext","minus");
        } 
    },
})
This is controller of AccountRow Component.

Step-4: AccountTree.cmp
<aura:component controller="AccConListController" implements="force:appHostable">
    <ltng:require styles="/resource/SLDS/assets/styles/salesforce-lightning-design-system-vf.css" 
                  scripts="/resource/jquerymin" 
                  afterScriptsLoaded="{!c.doInit}" />    
    <aura:attribute name="Accounts" type="Account[]" />
    <div class="slds">
        <div class="slds-page-header">
            <div class="slds-grid">
                <div class="slds-col slds-has-flexi-truncate">
                    <div class="slds-media">
                        <div class="slds-media__figure">
                            <c:svgIcon svgPath="/resource/SLDS/assets/icons/standard-sprite/svg/symbols.svg#process" category="standard" size="large" name="user" />
                        </div>
                        <div class="slds-media__body">
                            <p class="slds-text-heading--label">Tree View</p>
                            <div class="slds-grid">
                                <h1 class="slds-text-heading--medium slds-m-right--small slds-truncate slds-align-middle">Account -> Contact</h1>
                            </div>
                        </div>
                    </div>
                </div>
                <!-- /slds-col-->                        
            </div>   
            <!-- /slds-grid-->                 
        </div>
        <!-- /slds-page-header-->
        <div class="slds-tree-container" role="application">
            <ul class="slds-tree" role="tree" aria-labelledby="treeheading" aria-activedescendant="tree0-node0">
                <aura:iteration items="{!v.Accounts}" var="acc">          
                    <c:AccountRow acc="{!acc}" />
                </aura:iteration>
            </ul>
        </div>
    </div>
</aura:component>
This is parent component that holds AccountRow component as a nested component. And also i am using here SVG Icon in header. For more detail about SVG Icon Click here.

Step-5: AccountTreeController.js
({
    doInit : function(component, event, helper) {          
        helper.getAccounts(component);          
    },

    showPanel : function(component, event, helper){        
        helper.onLoadPage(component); 
    },

})
This is controller of AccountTree Component.

Step-6: AccountTreeHelper.js
 
({
    //Fetch the Accounts from the Apex controller
    getAccounts: function(component) {        
        var action = component.get("c.getAccounts");
        //Set up the callback
        var self = this;
        action.setCallback(this, function(actionResult) {
            component.set("v.Accounts", actionResult.getReturnValue());            
        });        
        $A.enqueueAction(action);                
    },        
})
This is helper of AccountTree Component. Its getAccounts() function calls getAccounts() method of AccConListController.apxc class
Source for the code: