Hello friends, In this post i will give you example that help you to show relational data in lightning datatable. Please visit the following link https://trailblazer.salesforce.com/ideaView?id=0873A000000lLXYQA2. Datatable not supported relational field but in this post you will find solution for custom object relational query (__r). Until above idea not get implemented, you guys can use this solution atleast for custom object relationship query.
Display relational object data in datatable
For this example, I have used 2 objects 1) student 2) collage. Student object have lookup relation with collage object. So here we can display collage record through student object using relational query. Let's see how we display both objects data in lightning datatable.
Note: This example only work, when you query data from child to parent.
1. Create a fieldset on student object that hold collage lookup field too.
2. Navigate to Developer Console | File | New | Apex Class and create a new apex class named DatatableHandler and replace the following code.
DatatableHandler.apxc
public class DatatableHandler {
@AuraEnabled
public static List<fieldAttribute> getColumns(string sObjectName){
List<fieldAttribute> objfieldAttr=new List<fieldAttribute>();
for(Schema.FieldSetMember f : getFieldSetFields(sObjectName)){
if(String.valueof(f.getType())=='REFERENCE'){
String fieldName=f.getFieldPath();
if(fieldName.contains('__c')){
fieldName=fieldName.replace('__c','');
objfieldAttr.add(new fieldAttribute(f.getLabel(),fieldName+'__r_Name',String.valueof(f.getType())));
}
else
objfieldAttr.add(new fieldAttribute(f.getLabel(),f.getFieldPath(),String.valueof(f.getType())));
}
else
objfieldAttr.add(new fieldAttribute(f.getLabel(),f.getFieldPath(),String.valueof(f.getType())));
}
return objfieldAttr;
}
@AuraEnabled
public static List<sObject> getSobjectData(string sObjectName){
List<String> fieldsforQuery=new List<String>();
for(Schema.FieldSetMember f : getFieldSetFields(sObjectName)){
if(String.valueof(f.getType())=='REFERENCE'){
String fieldName=f.getFieldPath();
if(fieldName.contains('__c')){
fieldName=fieldName.replace('__c','');
fieldsforQuery.add(fieldName+'__r.Name');
}
else
fieldsforQuery.add(fieldName);
}
else
fieldsforQuery.add(f.getFieldPath());
}
String query='SELECT ' + String.join(fieldsforQuery, ',') + ' FROM '+sObjectName;
System.debug('query'+query);
return Database.query(query);
}
public static List<Schema.FieldSetMember> getFieldSetFields(String sObjectName){
SObjectType objToken = Schema.getGlobalDescribe().get(sObjectName);
Schema.DescribeSObjectResult d = objToken.getDescribe();
Map<String, Schema.FieldSet> FsMap = d.fieldSets.getMap();
if(!FsMap.isEmpty()){
return FsMap.values()[0].getFields();
}
return null;
}
public class fieldAttribute{
@AuraEnabled
public string label{get;set;}
@AuraEnabled
public string apiName{get;set;}
@AuraEnabled
public string stype{get;set;}
public fieldAttribute(string label,string apiName,string stype){
this.label=label;
this.apiName=apiName;
this.stype=stype;
}
}
}
3. Navigate to Developer Console | File | New | Lightning Component and create a new component named ParentRecordDatatable and replace the following markup in their respective files.
ParentRecordDatatable.cmp
<aura:component controller="DatatableHandler" implements="force:appHostable,flexipage:availableForAllPageTypes,force:hasRecordId" access="global" >ParentRecordDatatableController.js
<aura:attribute name="results" type="List[]"/>
<aura:attribute name="mycolumns" type="List"/>
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<aura:attribute name="sObjectName" type="String" default="Student__c"/>
<aura:attribute name="isLoading" type="Boolean" default="false" />
<aura:if isTrue="{! v.isLoading }">
<lightning:spinner alternativeText="Loading" />
</aura:if>
<lightning:layout multipleRows="true" horizontalAlign="center">
<lightning:layoutItem padding="around-small" size="12">
<lightning:datatable keyField="id" data="{!v.results}"
columns="{!v.mycolumns}"
resizeColumnDisabled="true"
hideCheckboxColumn="true"
/>
</lightning:layoutItem>
</lightning:layout>
</aura:component>
({ParentRecordDatatableHelper.js
doInit : function(component, event, helper) {
helper.pullColumns(component);
},
})
({
pullColumns : function(component) {
component.set("v.isLoading", true);
var columns=[];
var action=component.get("c.getColumns");
action.setParams({
sObjectName:component.get("v.sObjectName")
})
action.setCallback(this,function(e){
component.set("v.isLoading", false);
if(e.getState()=='SUCCESS'){
var results=e.getReturnValue();
console.log(results);
if(results!=null){
if(results.length>0){
results.forEach(function(result){
if(result.apiName!="Id"){
if(result.apiName=='Name'){
columns.push({label:result.label,fieldName:'linkName',type:'url',
typeAttributes:{label: { fieldName:result.apiName}, target: '_self'}});
}
else if(result.stype=='DATETIME'){
columns.push({
label:result.label,fieldName:result.apiName,type:'date',
typeAttributes:{
day: 'numeric',
month: 'short',
year: 'numeric',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: true}
});
}
else if(result.stype=='BOOLEAN'){
columns.push({label:result.label,fieldName:result.apiName,type:'boolean'});
}
else if(result.stype=='DATE'){
columns.push({label:result.label,fieldName:result.apiName,type:'date',
typeAttributes:{day:'numeric',month:'short',year:'numeric'}});
}
else if(result.stype=='CURRENCY'){
columns.push({label:result.label,fieldName:result.apiName,type:'currency',
typeAttributes:{minimumFractionDigits :'2'}});
}
else{
columns.push({label:result.label,fieldName:result.apiName,type:result.stype});
}
}
})
component.set('v.mycolumns', columns);
this.pullData(component);
}
}
}
else{
this.showToast("ERROR","error",JSON.stringify(e.getError()));
}
});
$A.enqueueAction(action);
},
pullData:function(component){
component.set("v.isLoading", true);
var action=component.get("c.getSobjectData");
var serverjsObject=component.get("v.serverJSObject");
action.setParams({
sObjectName:component.get("v.sObjectName"),
})
action.setCallback(this,function(e){
component.set("v.isLoading", false);
if(e.getState()=='SUCCESS'){
var results=e.getReturnValue();
if(results.length>0){
results.forEach(row=>{
row.linkName = '/'+row.Id;
for (const col in row) {
const curCol = row[col];
if (typeof curCol === 'object') {
const newVal = curCol.Id ? ('/' + curCol.Id) : null;
this.flattenStructure(row, col + '_', curCol);
if (newVal === null) {
delete row[col];
}
else {
row[col] = newVal;
}
}
}
});
component.set('v.results', results);
}
else{
component.set('v.results', []);
}
}
else{
this.showToast("ERROR","error",JSON.stringify(e.getError()));
}
});
$A.enqueueAction(action);
},
flattenStructure:function (topObject, prefix, toBeFlattened) {
for (const prop in toBeFlattened) {
const curVal = toBeFlattened[prop];
if (typeof curVal === 'object') {
flattenStructure(topObject, prefix + prop + '_', curVal);
} else {
topObject[prefix + prop] = curVal;
}
}
},
showToast:function(title,type,message){
var toastEvent = $A.get("e.force:showToast");
if(toastEvent){
toastEvent.setParams({"title": title,"type": type,"message": message}).fire();
}
else{
alert(message);
}
},
})
Output:
Hope you like this post, for any feedback or suggestions please feel free to comment. I would appreciate your feedback and suggestions.
Thank you.
0 Comments
Post a Comment