Dynamically Creating Lightning Tabs

In this blog, I am going to show how to create a lightning component tabs dynamically by using lightning:tabset and lightning:tab components. In this example, simple I am creating four tabs dynamically when the user clicks on the button.

Lightning Component 

<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global">
    <aura:attribute name="moretabs" type="Aura.Component[]"/>
    <lightning:tabset variant="scoped">
        <lightning:tab label="Item One">
            Some content here
        </lightning:tab>
        <aura:iteration items="{!v.moretabs}" var="obj">
            {!obj}
        </aura:iteration>
        
    </lightning:tabset>
    <lightning:button label="Add tab" onclick="{!c.addTab}"/>
</aura:component>

 

({
    addTab: function(component, event) {
        var detail = component.get("v.moretabs");
        var newlst =[];
        newlst.push(detail);
        for(var i=0; i <4; i++){
            $A.createComponent("lightning:tab", {
                "label": "New Tab"+i,
                "id": "new"+i,
                "onactive": component.getReference("c.addContent")
            }, function (newTab, status, error) {
                if (status === "SUCCESS") {
                    newlst.push(newTab);
                    component.set("v.moretabs", newlst);
                } else {
                    throw new Error(error);
                }
            });
        }
    },
    addContent : function(component, event) {
        var tab = event.getSource();
        switch (tab.get('v.id')){
            case 'new':
                $A.createComponent("lightning:badge", {
                    "label": "NEW"
                }, function (newContent, status, error) {
                    if (status === "SUCCESS") {
                        tab.set('v.body', newContent);
                    } else {
                        throw new Error(error);
                    }
                });
                break;
        }
    }
})

On click of the button, the tabs will created dynamically as shown below.

 

lightning:notificationsLibrary Example

In this blog, I am going to explain how to use lightning:notificationsLibrary that provides an easy way to display notices and toast in the app. lightning:notificationsLibrary  component is supported in Lightning Experience, Salesforce app, and Lightning communities only. Include one <lightning:notificationsLibrary aura:id=”notifLib”/> tag in the component that triggers the notifications, where aura:id is a unique local ID. Only one tag is needed for multiple notifications.

Notices

Notices interrupt the user’s workflow and block everything else on the page. Notices must be acknowledged before a user regains control over the app again. As such, use notices sparingly. They are not suitable for confirming a user’s action, such as before deleting a record. To dismiss the notice, only the OK button is currently supported.

<lightning:notificationsLibrary aura:id="notifLib"/>
    <lightning:button name="Show Error Notice" label="Show Error Notice" onclick="{!c.handleShowErrorNotice}"/>

 

 handleShowErrorNotice : function(component, event, helper) {
        component.find('notifLib').showNotice({
            "variant": "error",
            "title":"Error",
            "header": "Something has gone wrong!",
            "message": "Unfortunately, there was a problem updating the record.",
            closeCallback: function() {
                alert('You closed the alert!');
            }
        });
    },

Toasts

Toasts are less intrusive than notices and are suitable for providing feedback to a user following an action, such as after a record is created. A toast can be dismissed or can remain visible until a predefined duration has elapsed.

<lightning:notificationsLibrary aura:id="notifLib"/>
<lightning:button name="success" label="Show Success" onclick="{!c.handlesuccessToast}"/>

 

handlesuccessToast : function(component, event, helper) {
        component.find('notifLib').showToast({
            "variant":"success",
            "title": "Notif library Success!",
            "mode":"sticky",
            "message": "The record has been updated successfully."
        });
    }

 

The Below lightning component shows the different type of notifications.

 

<aura:component implements="flexipage:availableForAllPageTypes,force:appHostable">
    <lightning:notificationsLibrary aura:id="notifLib"/>
    <lightning:button name="Show Error Notice" label="Show Error Notice" onclick="{!c.handleShowErrorNotice}"/>
    <lightning:button name="Show info Notice" label="Show info Notice" onclick="{!c.handleShowInfoNotice}"/>
    <lightning:button name="Show warning Notice" label="Show warning Notice" onclick="{!c.handleShowWarningNotice}"/>
    <lightning:button name="info" label="Show info" onclick="{!c.handleinfoToast}"/>
    <lightning:button name="warning" label="Show Warning" onclick="{!c.handlewarningToast}"/>
    <lightning:button name="success" label="Show Success" onclick="{!c.handlesuccessToast}"/>
    <lightning:button name="Erorr" label="Show Error" onclick="{!c.handleerrorToast}"/>  
</aura:component>

 

({    
    handleShowErrorNotice : function(component, event, helper) {
        component.find('notifLib').showNotice({
            "variant": "error",
            "title":"Error",
            "header": "Something has gone wrong!",
            "message": "Unfortunately, there was a problem updating the record.",
            closeCallback: function() {
                alert('You closed the alert!');
            }
        });
    },
    handleShowInfoNotice : function(component, event, helper) {
        component.find('notifLib').showNotice({
            "variant": "info",
            "title":"Info",
            "header": "Infomration Message!",
            "message": "Please Modify the Record.",
            closeCallback: function() {
                alert('You closed the alert!');
            }
        });
    },
    handleShowWarningNotice : function(component, event, helper) {
        component.find('notifLib').showNotice({
            "variant": "warning",
            "title":"Error",
            "header": "Something has gone wrong!",
            "message": "Unfortunately, there was a problem updating the record.",
            closeCallback: function() {
                alert('You closed the alert!');
            }
        });
    },
    handleinfoToast : function(component, event, helper) {
        component.find('notifLib').showToast({
            "variant":"info",
            "title": "Notif library Success!",
            "message": "The record has been updated successfully."
        });
    },
    handlewarningToast : function(component, event, helper) {
        component.find('notifLib').showToast({
            "variant":"warning",
            "mode":"dismissable",
            "title": "Notif library Success!",
            "message": "The record has been updated successfully."
        });
    },
    handlesuccessToast : function(component, event, helper) {
        component.find('notifLib').showToast({
            "variant":"success",
            "title": "Notif library Success!",
            "mode":"sticky",
            "message": "The record has been updated successfully."
        });
    },
    handleerrorToast : function(component, event, helper) {
        component.find('notifLib').showToast({
            "variant":"error",
            "mode":"pester",
            "title": "Notif library Success!",
            "message": "The record has been updated successfully."
        });
    }
})

 

 

 

Usage of lightning:treeGrid

In this blog, I am going to show how to use 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. In this example, I am going to show account and its contacts and opportunities as a tree grid.

Apex Class 

public class TreeGridExamples {
    @AuraEnabled
    public static String getTreeGridData(){
        List<Account> accs = [Select Id , Name,(Select Id , Name from Contacts) from Account];
        Map<Id , Contact> opps =new Map<Id , Contact>( [Select Id , Name,(Select Id ,Name From Opportunities) from Contact]);
        
        List<AccountWrapper> aooo = new List<AccountWrapper>();
        for(Account a : accs){
            AccountWrapper aWraper = new AccountWrapper() ; 
            aWraper.name =a.Name ;
            aWraper.label =a.Name ;
            List<Items> co = new List<Items>();
            for(Contact c : a.Contacts){
                Items conWrapp = new Items();
                conWrapp.name =c.Name ;
                conWrapp.label =c.Name ;
                
                List<Items> wrapperOooo = new List<Items>();
                for(Opportunity o : opps.get(c.Id).Opportunities){
                    Items ooo = new Items(); 
                    ooo.name = o.Name ;
                    ooo.label = o.Name ;
                    wrapperOooo.add(ooo);
                }
                
                conWrapp.items =wrapperOooo ;
                co.add(conWrapp);
            }
            aWraper.items = co;
            aooo.add(aWraper);
            
        }
        return JSON.serializePretty(aooo) ;
    } 
    public Class AccountWrapper{
        @AuraEnabled
        public String name {get;set;}
        @AuraEnabled
        public String label {get;set;}
        @AuraEnabled
        public List<Items> items {get;set;}
    }
    public Class Items{
        @AuraEnabled
        public String name {get;set;}
        @AuraEnabled
        public String label {get;set;}
        @AuraEnabled
        public List<Items> items {get;set;}
    }
    
}

Lightning Component 

<aura:component controller="TreeGridExamples">
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    <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 }"
                        keyField="name"
                        aura:id="mytree"
                        />
</aura:component>

 

({
    doInit: function (cmp, event, helper) {
        cmp.set('v.gridColumns', [
            {label: 'name', fieldName: 'name', type: 'text'},
            {label: 'label', fieldName: 'label', type: 'text'},
            ]);
        helper.getData(cmp);
    },
            
   
})

 

({
    getData : function (cmp) {
        var action = cmp.get("c.getTreeGridData");
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                var data = response.getReturnValue();
                var temojson = JSON.parse(JSON.stringify(data).split('items').join('_children'));
                console.log(temojson);
                cmp.set('v.gridData', JSON.parse(temojson));
            }
            // error handling when state is "INCOMPLETE" or "ERROR"
        });
        $A.enqueueAction(action);
    }
})

Below image shows the treegrid output.