Apex Class:
public class AccountController {
@AuraEnabled//Get Account Records
public static String getAccountList(Integer pageSize, Integer pageNumber, String sortingField, Boolean isSortAsc){
String jsonDT = '';
//Offset for SOQL
Integer offset = (pageNumber - 1) * pageSize;
//Total Records
Integer totalRecords = [SELECT COUNT() FROM Account];
Integer recordEnd = pageSize * pageNumber;
String sortBy = isSortAsc ? 'ASC' : 'DESC';
String query = 'SELECT Id, Name, AccountNumber, Industry, Phone FROM Account ORDER BY ';
query += sortingField + ' ' + sortBy;
query += ' LIMIT :pageSize OFFSET :offset';
AccountDTWrapper objDT = new AccountDTWrapper();
objDT.pageSize = pageSize;
objDT.pageNumber = pageNumber;
objDT.recordStart = offset + 1;
objDT.recordEnd = totalRecords >= recordEnd ? recordEnd : totalRecords;
objDT.totalRecords = totalRecords;
objDT.accounts = Database.query(query);
jsonDT = JSON.serialize(objDT);
return jsonDT;
}
public class AccountDTWrapper {
public Integer pageSize {get;set;}
public Integer pageNumber {get;set;}
public Integer totalRecords {get;set;}
public Integer recordStart {get;set;}
public Integer recordEnd {get;set;}
public List<Account> accounts {get;set;}
}
}
Lightning Component:
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes" access="global" controller="AccountController">
<!--Declare Attributes-->
<aura:attribute name="accounts" type="List"/>
<aura:attribute name="pageNumber" type="integer" default="1"/>
<aura:attribute name="pageSize" type="integer" default="10"/>
<aura:attribute name="totalPages" type="integer" default="0"/>
<aura:attribute name="totalRecords" type="integer" default="0"/>
<aura:attribute name="recordStart" type="integer" default="0"/>
<aura:attribute name="recordEnd" type="integer" default="0"/>
<aura:attribute name="isSortByName" type="Boolean" default="false"/>
<aura:attribute name="isSortByAccNo" type="Boolean" default="false"/>
<aura:attribute name="isSortByIndustry" type="Boolean" default="false"/>
<aura:attribute name="isSortByPhone" type="Boolean" default="false"/>
<aura:attribute name="isSortAsc" type="Boolean" default="true"/>
<aura:attribute name="selectedSortingField" type="String" default="Name"/>
<!--Declare Handlers-->
<aura:handler name="init" action="{!c.doInit}" value="{!this}"/>
<!--Component Start-->
<div class="slds-m-around_xx-large">
<lightning:card>
<aura:set attribute="title">
Accounts
</aura:set>
<aura:set attribute="footer">
<div class="slds-align_absolute-center">
<div class="slds-p-right_xx-small">
<lightning:button label="Prev"
onclick="{!c.handlePrev}"
disabled="{! v.pageNumber == 1}"
variant="brand"
iconName="utility:back"
name="prev"/>
</div>
<span class="slds-badge slds-badge_lightest">
{!v.recordStart}-{!v.recordEnd} of {!v.totalRecords} | Page {!v.pageNumber} of {!v.totalPages}
</span>
<div class="slds-p-left_xx-small">
<lightning:button label="Next"
disabled="{!v.pageNumber == v.totalPages}"
onclick="{!c.handleNext}"
variant="brand"
iconName="utility:forward"
iconPosition="right"
name="next"/>
</div>
</div>
</aura:set>
<table class="slds-table slds-table_cell-buffer slds-table_bordered">
<thead>
<tr class="slds-line-height_reset slds-text-title_caps">
<th style="width:30%" data-record="Name" class="slds-is-resizable" scope="col" onclick="{!c.handleSorting}">
<a href="javascript:void(0);" class="slds-th__action slds-text-link--reset">
<span class="slds-assistive-text">Sort</span>
<span class="slds-truncate" title="Name">Name</span>
<aura:if isTrue="{!v.isSortByName}">
<aura:if isTrue="{!v.isSortAsc}">
▲
<aura:set attribute="else">
▼
</aura:set>
</aura:if>
</aura:if>
</a>
</th>
<th style="width:20%" data-record="AccountNumber" class="slds-is-resizable" scope="col" onclick="{!c.handleSorting}">
<a href="javascript:void(0);" class="slds-th__action slds-text-link--reset">
<span class="slds-assistive-text">Sort</span>
<span class="slds-truncate" title="Account Number">Account Number</span>
<aura:if isTrue="{!v.isSortByAccNo}">
<aura:if isTrue="{!v.isSortAsc}">
▲
<aura:set attribute="else">
▼
</aura:set>
</aura:if>
</aura:if>
</a>
</th>
<th style="width:20%" data-record="Industry" class="slds-is-resizable" scope="col" onclick="{!c.handleSorting}">
<a href="javascript:void(0);" class="slds-th__action slds-text-link--reset">
<span class="slds-assistive-text">Sort</span>
<span class="slds-truncate" title="Industry">Industry</span>
<aura:if isTrue="{!v.isSortByIndustry}">
<aura:if isTrue="{!v.isSortAsc}">
▲
<aura:set attribute="else">
▼
</aura:set>
</aura:if>
</aura:if>
</a>
</th>
<th style="width:20%" data-record="Phone" class="slds-is-resizable" scope="col" onclick="{!c.handleSorting}">
<a href="javascript:void(0);" class="slds-th__action slds-text-link--reset">
<span class="slds-assistive-text">Sort</span>
<span class="slds-truncate" title="Phone">Phone</span>
<aura:if isTrue="{!v.isSortByPhone}">
<aura:if isTrue="{!v.isSortAsc}">
▲
<aura:set attribute="else">
▼
</aura:set>
</aura:if>
</aura:if>
</a>
</th>
<th scope="col" style="width:10%">
</th>
</tr>
</thead>
<aura:if isTrue="{!not(empty(v.accounts))}">
<tbody>
<aura:iteration items="{!v.accounts}" var="acc">
<tr class="slds-hint-parent">
<th data-label="Name" scope="row">
<div class="slds-truncate" title="{!acc.Name}">
{!acc.Name}
</div>
</th>
<td data-label="Account Number">
<div class="slds-truncate" title="{!acc.AccountNumber}">{!acc.AccountNumber}</div>
</td>
<td data-label="Industry">
<div class="slds-truncate" title="{!acc.Industry}">{!acc.Industry}</div>
</td>
<td data-label="Phone">
<div class="slds-truncate" title="{!acc.Phone}">{!acc.Phone}</div>
</td>
<td>
<div class="slds-align_absolute-center">
<lightning:buttonMenu alternativeText="Show menu" menuAlignment="auto" onselect="{!c.handleRowAction}" value="{!acc.Id}">
<lightning:menuItem value="edit" label="Edit" iconName="utility:edit" title="Edit" />
<lightning:menuItem value="view" label="View" iconName="utility:description" title="View" />
</lightning:buttonMenu>
</div>
</td>
</tr>
</aura:iteration>
</tbody>
</aura:if>
</table>
<aura:if isTrue="{!empty(v.accounts)}">
<div class="slds-align_absolute-center">
No records found
</div>
</aura:if>
</lightning:card>
</div>
<!--Component End-->
</aura:component>
Lightning JS Controller:
({
doInit : function(component, event, helper) {
helper.getAccounts(component, helper);
},
handleNext : function(component, event, helper) {
var pageNumber = component.get("v.pageNumber");
component.set("v.pageNumber", pageNumber+1);
helper.getAccounts(component, helper);
},
handlePrev : function(component, event, helper) {
var pageNumber = component.get("v.pageNumber");
component.set("v.pageNumber", pageNumber-1);
helper.getAccounts(component, helper);
},
handleRowAction: function (component, event, helper) {
var selectedAction = event.detail.menuItem.get("v.value");
var selectedAccountId = event.getSource().get("v.value");
switch (selectedAction) {
case 'edit':
helper.editRecord(component, event, selectedAccountId);
break;
case 'view':
helper.viewRecord(component, event, selectedAccountId);
break;
}
},
handleSorting: function (component, event, helper) {
var selectedItem = event.currentTarget;
var selectedField = selectedItem.dataset.record;
component.set("v.isSortByName", false);
component.set("v.isSortByAccNo", false);
component.set("v.isSortByIndustry", false);
component.set("v.isSortByPhone", false);
component.set("v.selectedSortingField", selectedField);
if(selectedField == 'Name'){
component.set("v.isSortByName", true);
}else if(selectedField == 'AccountNumber'){
component.set("v.isSortByAccNo", true);
}else if(selectedField == 'Industry'){
component.set("v.isSortByIndustry", true);
}else if(selectedField == 'Phone'){
component.set("v.isSortByPhone", true);
}
helper.sortColumnData(component, event);
},
})
Lightning JS Helper:
({
getAccounts: function(component, event) {
var action = component.get("c.getAccountList");
action.setParams({
"pageSize": component.get("v.pageSize"),
"pageNumber": component.get("v.pageNumber"),
"sortingField": component.get("v.selectedSortingField"),
"isSortAsc": component.get("v.isSortAsc")
});
action.setCallback(this, function(response) {
var state = response.getState();
if (component.isValid() && state === "SUCCESS"){
var result = response.getReturnValue();
if(result){
var resultData = JSON.parse(result);
var pageSize = component.get("v.pageSize");
component.set("v.accounts", resultData.accounts);
component.set("v.pageNumber", resultData.pageNumber);
component.set("v.totalRecords", resultData.totalRecords);
component.set("v.recordStart", resultData.recordStart);
component.set("v.recordEnd", resultData.recordEnd);
component.set("v.totalPages", Math.ceil(resultData.totalRecords / pageSize));
}
}
});
$A.enqueueAction(action);
},
viewRecord : function(component, event, selectedAccountId) {
var navEvt = $A.get("e.force:navigateToSObject");
navEvt.setParams({
"recordId": selectedAccountId,
"slideDevName": "detail"
});
navEvt.fire();
},
editRecord : function(component, event, selectedAccountId) {
var editRecordEvent = $A.get("e.force:editRecord");
editRecordEvent.setParams({
"recordId": selectedAccountId
});
editRecordEvent.fire();
},
sortColumnData: function(component, event) {
var accountList = component.get("v.accounts");
var isSortAsc = component.get("v.isSortAsc");
var sortingField = component.get("v.selectedSortingField");
accountList.sort(function(a, b){
var s1 = a[sortingField] == b[sortingField];
var s2 = (!a[sortingField] && b[sortingField]) || (a[sortingField] < b[sortingField]);
return s1? 0: (isSortAsc?-1:1)*(s2?1:-1);
});
component.set("v.accounts", accountList);
component.set("v.isSortAsc", !isSortAsc);
},
})