Pagination Of Contacts With Clint Side Controller Sorting Functionality On Lightning Component

PAGINATION OF CONTACTS WITH CLINT SIDE SORTING FUNCTIONALITY ON LIGHTNING COMPONENT


What is clint side sorting :In clint side sorting we will implement sorting functionality in clint side JS controller without using server side controller(Apex Class). i.e we use server side controller only to get the records from the Object . 

The remaining functionality i.e pagination , custom buttons(First,Previous,Next,Last) and sorting implement at clint side.

PROS :

1. In sales force one of the governer limits is total number of SOQL queries are 100. Using server side pagination each time on button click(First ,Previous,Next ,Last ) we call Soql query then we will get the error if we exceed the limit.Using clint side pagination each time no need call soql query.

CONS : 

1. Using clint side sorting we can not sot relational fields like Account.Name field in contacts.
2.If the number of records are increased , loading of records on custom button become slow. 

Here Is The Logic

Component:

<aura:component controller="ContactSortApexController" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction">
    <aura:attribute name="pMasterWrapperlist" type="List"/>
    <aura:attribute name="pWrapperlist" type="List"/>
    <aura:attribute name="pageSize" type="Integer" default="10"/>
    <aura:attribute name="masterlistSize" type="Integer"/>
    <aura:attribute name="startPosn" type="Integer" default="0"/>
    <aura:attribute name="endPosn" type="Integer"/>
    <aura:attribute type="String" name="sortField" />
    <aura:attribute name="isAsc" type="boolean" default="true" description="boolean flag for pass sorting condition to apex class"/> 
    <aura:attribute name="sortAsc" type="boolean"  />
    <aura:attribute name="Name" type="boolean" default="true"/>
    <aura:attribute name="account" type="boolean" default="true"/>
    <aura:attribute name="phone" type="boolean" default="true"/>
    <aura:attribute name="email" type="boolean" default="true"/>
    <aura:attribute name="owner" type="boolean" default="true"/>
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    <!--<aura:handler event="c:PaginatorEvent" action="{!c.performNavigation}"/>-->
    <div class="slds">
        <div class="wk_static">
            <div class="slds-page-header" role="banner">
                <div class="slds-grid">
                    <div class="slds-col slds-has-flexi-truncate">
                        <div class="slds-media slds-media--center slds-no-space slds-grow">
                            <div class="slds-media__figure">
                                <lightning:icon iconName="standard:account" size="small" alternativeText="Indicates approval"/> 
                            </div>
                            <div class="slds-media__body">
                                <h1 class="slds-page-header__title slds-m-right--small slds-truncate slds-align-middle" title="Accounts">Contacts</h1>
                            </div>
                            <div class="slds-media__figure slds-media__figure--reverse slds-truncate">
                                <lightning:button variant="neutral" label="New" onclick="{! c.createRecord }" />
                            </div>
                        </div>                    
                    </div>                
                </div>
            </div>
        </div>  
    </div>
    <div>
        <div style="padding-bottom:30px;">
            <form class="slds-form--stacked">
                <div class="slds-col--padded slds-p-top--large">
                    <table class="slds-table slds-table--bordered slds-table--fixed-layout slds-table--resizable-cols slds-max-medium-table--stacked-horizontal" role="grid">
                        <thead >
                            <tr class="slds-line-height--reset " style="line-height: 2.25;" >
                                <th class="slds-text-title--caps" scope="col" onclick="{!c.sortByName}">Name
                                    <!-- <div class="slds-truncate" title="Account Name">Name-->
                                    <span>  <aura:if isTrue="{!v.Name}"><lightning:icon iconName="utility:arrowup"  size="xx-small" alternativeText="Indicates approval"/>
                                        <aura:set attribute="else">
                                            <lightning:icon iconName="utility:arrowdown"  size="xx-small" alternativeText="Indicates approval"/>
                                        </aura:set>
                                        </aura:if>
                                    </span>
                                </th>
                                <th class="slds-text-title--caps" scope="col" >
                                    <div class="slds-truncate" title="Account Name">Account Name
                                        
                                    </div>
                                </th>
                                <th class="slds-text-title--caps" scope="col" onclick="{!c.sortByPhone}">
                                    <div class="slds-truncate" title="Phone">Phone
                                        <span>  <aura:if isTrue="{!v.phone}"><lightning:icon iconName="utility:arrowup"  size="xx-small" alternativeText="Indicates approval"/>
                                            <aura:set attribute="else">
                                                <lightning:icon iconName="utility:arrowdown"  size="xx-small" alternativeText="Indicates approval"/>
                                            </aura:set>
                                            </aura:if>
                                        </span></div>
                                </th>
                                <th class="slds-text-title--caps" scope="col" onclick="{!c.sortByEmail}">
                                    <div class="slds-truncate" title="Email">Email
                                        <span>  <aura:if isTrue="{!v.email}"><lightning:icon iconName="utility:arrowup"  size="xx-small" alternativeText="Indicates approval"/>
                                            <aura:set attribute="else">
                                                <lightning:icon iconName="utility:arrowdown"  size="xx-small" alternativeText="Indicates approval"/>
                                            </aura:set>
                                            </aura:if>
                                        </span></div>
                                </th>
                                <th class="slds-text-title--caps" scope="col" >
                                    <div class="slds-truncate" title="Owner">Owner
                                    </div>
                                </th>
                            </tr>
                        </thead>
                        <tbody>
                            <aura:iteration items="{!v.pWrapperlist}" var="con">
                                <tr class="slds-hint-parent">  
                                    <th scope="row"  class="slds-cell-edit" data-label="Name">
                                        <!-- <td data-label="Name" >-->
                                        <div class="slds-truncate" title="Name">
                                            <a href="javascript:void(0);" onclick="{!c.doView}">
                                                <span class="slds-truncate" id="{!con.Id}">{!con.Name}</span>
                                            </a>
                                        </div>
                                    </th>
                                    <!-- <td data-label="Account Name" >-->
                                    <th scope="row"  class="slds-cell-edit" data-label="Account Name">
                                        <div class="slds-truncate" title="Account Name">
                                            <a href="javascript:void(0);" onclick="{!c.doView}">
                                                <span class="slds-truncate" id="{!con.Account.Id }">{!con.Account.Name}</span>
                                            </a>
                                        </div>
                                    </th>
                                    <th scope="row"  class="slds-cell-edit" data-label="Phone">
                                        <!--<td data-label="Phone" >-->
                                        <div class="slds-truncate" title="Phone">{!con.Phone}</div>
                                    </th>
                                    <th scope="row"  class="slds-cell-edit" data-label="Email">
                                        <!--<td data-label="Email" >-->
                                        <div class="slds-truncate" title="Email">{!con.Email}</div>
                                    </th>
                                    <th scope="row"  class="slds-cell-edit" data-label="Contact Owner">
                                        <!--<td data-label="Contact Owner" >-->
                                        <div class="slds-truncate" title="Contact Owner">{!con.Owner.Alias}</div>
                                    </th>
                                </tr>
                            </aura:iteration>                       
                        </tbody>
                    </table>
                </div>
            </form>
        </div>
        <div class="slds-docked-form-footer" >
            <div style="width:50%" class="hidePageSize">
                <ui:inputSelect aura:id="recordSize"  label="Display Record Per Page:" class="testDiv width30px" change="{!c.onSelectChange}">
                    <ui:inputSelectOption text="10" label="10" value="true"/>
                    <ui:inputSelectOption text="15" label="15"/>
                    <ui:inputSelectOption text="20" label="20"/>
                </ui:inputSelect>
            </div>
            <lightning:button variant="neutral" label="First" disabled="{!v.startPosn == 0}"
                              onclick="{!c.First}" />
            <lightning:button variant="neutral" label="Previous" disabled="{!v.startPosn == 0}"
                              onclick="{!c.previous}" />
            <lightning:button variant="brand" label="Next" disabled="{!v.endPosn >= v.pMasterWrapperlist.length-1}"
                              onclick="{!c.next}" />
            <lightning:button variant="brand" label="last" disabled="{!v.endPosn >= v.pMasterWrapperlist.length-1}"
                              onclick="{!c.Last}" />
        </div>
    </div>
</aura:component>

Clint side controller:


({
    
    doInit:function(component,event,helper){
        helper.getContacts(component);
    },
    next:function(component,event,helper){
        helper.next(component);
    },
    previous:function(component,event,helper){
        helper.previous(component);
    },
    sortByName: function(component, event, helper) {
        helper.sortBy(component,helper, "Name"); 
        var a=component.get("v.sortAsc");
        component.set("v.Name",a);
    },
    sortByPhone: function(component, event, helper) {
        helper.sortBy(component,helper, "Phone");
        var a=component.get("v.sortAsc");
        component.set("v.phone",a);
    },
    sortByEmail: function(component, event, helper) {
        helper.sortBy(component,helper, "Email");
         var a=component.get("v.sortAsc");
        component.set("v.email",a);
    },
    First:function(component,event,helper){
        helper.First(component);
    },
    Last:function(component,event,helper){
        helper.Last(component);
    },
    
    doView: function(component, event, helper) {
        var editRecordEvent = $A.get("e.force:navigateToSObject");
        editRecordEvent.setParams({
            "recordId": event.target.id
        });
        editRecordEvent.fire();
    },
    doEdit: function(component, event, helper) {
        // console.log(event.getSource().get("v.name") );
        var editRecordEvent = $A.get("e.force:editRecord");
        editRecordEvent.setParams({
            "recordId": event.getSource().get("v.name")
        });
        editRecordEvent.fire();
    },
    
    onSelectChange: function(component, event, helper) {
        component.set("v.pageSize",component.find("recordSize").get("v.value"));
        helper.paginate(component);
    },
     createRecord : function (component, event, helper) {
        var createRecordEvent = $A.get("e.force:createRecord");
        createRecordEvent.setParams({
            "entityApiName": "Contact",
            "recordTypeId": component.get('v.disAccRecTypeId')
        });
        createRecordEvent.fire();
    }
})

Helper :

({
    performNavigation : function(component,event) {
        component.set("v.pWrapperlist",  event.getParam("pWrapperlist"));
        component.set("v.endPosn", event.getParam("endPosn"));
        component.set("v.startPosn", event.getParam("startPosn"));
    },
    paginate : function(component) {
        var wlist = component.get("v.pMasterWrapperlist");
        component.set("v.pWrapperlist", wlist);
        if(wlist.length > component.get("v.pageSize")){
            var subWrapperlist = [];
            for(var i=0; i<component.get("v.pageSize"); i++){
                subWrapperlist.push(wlist[i]);
            }
            component.set("v.pWrapperlist", subWrapperlist);
        }
    },
    getContacts : function(component) {
        var action = component.get("c.getConlist");
        action.setParams({
        });
        action.setCallback(this, function(resp) {
            var state=resp.getState();
            if(state === "SUCCESS"){
                console.log(resp.getReturnValue());
                component.set("v.pMasterWrapperlist", resp.getReturnValue());
                component.set("v.masterlistSize", component.get("v.pMasterWrapperlist").length);
                component.set("v.startPosn",0);
                component.set("v.endPosn",component.get("v.pageSize")-1);
                this.paginate(component);
            }
        });
        $A.enqueueAction(action);
    },
    next : function(component) {
        var wlist = component.get("v.pMasterWrapperlist");
        var endPosn = component.get("v.endPosn");
        var startPosn = component.get("v.startPosn");
        var subWrapperlist = [];
        for(var i=0; i<component.get("v.pageSize"); i++){
            endPosn++;
            if(wlist.length >= endPosn){
                subWrapperlist.push(wlist[endPosn]);
            }
            startPosn++;
        }
        component.set("v.pWrapperlist",subWrapperlist);
        component.set("v.startPosn",startPosn);
        component.set("v.endPosn",endPosn);
    },
    previous : function(component) {
        var wlist = component.get("v.pMasterWrapperlist");
        var startPosn = component.get("v.startPosn");
        var endPosn = component.get("v.endPosn");
        var subWrapperlist = [];
        var pageSize = component.get("v.pageSize");
        startPosn -= pageSize;
        if(startPosn > -1){
            for(var i=0; i<pageSize; i++){
                if(startPosn > -1){
                    subWrapperlist.push(wlist[startPosn]);
                    startPosn++;
                    endPosn--;
                }
            }
            startPosn -= pageSize;
            component.set("v.pWrapperlist",subWrapperlist);
            component.set("v.startPosn",startPosn);
            component.set("v.endPosn",endPosn);
        }
    },
    First : function(component) {
        var wlist = component.get("v.pMasterWrapperlist");
        var startPosn = component.get("v.startPosn");
        var endPosn = component.get("v.endPosn");
        var subWrapperlist = [];
        var pageSize = component.get("v.pageSize");
        startPosn=0;
        if(startPosn > -1){
            for(var i=0; i<pageSize; i++){
                if(startPosn > -1){
                    subWrapperlist.push(wlist[startPosn]);
                    startPosn++;
                }
            }
            startPosn=0;
            endPosn=pageSize-1;
            component.set("v.pWrapperlist",subWrapperlist);
            component.set("v.startPosn",startPosn);
            component.set("v.endPosn",endPosn);
        }
    },
    Last : function(component) {
        var wlist = component.get("v.pMasterWrapperlist");
        var startPosn = component.get("v.startPosn");
        var endPosn = component.get("v.endPosn");
        var subWrapperlist = [];
        var pageSize = component.get("v.pageSize");
        var l=wlist.length;
        var po=l-(l%pageSize);
        if((l%pageSize)!=0){
            startPosn=po;
        }
        else{
            startPosn=po-pageSize;
        }
        endPosn=l-1;
        if(startPosn <=endPosn ){
            for(var i=startPosn; i<=endPosn; i++){
                
                subWrapperlist.push(wlist[i]);
            }
            component.set("v.pWrapperlist",subWrapperlist);
            component.set("v.startPosn",startPosn);
            component.set("v.endPosn",endPosn);
        }
    },
    
    sortBy: function(component,helper,field) {
        var sortAsc = component.get("v.sortAsc"),
            sortField = component.get("v.sortField"),
            records = component.get("v.pMasterWrapperlist");
        sortAsc = sortField != field || !sortAsc;
        records.sort(function(a,b){
            var t1 = a[field] == b[field],
                t2 = (!a[field] && b[field]) || (a[field] < b[field]);
            return t1? 0: (sortAsc?-1:1)*(t2?1:-1);
        });
        component.set("v.sortAsc", sortAsc);
        component.set("v.sortField", field);
        component.set("v.pMasterWrapperlist", records);
        var startPosn = component.get("v.startPosn");
        var endPosn = component.get("v.endPosn");
        var pageSize = component.get("v.pageSize");
        startPosn=0;
        endPosn=pageSize-1;
        component.set("v.startPosn", startPosn);
        component.set("v.endPosn", endPosn);
        helper.paginate(component);
    }
    
})

Server Side Controller :

public class ContactSortApexController {
    
    @AuraEnabled
    public static List<Contact> getConlist(){
        return [SELECT Name, Account.Name, Phone, Email, Owner.Alias, OwnerId  FROM Contact 
               ];
        
    }
    
}

Result:



Comments

Popular posts from this blog

Configur Docusign For Salesforce

How To Make DataTable Column Resizable

Lightning:recordForm - Lightning Data Service