You need to sign in to do that
Don't have an account?
Nishant Shrivastava 30
i want to show child object details by selecting rows, how to fetch data of selected row and retrieve child objects in controller
component
<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId" access="global" controller="SingleRelatedListController">
<aura:attribute name="sobjectApiName" type="String" required="true" />
<aura:attribute name="relatedFieldApiName" type="String" required="true"/>
<aura:attribute name="numberOfRecords" type="Integer" default="6"/>
<aura:attribute name="sortedBy" type="String" required="true"/>
<aura:attribute name="sortedDirection" type="String" default="ASC"/>
<aura:attribute name="onRowActionHandler" type="Aura.Action"/>
<aura:attribute name="customActions" type="List"/>
<aura:attribute name="columns" type="List" />
<aura:attribute name="columnsWithActions" type="List" access="private"/>
<aura:attribute name="fields" type="String" required="true"/>
<aura:attribute name="records" type="Object" access="private"/>
<aura:attribute name="parentRelationshipApiName" type="String" access="private"/>
<aura:attribute name="sobjectLabel" type="String" access="private"/>
<aura:attribute name="sobjectLabelPlural" type="String" access="private"/>
<aura:attribute name="numberOfRecordsForTitle" type="String" access="private"/>
<aura:attribute name="iconName" type="String" access="private"/>
<aura:handler name="init" value="{!this}" action="{!c.init}"/>
<aura:handler name="change" value="{!v.columns}" action="{! c.handleColumnsChange }"/>
<aura:handler event="force:showToast" action="{!c.handleToastEvent}"/>
<lightning:overlayLibrary aura:id="overlayLib"/>
<div class="c-container">
<lightning:card class="slds-card_boundary" iconName="{!v.iconName}">
<aura:set attribute="actions">
<lightning:button label="New" onclick="{!c.handleCreateRecord}"/>
</aura:set>
<aura:set attribute="title">
<b><a class="slds-card__header-link" onclick="{!c.handleGotoRelatedList}">{!(v.sobjectLabelPlural) + ' (' + (v.numberOfRecordsForTitle) + ')'}</a></b>
</aura:set>
<aura:set attribute="footer">
<aura:if isTrue="{!not(empty(v.records))}">
<a onclick="{!c.handleGotoRelatedList}">View All</a>
</aura:if>
</aura:set>
<aura:if isTrue="{!not(empty(v.records))}">
<p class="slds-p-horizontal_small">
<lightning:datatable class="related-list"
columns="{! v.columnsWithActions }"
data="{! v.records }"
keyField="id"
onrowaction="{! c.handleRowAction }"
hideCheckboxColumn="false"
resizeColumnDisabled="true"
maxRowSelection="1"
onrowselection="{! c.selectionAction }"/>
</p>
</aura:if>
</lightning:card>
</div>
</aura:component>
controller
({
init: function (cmp, event, helper) {
helper.fetchData(cmp, event, helper);
helper.initColumnsWithActions(cmp, event, helper)
},
selectionAction: function (cmp, event, helper)
{
var selectedRows = event.getParam('selectedRows'); // fetches the records which are selected by the user
selectedRows ="1"{}
},
handleColumnsChange: function (cmp, event, helper) {
helper.initColumnsWithActions(cmp, event, helper)
},
handleRowAction: function (cmp, event, helper) {
var action = event.getParam('action');
var row = event.getParam('row');
var onRowActionHandler = cmp.get('v.onRowActionHandler');
if(onRowActionHandler){
$A.enqueueAction(onRowActionHandler)
}else{
switch (action.name) {
case 'edit':
helper.editRecord(cmp, row)
break;
case 'delete':
helper.removeRecord(cmp, row)
break;
}
}
},
handleGotoRelatedList : function (cmp, event, helper) {
var relatedListEvent = $A.get("e.force:navigateToRelatedList");
relatedListEvent.setParams({
"relatedListId": cmp.get("v.parentRelationshipApiName"),
"parentRecordId": cmp.get("v.recordId")
});
relatedListEvent.fire();
},
handleCreateRecord : function (cmp, event, helper) {
var createRecordEvent = $A.get("e.force:createRecord");
createRecordEvent.setParams({
"entityApiName": cmp.get("v.sobjectApiName"),
"defaultFieldValues": {
[cmp.get("v.relatedFieldApiName")] : cmp.get("v.recordId")
}
});
createRecordEvent.fire();
},
handleToastEvent : function (cmp, event, helper) {
var eventType = event.getParam('type');
var eventMessage= event.getParam('message');
if(eventType == 'SUCCESS' && eventMessage.includes(cmp.get('v.sobjectLabel'))){
helper.fetchData(cmp, event, helper)
event.stopPropagation();
}
},
})
helper
({
fetchData: function (cmp, event, helper) {
var action = cmp.get("c.initData")
var relatedFieldApiName = cmp.get("v.relatedFieldApiName")
var numberOfRecords = cmp.get("v.numberOfRecords")
var jsonData = JSON.stringify({fields:cmp.get("v.fields"),
relatedFieldApiName:cmp.get("v.relatedFieldApiName"),
recordId:cmp.get("v.recordId"),
numberOfRecords:numberOfRecords + 1,
sobjectApiName: cmp.get("v.sobjectApiName"),
sortedBy: cmp.get("v.sortedBy"),
sortedDirection: cmp.get("v.sortedDirection")
});
action.setParams({jsonData : jsonData});
action.setCallback(this, function(response) {
var state = response.getState();
if (state === "SUCCESS") {
var jsonData = JSON.parse(response.getReturnValue())
var records = jsonData.records
if(records.length > numberOfRecords){
records.pop()
cmp.set('v.numberOfRecordsForTitle', numberOfRecords + "+")
}else{
cmp.set('v.numberOfRecordsForTitle', Math.min(numberOfRecords,records.length))
}
records.forEach(record => {
record.LinkName = '/'+record.Id
for (const col in record) {
const curCol = record[col];
if (typeof curCol === 'object') {
const newVal = curCol.Id ? ('/' + curCol.Id) : null;
helper.flattenStructure(helper,record, col + '_', curCol);
if (newVal !== null) {
record[col+ '_LinkName'] = newVal;
}
}
}
});
cmp.set('v.records', records)
cmp.set('v.iconName', jsonData.iconName)
cmp.set('v.sobjectLabel', jsonData.sobjectLabel)
cmp.set('v.sobjectLabelPlural', jsonData.sobjectLabelPlural)
cmp.set('v.parentRelationshipApiName', jsonData.parentRelationshipApiName)
}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);
},
flattenStructure : function (helper,topObject, prefix, toBeFlattened) {
for (const prop in toBeFlattened) {
const curVal = toBeFlattened[prop];
if (typeof curVal === 'object') {
helper.flattenStructure(helper, topObject, prefix + prop + '_', curVal);
} else {
topObject[prefix + prop] = curVal;
}
}
},
initColumnsWithActions: function (cmp, event, helper) {
var customActions = cmp.get('v.customActions')
if( !customActions.length){
customActions = [
{ label: 'Edit', name: 'edit' },
{ label: 'Delete', name: 'delete' }
]
}
var columns = cmp.get('v.columns')
var columnsWithActions = []
columnsWithActions.push(...columns)
columnsWithActions.push({ type: 'action', typeAttributes: { rowActions: customActions } })
cmp.set('v.columnsWithActions', columnsWithActions)
},
removeRecord: function (cmp, row) {
var modalBody;
var modalFooter;
var sobjectLabel = cmp.get('v.sobjectLabel')
$A.createComponents([
["c:deleteRecordContent",{sobjectLabel:sobjectLabel}],
["c:deleteRecordFooter",{record: row, sobjectLabel:sobjectLabel}]
],
function(components, status){
if (status === "SUCCESS") {
modalBody = components[0];
modalFooter = components[1];
cmp.find('overlayLib').showCustomModal({
header: "Delete " + sobjectLabel,
body: modalBody,
footer: modalFooter,
showCloseButton: true
})
}
}
);
},
editRecord : function (cmp, row) {
var createRecordEvent = $A.get("e.force:editRecord");
createRecordEvent.setParams({
"recordId": row.Id
});
createRecordEvent.fire();
},
})
<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId" access="global" controller="SingleRelatedListController">
<aura:attribute name="sobjectApiName" type="String" required="true" />
<aura:attribute name="relatedFieldApiName" type="String" required="true"/>
<aura:attribute name="numberOfRecords" type="Integer" default="6"/>
<aura:attribute name="sortedBy" type="String" required="true"/>
<aura:attribute name="sortedDirection" type="String" default="ASC"/>
<aura:attribute name="onRowActionHandler" type="Aura.Action"/>
<aura:attribute name="customActions" type="List"/>
<aura:attribute name="columns" type="List" />
<aura:attribute name="columnsWithActions" type="List" access="private"/>
<aura:attribute name="fields" type="String" required="true"/>
<aura:attribute name="records" type="Object" access="private"/>
<aura:attribute name="parentRelationshipApiName" type="String" access="private"/>
<aura:attribute name="sobjectLabel" type="String" access="private"/>
<aura:attribute name="sobjectLabelPlural" type="String" access="private"/>
<aura:attribute name="numberOfRecordsForTitle" type="String" access="private"/>
<aura:attribute name="iconName" type="String" access="private"/>
<aura:handler name="init" value="{!this}" action="{!c.init}"/>
<aura:handler name="change" value="{!v.columns}" action="{! c.handleColumnsChange }"/>
<aura:handler event="force:showToast" action="{!c.handleToastEvent}"/>
<lightning:overlayLibrary aura:id="overlayLib"/>
<div class="c-container">
<lightning:card class="slds-card_boundary" iconName="{!v.iconName}">
<aura:set attribute="actions">
<lightning:button label="New" onclick="{!c.handleCreateRecord}"/>
</aura:set>
<aura:set attribute="title">
<b><a class="slds-card__header-link" onclick="{!c.handleGotoRelatedList}">{!(v.sobjectLabelPlural) + ' (' + (v.numberOfRecordsForTitle) + ')'}</a></b>
</aura:set>
<aura:set attribute="footer">
<aura:if isTrue="{!not(empty(v.records))}">
<a onclick="{!c.handleGotoRelatedList}">View All</a>
</aura:if>
</aura:set>
<aura:if isTrue="{!not(empty(v.records))}">
<p class="slds-p-horizontal_small">
<lightning:datatable class="related-list"
columns="{! v.columnsWithActions }"
data="{! v.records }"
keyField="id"
onrowaction="{! c.handleRowAction }"
hideCheckboxColumn="false"
resizeColumnDisabled="true"
maxRowSelection="1"
onrowselection="{! c.selectionAction }"/>
</p>
</aura:if>
</lightning:card>
</div>
</aura:component>
controller
({
init: function (cmp, event, helper) {
helper.fetchData(cmp, event, helper);
helper.initColumnsWithActions(cmp, event, helper)
},
selectionAction: function (cmp, event, helper)
{
var selectedRows = event.getParam('selectedRows'); // fetches the records which are selected by the user
selectedRows ="1"{}
},
handleColumnsChange: function (cmp, event, helper) {
helper.initColumnsWithActions(cmp, event, helper)
},
handleRowAction: function (cmp, event, helper) {
var action = event.getParam('action');
var row = event.getParam('row');
var onRowActionHandler = cmp.get('v.onRowActionHandler');
if(onRowActionHandler){
$A.enqueueAction(onRowActionHandler)
}else{
switch (action.name) {
case 'edit':
helper.editRecord(cmp, row)
break;
case 'delete':
helper.removeRecord(cmp, row)
break;
}
}
},
handleGotoRelatedList : function (cmp, event, helper) {
var relatedListEvent = $A.get("e.force:navigateToRelatedList");
relatedListEvent.setParams({
"relatedListId": cmp.get("v.parentRelationshipApiName"),
"parentRecordId": cmp.get("v.recordId")
});
relatedListEvent.fire();
},
handleCreateRecord : function (cmp, event, helper) {
var createRecordEvent = $A.get("e.force:createRecord");
createRecordEvent.setParams({
"entityApiName": cmp.get("v.sobjectApiName"),
"defaultFieldValues": {
[cmp.get("v.relatedFieldApiName")] : cmp.get("v.recordId")
}
});
createRecordEvent.fire();
},
handleToastEvent : function (cmp, event, helper) {
var eventType = event.getParam('type');
var eventMessage= event.getParam('message');
if(eventType == 'SUCCESS' && eventMessage.includes(cmp.get('v.sobjectLabel'))){
helper.fetchData(cmp, event, helper)
event.stopPropagation();
}
},
})
helper
({
fetchData: function (cmp, event, helper) {
var action = cmp.get("c.initData")
var relatedFieldApiName = cmp.get("v.relatedFieldApiName")
var numberOfRecords = cmp.get("v.numberOfRecords")
var jsonData = JSON.stringify({fields:cmp.get("v.fields"),
relatedFieldApiName:cmp.get("v.relatedFieldApiName"),
recordId:cmp.get("v.recordId"),
numberOfRecords:numberOfRecords + 1,
sobjectApiName: cmp.get("v.sobjectApiName"),
sortedBy: cmp.get("v.sortedBy"),
sortedDirection: cmp.get("v.sortedDirection")
});
action.setParams({jsonData : jsonData});
action.setCallback(this, function(response) {
var state = response.getState();
if (state === "SUCCESS") {
var jsonData = JSON.parse(response.getReturnValue())
var records = jsonData.records
if(records.length > numberOfRecords){
records.pop()
cmp.set('v.numberOfRecordsForTitle', numberOfRecords + "+")
}else{
cmp.set('v.numberOfRecordsForTitle', Math.min(numberOfRecords,records.length))
}
records.forEach(record => {
record.LinkName = '/'+record.Id
for (const col in record) {
const curCol = record[col];
if (typeof curCol === 'object') {
const newVal = curCol.Id ? ('/' + curCol.Id) : null;
helper.flattenStructure(helper,record, col + '_', curCol);
if (newVal !== null) {
record[col+ '_LinkName'] = newVal;
}
}
}
});
cmp.set('v.records', records)
cmp.set('v.iconName', jsonData.iconName)
cmp.set('v.sobjectLabel', jsonData.sobjectLabel)
cmp.set('v.sobjectLabelPlural', jsonData.sobjectLabelPlural)
cmp.set('v.parentRelationshipApiName', jsonData.parentRelationshipApiName)
}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);
},
flattenStructure : function (helper,topObject, prefix, toBeFlattened) {
for (const prop in toBeFlattened) {
const curVal = toBeFlattened[prop];
if (typeof curVal === 'object') {
helper.flattenStructure(helper, topObject, prefix + prop + '_', curVal);
} else {
topObject[prefix + prop] = curVal;
}
}
},
initColumnsWithActions: function (cmp, event, helper) {
var customActions = cmp.get('v.customActions')
if( !customActions.length){
customActions = [
{ label: 'Edit', name: 'edit' },
{ label: 'Delete', name: 'delete' }
]
}
var columns = cmp.get('v.columns')
var columnsWithActions = []
columnsWithActions.push(...columns)
columnsWithActions.push({ type: 'action', typeAttributes: { rowActions: customActions } })
cmp.set('v.columnsWithActions', columnsWithActions)
},
removeRecord: function (cmp, row) {
var modalBody;
var modalFooter;
var sobjectLabel = cmp.get('v.sobjectLabel')
$A.createComponents([
["c:deleteRecordContent",{sobjectLabel:sobjectLabel}],
["c:deleteRecordFooter",{record: row, sobjectLabel:sobjectLabel}]
],
function(components, status){
if (status === "SUCCESS") {
modalBody = components[0];
modalFooter = components[1];
cmp.find('overlayLib').showCustomModal({
header: "Delete " + sobjectLabel,
body: modalBody,
footer: modalFooter,
showCloseButton: true
})
}
}
);
},
editRecord : function (cmp, row) {
var createRecordEvent = $A.get("e.force:editRecord");
createRecordEvent.setParams({
"recordId": row.Id
});
createRecordEvent.fire();
},
})