Salesforce Lightning TreeGrid

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. Here is an example of lightning:datatable.

Note: This component requires API version 42.0 and later.

Apex Controller:

public class SampleAuraController {
    
    @AuraEnabled
    public static List <Account> getAccountList() {
        List<Account> accList = new List<Account>();
        accList = [SELECT Id, Name, NumberOfEmployees, Phone,
                   (SELECT FirstName, LastName, Email FROM Contacts)
                   FROM Account LIMIT 10];
        return accList;
    }
}

Lightning Component:

<!--Sample.cmp--> 
<aura:component controller="SampleAuraController" implements="flexipage:availableForAllPageTypes" access="global">
    <aura:attribute type="Account[]" name="acctList"/>
    <aura:attribute name="gridColumns" type="List" />
    <aura:attribute name="gridData" type="Object" />
    <aura:attribute name="gridExpandedRows" type="Object" />
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    <div class="slds-m-around_xx-large">
        <lightning:treeGrid aura:id="accTree" columns="{!v.gridColumns}" data="{!v.gridData}" keyField="Id"/>
    </div>
</aura:component>

Lightning Component JS Controller:

({
    doInit : function(component, event, helper) {
        var columns = [
            {
                type: 'text',
                fieldName: 'Name',
                label: 'Account Name'
            },
            {
                type: 'number',
                fieldName: 'NumberOfEmployees',
                label: 'Employees'
            },
            {
                type: 'phone',
                fieldName: 'Phone',
                label: 'Phone Number'
            },
            {
                type: 'text',
                fieldName: 'FirstName',
                label: 'First Name'
            },
            {
                type: 'text',
                fieldName: 'LastName',
                label: 'Last Name'
            },
            {
                type: 'email',
                fieldName: 'Email',
                label: 'Email'
            }
        ];
        component.set('v.gridColumns', columns);
        var action = component.get("c.getAccountList");
        action.setCallback(this, function(response){
            var state = response.getState();
            if (state === "SUCCESS" ) {
                var resultData = response.getReturnValue();
                for (var i=0; i<resultData.length; i++ ) {
                    resultData[i]._children = resultData[i]['Contacts'];
                    delete resultData[i].Contacts; 
                }
                component.set('v.gridData', resultData);
            }
        });
        $A.enqueueAction(action);
    }
})

Output:

Reference: lightning:treeGrid

Documentation in Salesforce Lightning Component Bundle

Component documentation helps others understand and use your components. Here is a sample example of Lightning Component Documentation.

Sample Component:

<!--Sample.cmp--> 
<aura:component implements="flexipage:availableForAllPageTypes" access="global">
    <strong>Sample Component</strong>
</aura:component>

To create documentation of above component, click DOCUMENTATION in the component sidebar of the Developer Console. Hereaura:description is to show the description of the component and aura:example is to show look and feel of the component.

<aura:documentation>
    <aura:description>
        <p>An <code>c:Sample</code> component represents an element that executes an action defined by a controller.</p>
    </aura:description>
    <aura:example name="Sample" ref="c:Sample" label="Using the c:Sample Component">
        <p>This example shows a simple setup of <code>Sample</code>.</p>
    </aura:example>
</aura:documentation>

The documentation you create will be available at https://.lightning.force.com/auradocs/reference.app, where is the name of your custom Salesforce domain and in the Component Library at https://.lightning.force.com/componentReference/suite.app where is the name of your custom Salesforce domain.

Create Survey Using Salesforce Surveys

Enable Surveys within your Org:

Go to Setup || Feature Settings || Survey || Survey Settings || Enable the Survey setting and Select the Community

Give users access to create surveys:
Create a Permission Set and give access to Surveys and Survey Invitations objects.

Survey Object Permission:

Survey Invitations objects Permission:

Assign the above created permission set to the users who will create surveys.

Create Survey:

Multi Select Picklist in Lightning Component

We can use lightning:dualListbox component to show multi select picklist field values. lightning:dualListbox component represents two side-by-side list boxes. Select one or more options in the list on the left. Move selected options to the list on the right. The order of the selected options is maintained and we can reorder options.

Here in below example I’m using a Custom object “Book”, and the multi select picklist field “Genre” of “Book” object.
Apex Class:

public class SampleAuraController {
    
    @AuraEnabled
    public static List <String> getPiklistValues() {
        List<String> plValues = new List<String>();
        
        //Get the object type from object name. Here I've used custom object Book.
        Schema.SObjectType objType = Schema.getGlobalDescribe().get('Book__c');
        
        //Describe the sObject using its object type.
        Schema.DescribeSObjectResult objDescribe = objType.getDescribe();
        
        //Get the specific field information from field name. Here I've used custom field Genre__c of Book object.
        Schema.DescribeFieldResult objFieldInfo = objDescribe.fields.getMap().get('Genre__c').getDescribe();
        
        //Get the picklist field values.
        List<Schema.PicklistEntry> picklistvalues = objFieldInfo.getPicklistValues();
        
        //Add the picklist values to list.
        for(Schema.PicklistEntry plv: picklistvalues) {
            plValues.add(plv.getValue());
        }
        plValues.sort();
        return plValues;
    }
}

Lightning Component:

<!--MultiSelectPicklist.cmp-->
<aura:component controller="SampleAuraController">
    
    <!--Declare Event Handlers--> 
    <aura:handler name="init" action="{!c.doInit}" value="{!this}" description="Call doInit function on component load to get picklist values"/>
    
    <!--Declare Attributes-->
    <aura:attribute name="GenreList" type="List" default="[]" description="Genre Picklist Values"/>
    <aura:attribute name="selectedGenreList" type="List" default="[]" description="Selected Genre Picklist Values"/>
    
    <div class="slds-m-around_xx-large">
        <lightning:dualListbox aura:id="selectGenre"
                               name="Genre"
                               label="Select Genre" 
                               sourceLabel="Available Genre" 
                               selectedLabel="Selected Genre" 
                               options="{!v.GenreList }"
                               value="{!v.selectedGenreList}"
                               onchange="{!c.handleGenreChange}"/>
        <lightning:button variant="brand" label="Get Selected Genre" onclick="{!c.getSelectedGenre}" />
    </div>
</aura:component>

Lightning Component JS Controller:

({
    doInit: function(component, event, helper) {
        var action = component.get("c.getPiklistValues");
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS"){
                var result = response.getReturnValue();
                var plValues = [];
                for (var i = 0; i < result.length; i++) {
                    plValues.push({
                        label: result[i],
                        value: result[i]
                    });
                }
                component.set("v.GenreList", plValues);
            }
        });
        $A.enqueueAction(action);
    },
    
    handleGenreChange: function (component, event, helper) {
        //Get the Selected values   
        var selectedValues = event.getParam("value");
        
        //Update the Selected Values  
        component.set("v.selectedGenreList", selectedValues);
    },
    
    getSelectedGenre : function(component, event, helper){
        //Get selected Genre List on button click 
        var selectedValues = component.get("v.selectedGenreList");
        console.log('Selectd Genre-' + selectedValues);
    }
})

Output:

Iterate Map List Values in Lightning Component

Apex Class:

public class SampleAuraController {
    
    @AuraEnabled
    Public static Map<string, List<string>> getMap(){ 
        Map<String, List<string>> mapObj = new Map<String, List<string>>();
        List<string> fruits = new List<String>{'Apple', 'Orange', 'Banana', 'Grapes'};
		List<string> vegetables = new List<String>{'Cabbage', 'Carrot', 'Potato', 'Tomato'};
		mapObj.put('Fruits', fruits);
        mapObj.put('Vegetables', vegetables);  
        return mapObj;
    }
}

Lightning Component:

<aura:component controller="SampleAuraController">
    <aura:attribute name="mapValues" type="object" />	
    <div class="slds-m-around_xx-large">
        <div class="slds-box slds-theme_default">
            <lightning:button label="Iterate Map" onclick="{!c.getMapValues}"/>
            <aura:iteration items="{!v.mapValues}"  var="mapKey" indexVar="key">  
                <strong><p>{!mapKey.key}</p></strong>
                <aura:iteration items="{!mapKey.value}" var="mapValue">
                    <p>{!mapValue}</p>
                </aura:iteration>
            </aura:iteration>
        </div>
    </div>
</aura:component>

Lightning Component JS Controller:

({
    getMapValues : function(component, event, helper) {
        var action = component.get("c.getMap");
        action.setCallback(this, function(response){
            var state = response.getState();
            if (state === "SUCCESS"){
                var result = response.getReturnValue();
                var arrayMapKeys = [];
                for(var key in result){
                    arrayMapKeys.push({key: key, value: result[key]});
                }
                component.set("v.mapValues", arrayMapKeys);
            }
        });
        $A.enqueueAction(action);
    }
})

Output: