Monday, March 22, 2021

 Pagination & Lazy Loading in Lightning Component

APEX CLASS : ------------------------------------------------------------------------------------------------------------
public class ArchivedCallsClass_New {
    
    @AuraEnabled
    public static list<ADB_Archivedivybase_Visit__x> getCallsRecords(){
        list<ADB_Archivedivybase_Visit__x> callsList = new  list<ADB_Archivedivybase_Visit__x>();
        try{
            user u = [select id,ivybat__Market_ISO__c,UserRoleID from user where id =: UserInfo.getUserId()];
            callsList = [Select Id,Name__c,OwnerId__c,ivybase_Store_c__c,ivybat_Is_Planned_c__c,ivybase_Seller_c__c,ivybase_Status_c__c,
                         ivybat_Campaign_c__c,ivybase_Lat_Position_Latitude_s__c,ivybat_Plan_c__c,ivybase_Type_c__c,ivybat_Call_Type_c__c,
                         ivybase_Visit_Date_c__c,ivybase_Original_Date_c__c,Default_Delivery_Date_c__c,
                         ivybase_Duration_c__c,ivybase_Non_Productive_Reason_c__c,ivybase_Time_In_c__c,ivybase_Resource_c__c,ivybat_Market_ISO_c__c,
                         ivybase_Time_Out_c__c,CreatedById__c,LastModifiedById__c From ADB_Archivedivybase_Visit__x 
                         where ivybat_Market_ISO_c__c =: u.ivybat__Market_ISO__c limit 50000];
            
        }
        catch(Exception e){
            system.debug('ERROR'+e.getMessage()); 
        }
        return callsList;
    }
   
}
LIGTNING COMPENENTS : ------------------------------------------------------------------------------------------------------------
<aura:component controller="ArchivedCallsClass_New " implements="force:appHostable,flexipage:availableForAllPageTypes,force:lightningQuickAction,force:hasRecordId">
<aura:attribute name="allData" type="List" /> <aura:attribute name="filteredData" type="List" /> <aura:attribute name="tableData" type="List" /> <aura:attribute name="columns" type="Object[]" /> <aura:attribute name="pageSize" type="Integer" default="15" /> <aura:attribute name="pageSizeOptions" type="Integer[]" default="10,15,20,25,50,100" /> <aura:attribute name="currentPageNumber" type="Integer" default="1" /> <aura:attribute name="totalPages" type="Integer" default="1" /> <aura:attribute name="searchPhrase" type="String" /> <aura:attribute name="isLoading" type="Boolean" default="false" /> <aura:handler name="init" value="{! this }" action="{! c.doInit }" /> <aura:if isTrue="{! v.isLoading }"> <lightning:spinner alternativeText="Loading" /> </aura:if> <lightning:card> <div class="slds-p-around_small slds-grid slds-grid_align-spread slds-grid_vertical-align-start"> <div> <lightning:select label="Number of records on page:" value="{! v.pageSize }" onchange="{! c.onPageSizeChange }"> <aura:iteration items="{! v.pageSizeOptions }" var="opt"> <option text="{! opt }"></option> </aura:iteration> </lightning:select> </div> <div> <lightning:button label="First" iconName="utility:left" iconPosition="left" onclick="{! c.onFirst }" disabled="{! v.currentPageNumber == 1 }" /> <lightning:button label="Previous" iconName="utility:chevronleft" iconPosition="left" onclick="{! c.onPrev }" disabled="{! v.currentPageNumber == 1 }" /> <span class="slds-var-p-horizontal_x-small"> Page {! (v.currentPageNumber) } of {! (v.totalPages) } </span> <span class="slds-var-p-horizontal_x-small"> Number of records: {! (v.filteredData.length) } </span> <lightning:button label="Next" iconName="utility:chevronright" iconPosition="right" onclick="{! c.onNext }" disabled="{! v.currentPageNumber == v.totalPages }" /> <lightning:button label="Last" iconName="utility:right" iconPosition="right" onclick="{! c.onLast }" disabled="{! v.currentPageNumber == v.totalPages }" /> </div> <div class="inline-container"> <span class="padding-right"> <lightning:input variant="label-hidden" placeholder="Search Phrase" type="search" value="{! v.searchPhrase }" onchange="{! c.onChangeSearchPhrase }" /> </span> <span> <lightning:button label="Search" variant="neutral" onclick="{! c.handleSearch }" /> </span> </div> </div> <lightning:datatable aura:id="table" columns="{! v.columns }" data="{! v.tableData }" hideCheckboxColumn="true" keyField="Id" /> </lightning:card> </aura:component> JS Controller : ------------------------------------------------------------------------------------------------------------ ({ doInit: function (component, event, helper) { helper.setupDataTable(component); helper.getData(component); }, onNext: function(component, event, helper) { let pageNumber = component.get("v.currentPageNumber"); component.set("v.currentPageNumber", pageNumber + 1); helper.setPageDataAsPerPagination(component); }, onPrev: function(component, event, helper) { let pageNumber = component.get("v.currentPageNumber"); component.set("v.currentPageNumber", pageNumber - 1); helper.setPageDataAsPerPagination(component); }, onFirst: function(component, event, helper) { component.set("v.currentPageNumber", 1); helper.setPageDataAsPerPagination(component); }, onLast: function(component, event, helper) { component.set("v.currentPageNumber", component.get("v.totalPages")); helper.setPageDataAsPerPagination(component); }, onPageSizeChange: function(component, event, helper) { helper.preparePagination(component, component.get('v.filteredData')); }, onChangeSearchPhrase : function (component, event, helper) { if ($A.util.isEmpty(component.get("v.searchPhrase"))) { let allData = component.get("v.allData"); component.set("v.filteredData", allData); helper.preparePagination(component, allData); } }, handleSearch : function (component, event, helper) { helper.searchRecordsBySearchPhrase(component); }, }) JS Helper : ------------------------------------------------------------------------------------------------------------ ({ setupDataTable: function (component) { component.set('v.columns', [ {label: 'Visit Code', fieldName: 'LinkName', type: 'url',typeAttributes: {label: { fieldName: 'Name__c' }, target: '_blank'}}, {label : 'Market ISO',fieldName : 'ivybat_Market_ISO_c__c',type : 'text',}, {label : 'Store',fieldName : 'ivybase_Store_c__c',type : 'text',} ]); }, getData: function (component) { component.set("v.isLoading", true); var action = component.get("c.getCallsRecords"); action.setCallback(this,function(response){ component.set("v.isLoading", false); var state = response.getState(); if(state == "SUCCESS"){ var callsWrapper = response.getReturnValue(); var callsList1 = callsWrapper; callsList1.forEach(function(record){ record.LinkName = '/'+record.Id; }); component.set('v.allData', callsList1); component.set('v.filteredData', callsList1); this.preparePagination(component, callsList1); }else if (state === "ERROR") { return (response.getError()); } }); $A.enqueueAction(action); }, preparePagination: function (component, imagesRecords) { let countTotalPage = Math.ceil(imagesRecords.length/component.get("v.pageSize")); let totalPage = countTotalPage > 0 ? countTotalPage : 1; component.set("v.totalPages", totalPage); component.set("v.currentPageNumber", 1); this.setPageDataAsPerPagination(component); }, setPageDataAsPerPagination: function(component) { let data = []; let pageNumber = component.get("v.currentPageNumber"); let pageSize = component.get("v.pageSize"); let filteredData = component.get('v.filteredData'); let x = (pageNumber - 1) * pageSize; for (; x < (pageNumber) * pageSize; x++){ if (filteredData[x]) { data.push(filteredData[x]); } } component.set("v.tableData", data); }, searchRecordsBySearchPhrase : function (component) { let searchPhrase = component.get("v.searchPhrase"); if (!$A.util.isEmpty(searchPhrase)) { let allData = component.get("v.allData"); let filteredData = allData.filter(record => record.Name__c.includes(searchPhrase)); component.set("v.filteredData", filteredData); this.preparePagination(component, filteredData); } }, }) STYLE : ------------------------------------------------------------------------------------------------------------ .THIS .inline-container { display: inline-flex; } .THIS .padding-right { padding-right: 20px; } JS Controller : ------------------------------------------------------------------------------------------------------------