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'/>
<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
Best Answer
In SF1 the header row behaves really strangely, it disappears when you scroll, and reappears sometimes only in part when you tap on it. 1a. I logged a case with SFDC and eventually was told the problem is that DataTables are using LDS which isn't supported in SF1. I think this is a bogus answer as I have constructed my own tables using LDS which work swimmingly in SF1.
No Input element yet, this is in the docs but it is a serious agro.
The sort function needs some tweaking to work properly. If you copy the documented code you will find it does not work correctly. I added an attribute for SortedDirection and set the default to Desc as well as an attribute for the sortedBy. See below:
3a. Sort is still a little weird after this as there seems to be a dependency on between the columns, for example, once you sort by name if you sort by age the age sort will be sub sorted within the alpha sort of name. It might be better to roll your own sort function if you want sorting on multiple columns.
Don't set the initial width, min and max width of the columns because you will get wacky results with dynamic data and the column resizing won't behave properly.
Checkboxes are a little wonky but once you get used to their special logic they make sense mostly... don't add an onclick handler as the onrowselection handler does the lifting here.