Blog

How can we get data through scrolling of the page?

In this blog you will learn how to fetch the records via SOQL Query by scrolling the scroll bar using Lightning Datatable in Lightning component.

Initial load of page :

Initially when the end user opens, the first page will load which contains the first 10 records. Then by incrementing +1 to the current page, it will query data related to the  next page number, we are querying the data using offset (starting position of the record)  and limit. So that response will be binded in the UI.

we get data through scrolling of the page

How was this achieved?

Here we can implement this scrolling using the Lightning data table by enableInfiniteLoading and onloadmore attribute.

Onloadmore – event handler retrieves more data when you scroll to the bottom of the table until it reaches the last data.

Lightning Component:

LightningDataTable.html

<div class="slds-grid slds-wrap" style="background-color: white;">
   <div class="slds-size--1-of-1">
      <div class="slds-page-header">
         <div class="slds-page-header__row">
            <div class="slds-page-header__col-title">
               <div class="slds-media">
                  <div class="slds-media__figure">
                     <span class="slds-icon_container slds-icon-standard-opportunity" title="Service History">
                        <lightning:icon iconName="custom:custom19" title="Service History" />
                        <span class="slds-assistive-text"> History Configuration</span>
                     </span>
                  </div>
                  <div class="slds-media__body">
                     <div class="slds-page-header__name">
                        <div class="slds-page-header__name-title">
                           <h1>
                              <span class="slds-page-header__title slds-truncate" title="Config History"> History Details</span>
                           </h1>
                        </div>
                        <p class="custom-style"> {!v.initialRecCount}/{!v.totalRecords} items </p>
                     </div>
                  </div>
               </div>
               <div style="height:450px">
                  <lightning:datatable aura:id="accountsTableID"
                     keyField="Id"
                     hideCheckboxColumn="true"
                     columns="{!v.accountHistoryColumns}"
                     data="{!v.accountHistoryData}"
                     enableInfiniteLoading="true"
                     onloadmore="{!c.viewAll}"/>
               </div>
            </div>
         </div>
      </div>
   </div>
</div>

LightningDataTable.js

({
  doInit: function (component, event, helper) {
    helper.getAccountList(component, event, helper);
  },
  viewAll: function (component, event, helper) {
    if (
      !(component.get("v.initialRecCount") >= component.get("v.totalRecords"))
    ) {
      console.log(
        "latestcurrentCountcontroller" + component.get("v.initialRecCount")
      );
      var pageNumber = component.get("v.PageNumber");
      console.log("pageNumbercontroller" + pageNumber);
      event.getSource().set("v.isLoading", true);
      helper.getRecPageList(component, event, pageNumber + 1);
    } else {
      event.getSource().set("v.isLoading", false);
      var toastEvent = $A.get("e.force:showToast");
      toastEvent.setParams({
        type: "Success",
        title: "Success",
        message: "All the account data loaded",
        mode: "dismissible",
      });
      toastEvent.fire();
    }
  },
});

LightningDataTableHelper.js

({
  getAccountList: function (component, event, helper) {
    var action = component.get("c.getAcclist");
    action.setParams({
      firstData: component.get("v.firstData"),
    });
    action.setCallback(this, function (result) {
      var state = result.getState();
      var toastEvent = $A.get("e.force:showToast");
      if (state === "SUCCESS") {
        var responseData = result.getReturnValue();
        console.log("responseData1" + JSON.stringify(responseData));
        if (
          responseData &&
          responseData.accountList &&
          responseData.accountList.length > 0
        ) {
          component.set("v.accountHistoryColumns", this.getColumnDefinitions());
          component.set("v.totalRecords", responseData.totalRecords);
          var accountsDataList = responseData.accountList;
          component.set("v.accountHistoryData", accountsDataList);
        }
      }
    });
    $A.enqueueAction(action);
  },

  getColumnDefinitions: function () {
    var columns = [
      { label: "Name", fieldName: "Name", type: "Name" },
      { label: "Active", fieldName: "Active__c", type: "text" },
      { label: "AccountNumber", fieldName: "AccountNumber", type: "text" },
      { label: "Description", fieldName: "Description", type: "text" },
    ];
    return columns;
  },

  getRecPageList: function (component, event, pageNumber) {
    var action = component.get("c.getAccReclist");
    var totalRows = component.get("v.totalRecords");

    action.setParams({
      PageNumber: pageNumber,
    });
    action.setCallback(this, function (result) {
      var state = result.getState();
      if (state === "SUCCESS") {
        var responseData = result.getReturnValue();
        var latestData = component.get("v.accountHistoryData");
        var mainListData = latestData.concat(responseData);
        console.log("responseData" + JSON.stringify(responseData));
        component.set("v.accountHistoryData", mainListData);
        component.set("v.PageNumber", pageNumber);
        var currentCount = component.get("v.initialRecCount");
        console.log("newcurrentCount" + currentCount);
        currentCount += component.get("v.firstData");
        console.log("latestcurrentCount" + currentCount);
        component.set("v.initialRecCount", currentCount);
        var totalRows = component.get("v.totalRecords");
        event.getSource().set("v.isLoading", false);
      }
    });
    $A.enqueueAction(action);
  },
})

Accountcontroller.apxc:

@AuraEnabled public static AccountDataTableWrapper getAcclist(Integer firstData){
      
    AccountDataTableWrapper AccDataWrapper =  new AccountDataTableWrapper();  
    try{
    AccDataWrapper.totalRecords = [SELECT COUNT() FROM Account];
    
    AccDataWrapper.accountList = [SELECT  id,name,active__c,AccountNumber,Description  FROM Account ORDER BY Name ASC LIMIT :firstData OFFSET 0];
    system.debug('accountList'+AccDataWrapper.accountList);
    }
   catch(Exception e){
      throw new AuraHandledException('Error in fetching account Creation');
       
    }
    return AccDataWrapper;
}


@AuraEnabled public static List<Account> getAccReclist(Integer PageNumber){
    Integer rowLimit= 10;
    Integer rowOffset = (pageNumber - 1) * rowLimit;
    
    system.debug('rowOffset'+rowOffset);
    return [SELECT  id,name,active__c,AccountNumber,Description  FROM Account ORDER BY Name ASC LIMIT :rowLimit OFFSET :rowOffset];
}

While this example uses a fixed number of rowLimit 10, to fetch the records on scrolling. For each scrolling until it reaches the last page number the data will be fetched, If the condition matches where the record count is greater than total records, the scrollable will end up there.

When will this scrolling be used?

We can also achieve this through the lightning button without using scrolling, but if the scenario is if the user wants to view all the data when it is having huge records, then we can implement using scrollable either by making an API call or by querying each page to load a set of records.