1

enter image description hereenter image description hereI am implementing lightning:datatable with pagination and save all the selected records at once i am facing two issues:

  1. if I select row2,3,4 in the first ten records and click next it automatically select the row12,13,14 on the next 10 records.
  2. if i select-row2,3,4 and deselect row4 and click next and select row17,18 and then try to save all at once when i click save by accessing component.find("accountTable").get("v.selectedRows"); It is coming as undefined.

Component:

<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global" controller="AccountController">
    <aura:attribute name="AccountData" type="Object"/>
    <aura:attribute name="SelectedAccount" type="Object[]"/>
    <aura:attribute name="columns" type="List"/>    
    <!-- Attribute Declration For Pagination -->
    <aura:attribute name="PaginationList" type="account"/>
    <aura:attribute name="startPage" type="Integer" />
    <aura:attribute name="endPage" type="Integer"/>
    <aura:attribute name="totalRecords" type="Integer"/>
    <aura:attribute name="pageSize" type="Integer" default="10"/>
    <!-- Attribute Declration For Pagination End-->
    <aura:handler name="init" value="{! this }" action="{! c.doInit }"/>
    <label>Account Table</label>
        <lightning:datatable aura:id="accountTable" data="{! v.PaginationList }" 
                             columns="{! v.columns }" 
                             keyField="id"
                             onrowselection="{! c.getSelectedName }"/>  
        <br/>
        <lightning:buttonGroup >
            <lightning:button label="Previous" disabled="{!v.startPage == 0}"  
                              onclick="{!c.previous}" variant="brand"
                              iconName='utility:back'/>
            &nbsp; &nbsp; &nbsp;
            <lightning:button label="Next" disabled="{!v.endPage >= v.totalRecords}" 
                              onclick="{!c.next}" variant="brand"
                              iconName='utility:forward' iconPosition='right'/>
        </lightning:buttonGroup>
        <lightning:button label="Save"  
                              onclick="{!c.save}" variant="brand"/>
</aura:component>

Controller:

({
    doInit: function (component, event, helper) {
        // Set the columns of the Table 
        component.set('v.columns', [
            {label: 'Account Name', fieldName: 'Name', type: 'text'},
            {label: 'Industry', fieldName: 'Industry', type: 'text'},
            {label: 'Type', fieldName: 'Type', type: 'text'},
            {label: 'Id', fieldName: 'Id', type: 'text'},
        ]);
            helper.doFetchAccount(component);
    },getSelectedName: function (component, event) {
            var selectedRows = event.getParam('selectedRows');
            var selectedAccount=[];
             selectedAccount=component.get("v.SelectedAccount");
            for (var i = 0; i < selectedRows.length; i++){
                var row=selectedRows[i];
                if(selectedAccount.includes(row)==false){
                 selectedAccount.push(row);   
                }  }
    component.set("v.SelectedAccount",selectedAccount);    console.log("selectedAccount"+JSON.stringify(component.get("v.SelectedAccount")));},
    next: function (component, event, helper) {
        helper.next(component, event);
    },
    previous: function (component, event, helper) {
        helper.previous(component, event);
    },
    save: function (component, event, helper) {
        helper.save(component, event);
    }
})

Helper:

({
    doFetchAccount : function(component) {
        var action = component.get('c.showAccounts');
        action.setCallback(this, function(response){
            var state = response.getState();
            if(state === 'SUCCESS' && component.isValid()){
                var pageSize = component.get("v.pageSize");
                component.set('v.AccountData', response.getReturnValue());
                // get size of all the records and then hold into an attribute "totalRecords"
                component.set("v.totalRecords", component.get("v.AccountData").length);
                // set star as 0
                component.set("v.startPage",0);

                component.set("v.endPage",pageSize-1);
                var PaginationList = [];
                for(var i=0; i< pageSize; i++){
                    if(component.get("v.AccountData").length> i)
                        PaginationList.push(response.getReturnValue()[i]);    
                }
                component.set('v.PaginationList', PaginationList);
            }else{
                alert('ERROR');
            }
        });
        $A.enqueueAction(action);
    },
    next : function(component, event){
        var sObjectList = component.get("v.AccountData");
        var end = component.get("v.endPage");
        var start = component.get("v.startPage");
        var pageSize = component.get("v.pageSize");
        var Paginationlist = [];
        var counter = 0;
        component.find("accountTable").get("v.selectedRows");
        console.log('selectedRecords'+component.find("accountTable").get("v.selectedRows"));
        for(var i=end+1; i<end+pageSize+1; i++){
            if(sObjectList.length > i){
                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);
    },
    previous : function(component, event){
        var sObjectList = component.get("v.AccountData");
        var end = component.get("v.endPage");
        var start = component.get("v.startPage");
        var pageSize = component.get("v.pageSize");
        var Paginationlist = [];
        var counter = 0;
        for(var i= start-pageSize; i < start ; i++){
            if(i > -1){
                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);
    },
        save : function(component, event){
            component.find("accountTable").get("v.selectedRows");
        console.log('saveRecords'+component.find("accountTable").get("v.selectedRows"));
    }
})

Apex:

public class AccountController {
/*Display account data*/
    @AuraEnabled
    public static List<Account> showAccounts(){
        List<Account> accountList = new List<Account>();
        accountList = [Select Id, Name, Industry,Type From Account LIMIT 100 ];
        return accountList;
    }
}
3

Apart from changing keyField="Id", you can make the following changes.

To store the selected Accounts, you have to store them pagewise as a user can select and deselect the Accounts.

Here I have used getSelectedRows() method of Lightning Datatable to get the selected rows in previous and next method.

............
<aura:attribute name="SelectedAccount" type="Map" default="{}"/>
............
var selectedRows = dTable.getSelectedRows();
var pgName = "page" + current;
component.get("v.SelectedAccount")[pgName] = selectedRows;
...........

To pre-select the checkboxes while the user is moving from one page to other you have to set the selected rows in Previous and Next methods.

........
if (typeof selectedRows != 'undefined' && selectedRows) {
    var selectedRowsIds = [];
    for(var i=0;i<selectedRows.length;i++){
        selectedRowsIds.push(selectedRows[i].Id);  
    }         
    var dTable = component.find("accountTable");
    dTable.set("v.selectedRows", selectedRowsIds); 
}
........

Complete Code:

Component

<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global" controller="AccountController">
    <aura:attribute name="AccountData" type="Object"/>
    <aura:attribute name="SelectedAccount" type="Map" default="{}"/>
    <aura:attribute name="columns" type="List"/>    
    <!-- Attribute Declration For Pagination -->
    <aura:attribute name="PaginationList" type="account"/>
    <aura:attribute name="currentPage" type="Integer" />
    <aura:attribute name="startPage" type="Integer" />
    <aura:attribute name="endPage" type="Integer"/>
    <aura:attribute name="totalRecords" type="Integer"/>
    <aura:attribute name="pageSize" type="Integer" default="10"/>
    <!-- Attribute Declration For Pagination End-->
    <aura:handler name="init" value="{! this }" action="{! c.doInit }"/>
    <label>Account Table</label>
    <lightning:datatable aura:id="accountTable" data="{! v.PaginationList }" 
                         columns="{! v.columns }" 
                         keyField="Id"
                         onrowselection="{!c.getSelectedName}"/>  
    <br/>
    <lightning:buttonGroup >
        <lightning:button label="Previous" disabled="{!v.startPage == 0}"  
                          onclick="{!c.previous}" variant="brand"
                          iconName='utility:back'/>
        &nbsp; &nbsp; &nbsp;
        <lightning:button label="Next" disabled="{!v.endPage >= v.totalRecords}" 
                          onclick="{!c.next}" variant="brand"
                          iconName='utility:forward' iconPosition='right'/>
    </lightning:buttonGroup>
    <lightning:button label="Save" onclick="{!c.save}" variant="brand"/>
</aura:component>

Controller:

({
    doInit: function (component, event, helper) {
        // Set the columns of the Table 
        component.set('v.columns', [
            {label: 'Account Name', fieldName: 'Name', type: 'text'},
            {label: 'Industry', fieldName: 'Industry', type: 'text'},
            {label: 'Type', fieldName: 'Type', type: 'text'},
            {label: 'Id', fieldName: 'Id', type: 'text'},
        ]);
        helper.doFetchAccount(component);
    },
    getSelectedName: function (component, event) {

    },
    next: function (component, event, helper) {
        helper.next(component, event);
    },
    previous: function (component, event, helper) {
        helper.previous(component, event);
    },
    save: function (component, event, helper) {
        helper.save(component, event);
    }
})

Helper

({
    doFetchAccount : function(component) {
        var action = component.get('c.showAccounts');
        action.setCallback(this, function(response){
            var state = response.getState();
            if(state === 'SUCCESS' && component.isValid()){
                var pageSize = component.get("v.pageSize");
                component.set('v.AccountData', response.getReturnValue());
                // get size of all the records and then hold into an attribute "totalRecords"
                component.set("v.totalRecords", component.get("v.AccountData").length);
                //Set the current Page as 0
                component.set("v.currentPage",0);
                // set star as 0
                component.set("v.startPage",0);
                component.set("v.endPage",pageSize-1);
                var PaginationList = [];
                for(var i=0; i< pageSize; i++){
                    if(component.get("v.AccountData").length> i){
                        PaginationList.push(response.getReturnValue()[i]);
                    }
                }
                component.set('v.PaginationList', PaginationList);
            }else{
                alert('ERROR');
            }
        });
        $A.enqueueAction(action);
    },
    next : function(component, event){
        var current = component.get("v.currentPage");    
        var dTable = component.find("accountTable");
        var selectedRows = dTable.getSelectedRows();
        var pgName = "page" + current;
        component.get("v.SelectedAccount")[pgName] = selectedRows;
        current = current +1;
        pgName = "page" + current;
        var selectedRows = component.get("v.SelectedAccount")[pgName];
        component.set("v.currentPage",current);
        console.log("Next selectedAccount "+JSON.stringify(component.get("v.SelectedAccount")));        
        var sObjectList = component.get("v.AccountData");
        var end = component.get("v.endPage");
        var start = component.get("v.startPage");
        var pageSize = component.get("v.pageSize");
        var Paginationlist = [];
        var counter = 0;
        for(var i=end+1; i<end+pageSize+1; i++){
            if(sObjectList.length > i){
                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);
        if (typeof selectedRows != 'undefined' && selectedRows) {
            var selectedRowsIds = [];
            for(var i=0;i<selectedRows.length;i++){
                selectedRowsIds.push(selectedRows[i].Id);  
            }         
            var dTable = component.find("accountTable");
            dTable.set("v.selectedRows", selectedRowsIds); 
        }
    },
    previous : function(component, event){   
        var current = component.get("v.currentPage");
        var dTable = component.find("accountTable");
        var selectedRows = dTable.getSelectedRows();
        var pgName = "page" + current;
        component.get("v.SelectedAccount")[pgName] = selectedRows;
        current = current - 1; 
        pgName = "page" + current;
        var selectedRows = component.get("v.SelectedAccount")[pgName];
        component.set("v.currentPage",current);
        console.log("Prev selectedAccount "+JSON.stringify(component.get("v.SelectedAccount")));        
        var sObjectList = component.get("v.AccountData");
        var end = component.get("v.endPage");
        var start = component.get("v.startPage");
        var pageSize = component.get("v.pageSize");
        var Paginationlist = [];
        var counter = 0;
        for(var i= start-pageSize; i < start ; i++){
            if(i > -1){
                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);
        if (typeof selectedRows != 'undefined' && selectedRows) {
            var selectedRowsIds = [];
            for(var i=0;i<selectedRows.length;i++){
                selectedRowsIds.push(selectedRows[i].Id);  
            }         
            var dTable = component.find("accountTable");
            dTable.set("v.selectedRows", selectedRowsIds);
        }
    },
    save : function(component, event){
        console.log("selectedAccount "+JSON.stringify(component.get("v.SelectedAccount")));
    }
})

Apex

public class AccountController {
    /*Display account data*/
    @AuraEnabled
    public static List<Account> showAccounts(){
        List<Account> accountList = new List<Account>();
        accountList = [Select Id, Name, Industry,Type From Account LIMIT 100 ];
        return accountList;
    }
}

Screen Capture

enter image description here

1

Checkbox unique identifiers are tied to the keyField.

Try changing it to case sensitive Id in your datatable from id

  • I am using keyField as Id <lightning:datatable aura:id="accountTable" data="{! v.PaginationList }" columns="{! v.columns }" keyField="id" onrowselection="{! c.getSelectedName }"/> – Vidhyasagaran Muralidharan Apr 8 '18 at 3:47
  • I think this is a case sensitivity issue - you call the keyField id but the actual field on the columns json is Id - try changing it to: keyField="Id" – Itai Shmida Apr 8 '18 at 9:24
  • Issue no:1 is fixed but if you see the issue 2 it still exists in the lightning datatable.attaching the console screenshot.First i selected 3 records in first ten records and then i clicked next and selected 2 more records and click next.In the next click it is not showing 5 records.And on click of save the selectedrows comes blank.is this bug?.Please check console log name -selectedRecords,saveRecords – Vidhyasagaran Muralidharan Apr 8 '18 at 20:19
  • As in your code in a single list, you are pushing the selected Accounts if it is not present. I think by doing this you can't handle select and deselect as there is no way to differentiate the two in the getSelectedName method as it is giving only the selected list. I have tried to store the selected list with page index so that I can have the final list after select and deselect. Please check my answer for details. – Saroj Bera Apr 8 '18 at 20:34
  • @sarojBera:code is not preselecting the values if it move from previous or next attaching screenshot – Vidhyasagaran Muralidharan Apr 8 '18 at 21:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.