Delete Multiple Records Using Pagination in Lightning Component
Hello guys, today in this post we are going to learn about how to delete multiple records using pagination using Salesforce Lightning Component.
But before we get started, first we need to make a new button lets say View Contacts on Account standard object in Salesforce.
View Contacts button is made to show all the contact records related to account object.
Let's highlight those we are going to study about:
Don't forget to check out: Top Salesforce Lightning Components to Improve Functionality
How to write JavaScript Pagination?
Pagination is done because you might have 1000 records which is awkward to show on one page so what did I do by using pagination
I’m just showing, for example, five records per page, you can change it according to your need.
How to use Checkbox functionality?
I think it’s clear now because we are going to delete multiple records so we need something and that’s the Checkbox. Well it is not surprising but I am going to show you how can retain checkbox while changing the page because it gets unticked when you use checkbox but in this case, it won’t.
How to show the total number of records in that object?
I’m going to show you the total number of records (in my case I have used recordId which fetches records, for example, contact records particular to that Account in Account standard object.
How to select all of the records or none?
There is this thing which selects as per your need, giving selecting all records functionality is given because you might have over 1k records than you do not want to select all manually. So here it helps in this case.
Well, the theoretical part is over so let’s come to our programming part. I’m going to explain it to you through a code. You can understand easily as most of the lines are commented for your real understanding.
Apex Controller : ViewContacts_on_Account
/* API : 48 Author : Deepak Rajput Date : 24/04/2020 */ public class ViewContacts_on_Account { @AuraEnabled public static List<contactListWrapper> fetchContactWrapper(Id recordId ){ List<contactListWrapper> lstcontactListWrapper = new List<contactListWrapper>(); // query contact records related to account and create 'contactListWrapper' class instance for each record. for(Contact con : [Select id,FirstName,LastName,Phone from Contact where AccountId =:recordId Limit 100]){ // by default checkbox should be false lstcontactListWrapper.add(new contactListWrapper(false,con)); } // return the 'lstcontactListWrapper' list return lstcontactListWrapper; } @AuraEnabled public static void DelcontactList(list<Contact> lstRecordId) { list<id> ids=new list<id>(); for(Contact c : lstRecordId){ ids.add(c.id); } List<contact> contactList = [Select id,FirstName,LastName,Phone from Contact where Id =:ids]; delete contactList; } /* wrapper class */ public class contactListWrapper { @AuraEnabled public boolean isChecked {get;set;} @AuraEnabled public contact objContact{get;set;} public contactListWrapper(boolean isChecked, contact objContact){ this.isChecked = isChecked; this.objContact = objContact; } } }
Lightning Component : ViewContacts_on_Account.cmp
<!-- API : 48 Author : Deepak Rajput Date : 24/04/2020 --> <aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global" controller="ViewContacts_on_Account"> <!-- call doInit method on component load --> <aura:handler name="init" value="{!this}" action="{!c.doInit}"/> <!-- aura attributes to store data/values --> <aura:attribute name="recordId" type="Id" /> <aura:attribute name="listOfAllContacts" type="list"/> <aura:attribute name="PaginationList" type="list"/> <aura:attribute name="selectedCount" type="integer" default="0" description="selected Records Count"/> <aura:attribute name="startPage" type="Integer" /> <aura:attribute name="endPage" type="Integer"/> <aura:attribute name="totalRecordsCount" type="Integer"/> <aura:attribute name="pageSize" type="Integer" default="5" description="number of records to be display on per page"/> <aura:attribute name="currentPage" type="integer" default="1"/> <aura:attribute name="totalPagesCount" type="integer"/> <aura:attribute name="bNoRecordsFound" type="boolean"/> <aura:if isTrue="{!v.bNoRecordsFound}"> <!--display error message if there is no records available --> <div class="slds-notify slds-notify_alert slds-theme_alert-texture slds-theme_info" role="alert"> <span class="slds-assistive-text">error</span> <h2>No record found.</h2> </div> <!-- display total record and selected record count --> <p class="slds-m-around_small"> <span class="slds-badge slds-badge_lightest" style="display:inline-block"> Total Records : {!v.selectedCount > 0 ? v.selectedCount + '/' : ''} {!v.totalRecordsCount} </span> </p> <!-- data table start--> <table class="slds-table slds-table_bordered slds-table_cell-buffer"> <thead> <tr class="slds-text-title_caps"> <!--header checkbox for select all--> <th style="width:3.25rem;" class="slds-text-align_right"> <div class="slds-form-element"> <div class="slds-form-element__control"> <label class="slds-checkbox"> <ui:inputCheckbox disabled="{!v.totalRecordsCount == 0}" aura:id="selectAllId" change="{!c.selectAllCheckbox}"/> <span class="slds-checkbox_faux"></span> <span class="slds-form-element__label"></span> </label> </div> </div> </th> <th scope="col"> <div class="slds-truncate" title="FirstName">FirstName</div> </th> <th scope="col"> <div class="slds-truncate" title="LastName">LastName</div> </th> <th scope="col"> <div class="slds-truncate" title="Phone">Phone</div> </th> </tr> </thead> <tbody> <aura:iteration items="{!v.PaginationList}" var="obj"> <tr> <th scope="row" class="slds-text-align_right" style="width:3.25rem;"> <div class="slds-form-element"> <div class="slds-form-element__control"> <label class="slds-checkbox"> <ui:inputCheckbox text="{!obj.objContact.Id}" value="{!obj.isChecked}" change="{!c.checkboxSelect}" aura:id="SelectAllIds"/> <span class="slds-checkbox_faux"></span> <span class="slds-form-element__label text"></span> </label> </div> </div> </th> <th scope="row"> <div class="slds-truncate" title="{!obj.objContact.FirstName}"> {!obj.objContact.FirstName} </div> </th> <th scope="row"> <div class="slds-truncate" title="{!obj.objContact.LastName}"> {!obj.objContact.LastName} </div> </th> <th scope="row"> <div class="slds-truncate" title="{!obj.objContact.Phone}"> <lightning:formattedPhone value="{!obj.objContact.Phone}"/> </div> </th> </tr> </aura:iteration> </tbody> </table> <!-- DataTable End --> <br/> <!-- Pagination Buttons Start --> <div class="slds-align_absolute-center"> <lightning:button label="Previous" disabled="{!v.startPage == 0}" onclick="{!c.navigation}" variant="brand" iconName="utility:back" name="previous"/> <span class="slds-badge slds-badge_lightest" style="margin-right: 10px;margin-left: 10px;"> Page {!v.currentPage} out of {!v.totalPagesCount} </span> <lightning:button label="Next" disabled="{!(v.endPage + 1) >= v.totalRecordsCount}" onclick="{!c.navigation}" variant="brand" iconName="utility:forward" iconPosition="right" name="next"/> </div> <button class="slds-button slds-button--brand" onclick="{!c.deleteSelected}">Delete Contact</button> <!-- Pagination Buttons End --> </aura:if> </aura:component>
JavaScript Controller : ViewContacts_on_AccountController.js
({ doInit: function(component, event, helper) { helper.doInitHelper(component, event); }, /* javaScript function for pagination */ navigation: function(component, event, helper) { var sObjectList = component.get("v.listOfAllContacts"); var end = component.get("v.endPage"); var start = component.get("v.startPage"); var pageSize = component.get("v.pageSize"); var whichBtn = event.getSource().get("v.name"); // check if whichBtn value is 'next' then call 'next' helper method if (whichBtn == 'next') { component.set("v.currentPage", component.get("v.currentPage") + 1); helper.next(component, event, sObjectList, end, start, pageSize); } // check if whichBtn value is 'previous' then call 'previous' helper method else if (whichBtn == 'previous') { component.set("v.currentPage", component.get("v.currentPage") - 1); helper.previous(component, event, sObjectList, end, start, pageSize); } }, selectAllCheckbox: function(component, event, helper) { var selectedHeaderCheck = event.getSource().get("v.value"); var updatedAllRecords = []; var updatedPaginationList = []; var listOfAllContacts = component.get("v.listOfAllContacts"); var PaginationList = component.get("v.PaginationList"); // play a for loop on all records list for (var i = 0; i < listOfAllContacts.length; i++) { // check if header checkbox is 'true' then update all checkbox with true and update selected records count // else update all records with false and set selectedCount with 0 if (selectedHeaderCheck == true) { listOfAllContacts[i].isChecked = true; component.set("v.selectedCount", listOfAllContacts.length); } else { listOfAllContacts[i].isChecked = false; component.set("v.selectedCount", 0); } updatedAllRecords.push(listOfAllContacts[i]); } // update the checkbox for 'PaginationList' based on header checbox for (var i = 0; i < PaginationList.length; i++) { if (selectedHeaderCheck == true) { PaginationList[i].isChecked = true; } else { PaginationList[i].isChecked = false; } updatedPaginationList.push(PaginationList[i]); } component.set("v.listOfAllContacts", updatedAllRecords); component.set("v.PaginationList", updatedPaginationList); }, checkboxSelect: function(component, event, helper) { // on each checkbox selection update the selected record count var selectedRec = event.getSource().get("v.value"); var getSelectedNumber = component.get("v.selectedCount"); if (selectedRec == true) { getSelectedNumber++; } else { getSelectedNumber--; component.find("selectAllId").set("v.value", false); } component.set("v.selectedCount", getSelectedNumber); // if all checkboxes are checked then set header checkbox with true if (getSelectedNumber == component.get("v.totalRecordsCount")) { component.find("selectAllId").set("v.value", true); } }, getSelectedRecords: function(component, event, helper) { var allRecords = component.get("v.listOfAllContacts"); var selectedRecords = []; for (var i = 0; i < allRecords.length; i++) { if (allRecords[i].isChecked) { selectedRecords.push(allRecords[i].objContact); } } alert(JSON.stringify(selectedRecords)); }, //For Delete selected records deleteSelected: function(component, event, helper) { var allRecords = component.get("v.listOfAllContacts"); var selectedRecords = []; for (var i = 0; i < allRecords.length; i++) { if (allRecords[i].isChecked) { selectedRecords.push(allRecords[i].objContact); } } // call the helper function and pass all selected record id's. helper.deleteSelectedHelper(component, event, selectedRecords); console.log("selectedRecords"); }, })
Check out another amazing blog by Deepak here: Salesforce Ant Migration Tool - The Complete Guide
JavaScript Helper : ViewContacts_on_AccountHelper.js
({ /* doInitHelper funcation to fetch all records, and set attributes value on component load */ doInitHelper : function(component,event){ var action = component.get("c.fetchContactWrapper"); action.setParams ({ recordId: component.get("v.recordId") }); action.setCallback(this, function(response) { var state = response.getState(); if (state === "SUCCESS"){ var oRes = response.getReturnValue(); if(oRes.length > 0){ component.set('v.listOfAllContacts', oRes); var pageSize = component.get("v.pageSize"); var totalRecordsList = oRes; var totalLength = totalRecordsList.length ; component.set("v.totalRecordsCount", totalLength); component.set("v.startPage",0); component.set("v.endPage",pageSize-1); // component.set("") var PaginationLst = []; for(var i=0; i < pageSize; i++){ if(component.get("v.listOfAllContacts").length > i){ PaginationLst.push(oRes[i]); } } component.set('v.PaginationList', PaginationLst); component.set("v.selectedCount" , 0); //use Math.ceil() to Round a number upward to its nearest integer component.set("v.totalPagesCount", Math.ceil(totalLength / pageSize)); component.set("v.currentPage", 1); //currentPage = ceil(($startIndex - 1) / $itemsPerPage) + 1; // ((startIndex-1)/itemsPerPage) + 1, }else{ // if there is no records then display message component.set("v.bNoRecordsFound" , true); } } else{ alert('Error...'); } }); $A.enqueueAction(action); }, // navigate to next pagination record set next : function(component,event,sObjectList,end,start,pageSize){ var Paginationlist = []; var counter = 0; for(var i = end + 1; i < end + pageSize + 1; i++){ if(sObjectList.length > i){ if(component.find("selectAllId").get("v.value")){ Paginationlist.push(sObjectList[i]); }else{ 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); }, // navigate to previous pagination record set previous : function(component,event,sObjectList,end,start,pageSize){ var Paginationlist = []; var counter = 0; for(var i= start-pageSize; i < start ; i++){ if(i > -1){ if(component.find("selectAllId").get("v.value")){ Paginationlist.push(sObjectList[i]); }else{ 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); }, deleteSelectedHelper: function(component, event, selectedRecords) { //call apex class method var action = component.get('c.DelcontactList'); // pass the all selected record's Id's to apex method action.setParams({ "lstRecordId": selectedRecords }); action.setCallback(this, function(response) { //store state of response var state = response.getState(); if (state === "SUCCESS") { console.log(state); $A.get('e.force:refreshView').fire(); if (response.getReturnValue() != '') { // if getting any error while delete the records , then display a alert msg/ // alert('The following error has occurred. while Delete record-->' + response.getReturnValue()); } else { console.log('check it--> delete successful'); } // call the onLoad function for refresh the List view this.doInitHelper(component, event); } }); $A.enqueueAction(action); }, })
Feel free to ask any questions and don’t forget to share it with your friends.