Last active
March 18, 2019 16:52
-
-
Save tushar30/302a4a6c804343f19dcd7ffa99ccff6f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<aura:application extends="force:slds"> | |
<aura:attribute name="userData" type="List" default="[]"/> | |
<aura:attribute name="tableHeight" type="Integer" default="450"/> | |
<aura:attribute name="sortedDirection" type="String" default="DESC"/> | |
<aura:attribute name="inlineEdit" type="boolean" default="true"/> | |
<aura:attribute name="enableColAction" type="boolean" default="true"/> | |
<c:DataTableLazyLoading selectedData="{!v.userData}" tableHeight="{!v.tableHeight}" | |
sortedDirection="{!v.sortedDirection}" inlineEdit="{!v.inlineEdit}" | |
enableColAction ="{!v.enableColAction}"/> | |
Selected Rows: <br/> <br/> | |
<aura:iteration items="{!v.userData}" var="item"> | |
{!item.Id}<br/> | |
</aura:iteration> | |
</aura:application> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class DataTableController { | |
@AuraEnabled | |
public static DataTableWrapper initRecords(String ObjectName, String fieldNamesStr, String Orderby, String OrderDir, boolean inlineEdit, boolean enableColAction) { | |
DataTableWrapper dtw = new DataTableWrapper(); | |
List<LabelDescriptionWrapper> labelList = new List<LabelDescriptionWrapper>(); | |
List<String> fieldSet = new List<String>(); | |
Set<String> fieldNameSet = new Set<String>(fieldNamesStr.split(',')); | |
if(Schema.getGlobalDescribe().containsKey(ObjectName) ) { | |
sObject sObj = Schema.getGlobalDescribe().get(ObjectName).newSObject() ; | |
//get all the labels for Opportunity fields and put them in a map, keyed to the field api name | |
Map<String, Schema.SObjectField> fieldMap = Schema.getGlobalDescribe().get(ObjectName).getDescribe().fields.getMap(); | |
Map<Schema.SObjectField,String> fieldToAPIName = new Map<Schema.SObjectField,String>(); | |
Map<String, String> apiNameToLabel = new Map<String, String>(); | |
for(String fieldName : fieldNameSet){ | |
if(fieldMap.containsKey(fieldName)) { | |
fieldSet.add(fieldName); | |
labelList.add(new LabelDescriptionWrapper(fieldMap.get(fieldName).getDescribe().getLabel(), fieldName, fieldMap.get(fieldName).getDescribe().getType().name().toLowerCase(), true,inlineEdit, null )); | |
} | |
} | |
//add action | |
if(enableColAction) { | |
List<Actions> actionList = new List<Actions>(); | |
actionList.add(new Actions('Edit','Edit')); | |
actionList.add(new Actions('View','View')); | |
actionList.add(new Actions('Delete','Delete')); | |
TypeAttributes tAttribute = new TypeAttributes(actionList); | |
labelList.add(new LabelDescriptionWrapper('Actions', 'Actions', 'action', false, false, tAttribute )); | |
} | |
//call method to query | |
List<sObject> sObjectRecords = getsObjectRecords(ObjectName, fieldSet, 50, '', Orderby, OrderDir); | |
dtw.ldwList = labelList; | |
dtw.sobList = sObjectRecords; | |
dtw.fieldsList = fieldSet; | |
dtw.totalCount = Database.countQuery('SELECT count() FROM '+ObjectName); | |
} | |
return dtw; | |
} | |
@AuraEnabled | |
public static List<sObject> getsObjectRecords(String ObjectName, List<String> fieldNameSet, Integer LimitSize, String recId, String Orderby, String OrderDir) { | |
OrderDir = String.isBlank(OrderDir) ? 'asc' : OrderDir; | |
String query = 'SELECT '+String.join(fieldNameSet, ',')+' FROM '+ObjectName; | |
if(String.isNotBlank(recId)) { | |
recId = String.valueOf(recId); | |
query += ' WHERE ID >: recId '; | |
} | |
query += ' ORDER BY '+Orderby+' '+OrderDir+' NULLS LAST'; | |
if(LimitSize != null && Integer.valueOf(LimitSize) > 0) { | |
LimitSize = Integer.valueOf(LimitSize); | |
query += ' Limit '+LimitSize; | |
} | |
return Database.query(query); | |
} | |
@AuraEnabled | |
public static sObject deleteSObject(sObject sob) { | |
delete sob; | |
return sob; | |
} | |
@AuraEnabled | |
public static void updateRecords(List<sObject> sobList, String updateObjStr, String objectName) { | |
// | |
System.debug(updateObjStr); | |
System.debug(sobList); | |
schema.SObjectType sobjType = Schema.getGlobalDescribe().get(ObjectName); | |
Map<String, Schema.sObjectField> sObjectFields = sobjType.getDescribe().fields.getMap(); | |
List<sObject> updateList = new List<sObject>(); | |
List<Object> obList = (List<object>) json.deserializeUntyped(updateObjStr); | |
for(object ob : obList) { | |
Map<String, object> obmap = (Map<String, object>)ob; | |
String rowKey = (String)obmap.get('id'); | |
Integer rowKeyInt = Integer.ValueOf(rowKey.removeStart('row-')); | |
sobject sObj = sobList[rowKeyInt]; | |
for(string fieldName : obmap.keySet()) { | |
if(fieldName != 'id') { | |
Object value = obmap.get(fieldName); | |
Schema.DisplayType valueType = sObjectFields.get(fieldName).getDescribe().getType(); | |
if (value instanceof String && valueType != Schema.DisplayType.String) | |
{ | |
String svalue = (String)value; | |
if (valueType == Schema.DisplayType.Date) | |
sObj.put(fieldName, Date.valueOf(svalue)); | |
else if(valueType == Schema.DisplayType.DateTime) { | |
try{ | |
System.debug( (DateTime)value); | |
}catch(exception ex) { | |
system.debug(ex.getmessage()); | |
} | |
String d1 = svalue; | |
list<String> d2 = d1.split('-'); | |
list<integer> timeComponent = new list<integer>(); | |
timeComponent.add(Integer.valueOf(d2[0])); | |
timeComponent.add(Integer.valueOf(d2[1])); | |
timeComponent.add(Integer.valueOf(d2[2].left(2))); | |
String t = d2[2].substringBetween('T','.'); | |
list<String> time1 = t.split(':'); | |
timeComponent.add(Integer.valueOf(time1[0])); | |
timeComponent.add(Integer.valueOf(time1[1])); | |
timeComponent.add(Integer.valueOf(time1[2])); | |
Datetime dt = Datetime.newInstance(timeComponent[0],timeComponent[1],timeComponent[2],timeComponent[3],timeComponent[4],timeComponent[5]); | |
sObj.put(fieldName, dt); | |
} | |
// | |
else if (valueType == Schema.DisplayType.Percent || valueType == Schema.DisplayType.Currency) | |
sObj.put(fieldName, svalue == '' ? null : Decimal.valueOf(svalue)); | |
else if (valueType == Schema.DisplayType.Double) | |
sObj.put(fieldName, svalue == '' ? null : Double.valueOf(svalue)); | |
else if (valueType == Schema.DisplayType.Integer) | |
sObj.put(fieldName, Integer.valueOf(svalue)); | |
else if (valueType == Schema.DisplayType.Base64) | |
sObj.put(fieldName, Blob.valueOf(svalue)); | |
else | |
sObj.put(fieldName, svalue); | |
} | |
else | |
sObj.put(fieldName, value); | |
} | |
} | |
updateList.add(sObj); | |
} | |
update updateList; | |
//return sobList; | |
} | |
public class DataTableWrapper { | |
@AuraEnabled | |
public List<LabelDescriptionWrapper> ldwList; | |
@AuraEnabled | |
public List<sObject> sobList; | |
@AuraEnabled | |
public List<String> fieldsList; | |
@AuraEnabled | |
public Integer totalCount; | |
} | |
public class LabelDescriptionWrapper { | |
@AuraEnabled | |
public String label; | |
@AuraEnabled | |
public String fieldName; | |
@AuraEnabled | |
public String type; | |
@AuraEnabled | |
public boolean sortable; | |
@AuraEnabled | |
public boolean editable; | |
@AuraEnabled | |
public TypeAttributes typeAttributes; | |
public LabelDescriptionWrapper(String labelTemp, String fieldNameTemp, String typeTemp, boolean sortableTemp, boolean editableTemp,TypeAttributes typeAttributesTemp) { | |
label = labelTemp; | |
fieldName = fieldNameTemp; | |
type = typeTemp; | |
sortable = sortableTemp; | |
editable = editableTemp; | |
typeAttributes = typeAttributesTemp; | |
} | |
} | |
public class TypeAttributes { | |
@AuraEnabled | |
public List<Actions> rowActions; | |
public typeAttributes(List<Actions> rowActionsTemp) { | |
rowActions = rowActionsTemp; | |
} | |
} | |
public class Actions { | |
@AuraEnabled | |
public String label; | |
@AuraEnabled | |
public String name; | |
public Actions(String labelTemp, String nameTemp) { | |
label = labelTemp; | |
name = nameTemp; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<aura:component controller="DataTableController" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global" > | |
<!-- attributes --> | |
<aura:attribute name="objectName" type="String" default="Account"/> | |
<aura:attribute name="fieldsString" type="String" default="Name,Phone,Email,Website"/> | |
<aura:attribute name="fieldsList" type="List" default="[]"/> | |
<aura:attribute name="columns" type="List" default="[]"/> | |
<aura:attribute name="data" type="List" default="[]"/> | |
<aura:attribute name="selectedData" type="List" default="[]"/> | |
<aura:attribute name="keyField" type="String" default="id"/> | |
<aura:attribute name="initialRows" type="Integer" default="5"/> | |
<aura:attribute name="selectedRowsCount" type="Integer" default="0"/> | |
<aura:attribute name="enableInfiniteLoading" type="Boolean" default="true"/> | |
<aura:attribute name="rowsToLoad" type="Integer" default="50"/> | |
<aura:attribute name="totalNumberOfRows" type="Integer" default="3000"/> | |
<aura:attribute name="loadMoreStatus" type="String" default=""/> | |
<aura:attribute name="sortedBy" type="String" default="Id"/> | |
<aura:attribute name="sortedDirection" type="String" default="ASC"/> | |
<aura:attribute name="inlineEdit" type="boolean" default="true"/> | |
<aura:attribute name="enableColAction" type="boolean" default="true"/> | |
<aura:attribute name="showRowNumber" type="boolean" default="true"/> | |
<aura:attribute name="hideCheckboxColumn" type="boolean" default="false"/> | |
<aura:attribute name="maxRowSelection" type="Integer" default="50"/> | |
<aura:attribute name="tableHeight" type="Integer" default="450"/> | |
<aura:attribute name="errors" type="Object" default="[]"/> | |
<aura:attribute name="pageReference" type="Object"/> | |
<lightning:navigation aura:id="navService"/> | |
<lightning:notificationsLibrary aura:id="notifLib"/> | |
<!-- handlers--> | |
<aura:handler name="init" value="{! this }" action="{! c.init }"/> | |
<div class="slds-is-relative"> | |
<!-- the container element determine the height of the datatable --> | |
<div style="{!'height:'+v.tableHeight+'px'}"> | |
<lightning:datatable aura:id="dataTable" | |
columns="{! v.columns }" | |
data="{! v.data }" | |
keyField="{! v.keyField }" | |
showRowNumberColumn="{! v.showRowNumber }" | |
sortable = "true" | |
editable = "true" | |
onsort = "{! c.updateColumnSorting }" | |
sortedBy="{!v.sortedBy}" | |
sortedDirection="{!v.sortedDirection}" | |
onrowselection="{! c.updateSelectedRow }" | |
maxRowSelection="{! v.maxRowSelection }" | |
enableInfiniteLoading="{! v.enableInfiniteLoading }" | |
onloadmore="{! c.loadMoreData }" | |
onrowaction="{! c.handleRowAction }" | |
errors="{! v.errors }" | |
draftValues="{! v.draftValues }" | |
onsave="{! c.handleSaveEdition }" | |
/><!-- hideCheckboxColumn = "{! c.hideCheckboxColumn }" --> | |
</div> | |
{! v.loadMoreStatus } | |
</div> | |
</aura:component> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
({ | |
init: function (cmp, event, helper) { | |
console.log( cmp.get("v.data").length ); | |
helper.initData(cmp, event, cmp.get("v.data").length); | |
}, | |
updateSelectedRow: function (cmp, event) { | |
var selectedRows = event.getParam('selectedRows'); | |
cmp.set('v.selectedRowsCount', selectedRows.length); | |
cmp.set('v.selectedData', selectedRows); | |
console.log( cmp.get('v.selectedData') ); | |
}, | |
resetRows: function (cmp, event, helper) { | |
cmp.set('v.data', []); | |
helper.initData(cmp, event, cmp.get("v.data").length); | |
}, | |
loadMoreData: function (cmp, event, helper) { | |
var rowsToLoad = cmp.get('v.rowsToLoad'); | |
event.getSource().set("v.isLoading", true); | |
cmp.set('v.loadMoreStatus', 'Loading'); | |
helper.fetchData(cmp, event, cmp.get("v.data").length); | |
}, | |
updateColumnSorting: function (cmp, event, helper) { | |
var fieldName = event.getParam('fieldName'); | |
var sortDirection = event.getParam('sortDirection'); | |
// assign the latest attribute with the sorted column fieldName and sorted direction | |
cmp.set("v.sortedBy", fieldName); | |
cmp.set("v.sortedDirection", sortDirection); | |
cmp.set('v.data', []); | |
event.getSource().set("v.isLoading", true); | |
cmp.set('v.loadMoreStatus', 'Loading'); | |
helper.initData(cmp, event, cmp.get("v.data").length); | |
}, | |
handleRowAction: function (cmp, event, helper) { | |
var action = event.getParam('action'); | |
var row = event.getParam('row'); | |
switch (action.name) { | |
case 'Edit': | |
helper.editRecord(cmp, row); | |
break; | |
case 'View': | |
helper.viewRecord(cmp, row); | |
break; | |
case 'Delete': | |
helper.deleteRecord(cmp, row); | |
break; | |
default: | |
helper.viewRecord(cmp,row); | |
break; | |
} | |
}, | |
handleSaveEdition: function (cmp, event, helper) { | |
var draftValues = event.getParam('draftValues'); | |
var data = cmp.get('v.data'); | |
helper.saveRecords(cmp, event, helper, data, draftValues); | |
}, | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
({ | |
initData: function (cmp, event, numberOfRecords) { | |
var action = cmp.get("c.initRecords"); | |
action.setParams({ | |
ObjectName : cmp.get("v.objectName"), | |
fieldNamesStr : cmp.get("v.fieldsString"), | |
Orderby : cmp.get("v.sortedBy"), | |
OrderDir : cmp.get("v.sortedDirection"), | |
inlineEdit: cmp.get("v.inlineEdit"), | |
enableColAction: cmp.get("v.enableColAction") | |
}); | |
action.setCallback(this, function(response) { | |
var state = response.getState(); | |
if (state === "SUCCESS") { | |
console.log(response.getReturnValue().ldwList); | |
cmp.set("v.columns", response.getReturnValue().ldwList); | |
cmp.set("v.data", response.getReturnValue().sobList); | |
cmp.set("v.fieldsList", response.getReturnValue().fieldsList); | |
cmp.set("v.totalNumberOfRows", response.getReturnValue().totalCount); | |
cmp.set('v.loadMoreStatus', ''); | |
event.getSource().set("v.isLoading", false); | |
} | |
else if (state === "ERROR") { | |
var errors = response.getError(); | |
if (errors) { | |
if (errors[0] && errors[0].message) { | |
console.log("Error message: " + | |
errors[0].message); | |
} | |
} else { | |
console.log("Unknown error"); | |
} | |
} | |
}); | |
$A.enqueueAction(action); | |
}, | |
fetchData: function (cmp, event, numberOfRecords) { | |
//var dataPromise; | |
var data = cmp.get("v.data"); | |
var dataSize = cmp.get("v.data").length; | |
var lastId = data[dataSize - 1].Id; | |
var action = cmp.get("c.getsObjectRecords"); | |
action.setParams({ | |
ObjectName : cmp.get("v.objectName"), | |
fieldNameSet : cmp.get("v.fieldsList"), | |
LimitSize : 50, | |
recId : lastId, | |
Orderby : cmp.get("v.sortedBy"), | |
OrderDir : cmp.set("v.sortedDirection") | |
}); | |
action.setCallback(this, function(response) { | |
var state = response.getState(); | |
if (state === "SUCCESS") { | |
if (cmp.get('v.data').length >= cmp.get('v.totalNumberOfRows')) { | |
cmp.set('v.enableInfiniteLoading', false); | |
cmp.set('v.loadMoreStatus', 'No more data to load'); | |
} else { | |
var currentData = cmp.get('v.data'); | |
var newData = currentData.concat(response.getReturnValue()); | |
cmp.set('v.data', newData); | |
cmp.set('v.loadMoreStatus', ''); | |
} | |
event.getSource().set("v.isLoading", false); | |
} | |
else if (state === "ERROR") { | |
var errors = response.getError(); | |
if (errors) { | |
if (errors[0] && errors[0].message) { | |
console.log("Error message: " + | |
errors[0].message); | |
} | |
} else { | |
console.log("Unknown error"); | |
} | |
} | |
}); | |
$A.enqueueAction(action); | |
}, | |
sortData: function (cmp, fieldName, sortDirection) { | |
var data = cmp.get("v.data"); | |
var reverse = sortDirection !== 'asc'; | |
//sorts the rows based on the column header that's clicked | |
data.sort(this.sortBy(fieldName, reverse)) | |
cmp.set("v.data", data); | |
}, | |
sortBy: function (field, reverse, primer) { | |
var key = primer ? | |
function(x) {return primer(x[field])} : | |
function(x) {return x[field]}; | |
//checks if the two rows should switch places | |
reverse = !reverse ? 1 : -1; | |
return function (a, b) { | |
return a = key(a), b = key(b), reverse * ((a > b) - (b > a)); | |
} | |
}, | |
editRecord: function (cmp, row) { | |
var navService = cmp.find("navService"); | |
var pageReference = { | |
type: 'standard__recordPage', | |
attributes: { | |
"recordId": row.Id, | |
"objectApiName": cmp.get("v.objectName"), | |
"actionName": "edit" | |
} | |
} | |
navService.navigate(pageReference); | |
}, | |
viewRecord : function(cmp, row) { | |
var navService = cmp.find("navService"); | |
console.log(row); | |
var pageReference = { | |
type: 'standard__recordPage', | |
attributes: { | |
"recordId": row.Id, | |
"objectApiName": cmp.get("v.objectName"), | |
"actionName": "view" | |
} | |
} | |
navService.navigate(pageReference); | |
}, | |
deleteRecord : function(cmp, row) { | |
var action = cmp.get("c.deleteSObject"); | |
action.setParams({ | |
"sob":row | |
}); | |
action.setCallback(this, function(response) { | |
var state = response.getState(); | |
if (state === "SUCCESS") { | |
var rows = cmp.get('v.data'); | |
var rowIndex = rows.indexOf(row); | |
rows.splice(rowIndex, 1); | |
cmp.set('v.data', rows); | |
/* var toastEvent = $A.get("e.force:showToast"); | |
toastEvent.setParams({ | |
"title": "Success!", | |
"message": "Record deleted.", | |
"type": "success" | |
}); | |
toastEvent.fire(); | |
*/ | |
cmp.find('notifLib').showNotice({ | |
"variant": "info", | |
"header": "Success!", | |
"message": "Record deleted.", | |
closeCallback: function() { | |
} | |
}); | |
} | |
else if (state === "ERROR") { | |
// handle error | |
var errorMsg = ''; | |
var errors = response.getError(); | |
if (errors) { | |
if (errors[0] && errors[0].message) { | |
errorMsg = errors[0].message; | |
} | |
if (errors[0] && errors[0].pageErrors && errors[0].pageErrors[0].message) { | |
errorMsg += errors[0].pageErrors[0].message; | |
} | |
} | |
cmp.find('notifLib').showNotice({ | |
"variant": "error", | |
"header": "Something has gone wrong!", | |
"message": errorMsg, | |
closeCallback: function() { | |
} | |
}); | |
/* | |
var errors = response.getError(); | |
var toastEvent = $A.get("e.force:showToast"); | |
toastEvent.setParams({ | |
"title": "error", | |
"message": errorMsg, | |
"type": "error" | |
}); | |
toastEvent.fire();*/ | |
} | |
}); | |
$A.enqueueAction(action); | |
}, | |
saveRecords : function(cmp, event, helper, data, draftValues) { | |
var action = cmp.get("c.updateRecords"); | |
var draftValuesStr = JSON.stringify(draftValues); | |
action.setParams({ | |
"sobList":data, | |
"updateObjStr" : draftValuesStr, | |
"objectName" : cmp.get("v.objectName") | |
}); | |
action.setCallback(this, function(response) { | |
var state = response.getState(); | |
if (state === "SUCCESS") { | |
cmp.set('v.errors', []); | |
cmp.set('v.draftValues', []); | |
helper.initData(cmp, event, 50); | |
} | |
else if (state === "ERROR") { | |
// handle error | |
var errorMsg = ''; | |
var errors = response.getError(); | |
if (errors) { | |
if (errors[0] && errors[0].message) { | |
errorMsg = errors[0].message; | |
} | |
if (errors[0] && errors[0].pageErrors && errors[0].pageErrors[0].message) { | |
errorMsg += errors[0].pageErrors[0].message; | |
} | |
} | |
cmp.find('notifLib').showNotice({ | |
"variant": "error", | |
"header": "Something has gone wrong!", | |
"message": errorMsg, | |
closeCallback: function() { | |
} | |
}); | |
cmp.set('v.errors', errorMsg); | |
} | |
}); | |
$A.enqueueAction(action); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment