Category Archives: Salesforce

Lightning Component Client Side Pagination

Pagination Component:
Create a new Lightning Component Pagination.cmp.

<!--Pagination.cmp-->
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" 
                controller='PaginationController'
                access="global" >
    
    <!-- Attribute Declration For Pagination -->
    <aura:attribute name="ContactData" type="Object"/>
    <aura:attribute name="columns" type="List"/>
    
    <aura:attribute name="isSending" type="boolean" />
    
    <!-- Attribute Declration For Pagination -->
    <aura:attribute name="PaginationList" type="Contact"/>
    <aura:attribute name="startPage" type="Integer" />
    <aura:attribute name="endPage" type="Integer"/>
    <aura:attribute name="totalRecords" type="Integer"/>
    <aura:attribute name="pageSize" type="Integer" default="10"/>
    <!-- Attribute Declration For Pagination End-->
    
    <aura:handler name="init" value="{! this }" action="{! c.doInit }"/>
    
    <!-- Spinner Start, show the loading screen while 
   Client side controller(JS) is communicating with Server Side(APEX) controller -->
    <aura:if isTrue="{!v.isSending}">
        <div class="slds-spinner_container">
            <div class="slds-spinner--brand slds-spinner slds-spinner--large" role="alert">
                <span class="slds-assistive-text">Loading</span>
                <div class="slds-spinner__dot-a"></div>
                <div class="slds-spinner__dot-b"></div>
            </div>
        </div>
    </aura:if>
    <!-- Spinner End -->
    
    <div class="slds-page-header">
        <div class="slds-media">
            <div class="slds-media__figure">
                <span class="slds-icon_container slds-icon-standard-opportunity" 
                      title="Description of icon when needed">
                    
                </span>
            </div>
        </div>
    </div>
    
    <div class="slds-m-top_medium" >
        <lightning:datatable data="{! v.PaginationList }" class="slds-m-top_medium"
                             columns="{! v.columns }" 
                             keyField="id"
                             onrowselection="{! c.getSelectedName }"/>	
        <br/>
        <lightning:buttonGroup >
            <lightning:button label="Previous" disabled="{!v.startPage == 0}"  
                              onclick="{!c.previous}" variant="brand"
                              iconName='utility:back'/>
            &nbsp; &nbsp; &nbsp;
            <lightning:button label="Next" disabled="{!v.endPage >= v.totalRecords}" 
                              onclick="{!c.next}" variant="brand"
                              iconName='utility:forward' iconPosition='right'/>
        </lightning:buttonGroup>
    </div>
</aura:component>

Pagination JavaScript Controller:
Now create below JavaScript PaginationController.js controller for above Pagination.cmp component.

({
    doInit: function (component, event, helper) {
        // Set the columns of the Table 
        component.set('v.isSending',true);
        component.set('v.columns', [
            {label: 'Name', fieldName: 'Name', type: 'text', sortable : true},
            {label: 'Email', fieldName: 'Email', type: 'email', sortable : true},
            {label: 'Phone', fieldName: 'Phone', type: 'phone', sortable : true}]);
        helper.doFetchContact(component);
    },
    getSelectedName: function (component, event) {
        var selectedRows = event.getParam('selectedRows');
        // Display that fieldName of the selected rows
        for (var i = 0; i < selectedRows.length; i++){
            alert("You selected: " + selectedRows[i].Name);
        }
    },
    next: function (component, event, helper) {
        helper.next(component, event);
    },
    previous: function (component, event, helper) {
        helper.previous(component, event);
    }
})

Pagination JavaScript Controller Helper:
Now create below JavaScript PaginationHelper.js helper for above PaginationController.js component.

({
    /*
     * Initially this Method will be called and will fetch the records from the Salesforce Org 
     * Then we will hold all the records into the attribute of Lightning Component
     */
    doFetchContact : function(component) {
        var action = component.get('c.getContacts');
        action.setCallback(this, function(response){
            var state = response.getState();
            if(state === 'SUCCESS' && component.isValid()){
                var pageSize = component.get("v.pageSize");
                // hold all the records into an attribute named "ContactData"
                component.set('v.ContactData', response.getReturnValue());
                // get size of all the records and then hold into an attribute "totalRecords"
                component.set("v.totalRecords", component.get("v.ContactData").length);
                // set star as 0
                component.set("v.startPage",0);
                
                component.set("v.endPage",pageSize-1);
                var PaginationList = [];
                for(var i=0; i< pageSize; i++){
                    if(component.get("v.ContactData").length> i)
                        PaginationList.push(response.getReturnValue()[i]);    
                }
                component.set('v.PaginationList', PaginationList);
                component.set('v.isSending',false);
            }else{
                alert('ERROR');
            }
        });
        $A.enqueueAction(action);
    },
    /*
     * Method will be called when use clicks on next button and performs the 
     * calculation to show the next set of records
     */
    next : function(component, event){
        var sObjectList = component.get("v.ContactData");
        var end = component.get("v.endPage");
        var start = component.get("v.startPage");
        var pageSize = component.get("v.pageSize");
        var Paginationlist = [];
        var counter = 0;
        for(var i=end+1; i<end+pageSize+1; i++){
            if(sObjectList.length > i){
                Paginationlist.push(sObjectList[i]);
            }
            counter ++ ;
        }
        start = start + counter;
        end = end + counter;
        component.set("v.startPage",start);
        component.set("v.endPage",end);
        component.set('v.PaginationList', Paginationlist);
    },
    /*
     * Method will be called when use clicks on previous button and performs the 
     * calculation to show the previous set of records
     */
    previous : function(component, event){
        var sObjectList = component.get("v.ContactData");
        var end = component.get("v.endPage");
        var start = component.get("v.startPage");
        var pageSize = component.get("v.pageSize");
        var Paginationlist = [];
        var counter = 0;
        for(var i= start-pageSize; i < start ; i++){
            if(i > -1){
                Paginationlist.push(sObjectList[i]);
                counter ++;
            }else{
                start++;
            }
        }
        start = start - counter;
        end = end - counter;
        component.set("v.startPage",start);
        component.set("v.endPage",end);
        component.set('v.PaginationList', Paginationlist);
    }
})

Pagination Apex Controller:
Create below apex controller to use it in Pagination.cmp component.

public class PaginationController {
    @AuraEnabled
    public static List<Contact> getContacts(){
        List<Contact> contactList = new List<Contact>();
        contactList = [SELECT Id, Name, Email, Phone From Contact LIMIT 50];
        return contactList;
    }
}

Pagination App:

<!--PaginationApp.app-->
<aura:application extends="force:slds">
    <c:Pagination />    
</aura:application>

Output:

Nested server side method calling in Lightning Component

Apex Controller:

public class SampleAuraController {
    
    @AuraEnabled
    public static String firstAction() {
        return 'First Action';
    }
    
    @AuraEnabled
    public static String secondAction() {
        return 'Second Action';
    }
}

Lightning Component:

<!--Sample.cmp--> 
<aura:component controller="SampleAuraController" implements="flexipage:availableForAllPageTypes" access="global">
    <div class="slds-m-around_xx-large">
        <lightning:button variant="brand" label="Click" onclick="{!c.handleAction}" />
    </div>
</aura:component>

Lightning Component JS Controller:

({
    handleAction : function(component, event, helper) {
        var action1 = component.get("c.firstAction");
        action1.setCallback(this, function(response){
            var state = response.getState();
            if (state === "SUCCESS") {
                var result1  = response.getReturnValue();
                alert(result1);
                var action2 = component.get("c.secondAction");
                action2.setCallback(this, function(response){
                    var state = response.getState();
                    if (state === "SUCCESS") {
                        var result2  = response.getReturnValue();
                        alert(result2);
                    }
                });
                $A.enqueueAction(action2);
            }
        });
        $A.enqueueAction(action1);
    }
})

SVG in Lightning Component Bundle

SVG resource is to define a custom icon for the lightning component when it appears in the Lightning App Builder’s component pane. SVG icons is used in Salesforce Lightning App Builder or Community Builder.

Here is a lightning component with default SVG icon:

Sample Component:

<aura:component implements="flexipage:availableForAllPageTypes">
    <strong>Sample Component</strong>
</aura:component>

The default SVG icon looks like below:

Edit the SVG for custom SVG icon of above “Sample” lightning component: To customize the default SVG, click SVG in the component sidebar of the Developer Console.

Custom Sample Component SVG icon: Here I’ve changed the custom SVG icon to a rectangle filled with blue color. You can change it to as per your requirement.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400">
	<rect width="400" height="300" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
</svg>

The custom SVG icon looks like below:

Convert Attachment to File in Salesforce Using Apex

Salesforce introduced Files related list in Winter’16, and now Salesforce is going to replace Notes and Attachment section with Files. Basically, Files that you upload to the Notes & Attachments related list on records in Salesforce Classic are now Salesforce Files objects, rather than the old attachment objects.

Sometimes you may have requirement to move attachment documents to file using apex. Before creating Files in Salesforce you have to understand the Object relationship. Here is an example to create File from Attachment using apex.

ContentDocument: This object record you don’t have to create. It gets created when you create ContentVersion which is the child of ContentDocument.

ContentVersion: This object stores document information similar like Attachment.

ContentDocumentLink: This object will share the files with Users, Records, Groups etc. You can create multiple records to attach the same files under multiple records.

Sample Code:

//Get attachment
Attachment attach = [SELECT Id, Name, Body, ContentType, ParentId From Attachment LIMIT 1];

//Insert ContentVersion
ContentVersion cVersion = new ContentVersion();
cVersion.ContentLocation = 'S'; //S-Document is in Salesforce. E-Document is outside of Salesforce. L-Document is on a Social Netork.
cVersion.PathOnClient = attach.Name;//File name with extention
cVersion.Origin = 'H';//C-Content Origin. H-Chatter Origin.
cVersion.OwnerId = attach.OwnerId;//Owner of the file
cVersion.Title = attach.Name;//Name of the file
cVersion.VersionData = attach.Body;//File content
Insert cVersion;

//After saved the Content Verison, get the ContentDocumentId
Id conDocument = [SELECT ContentDocumentId FROM ContentVersion WHERE Id =:cVersion.Id].ContentDocumentId;

//Insert ContentDocumentLink
ContentDocumentLink cDocLink = new ContentDocumentLink();
cDocLink.ContentDocumentId = conDocument;//Add ContentDocumentId
cDocLink.LinkedEntityId = attach.ParentId;//Add attachment parentId
cDocLink.ShareType = 'I';//V - Viewer permission. C - Collaborator permission. I - Inferred permission.
cDocLink.Visibility = 'InternalUsers';//AllUsers, InternalUsers, SharedUsers
Insert cDocLink;