Am trying to accomplish a POC in my project. We have a lightning Datatable using . I could generate a set of records to display on the component. But I need one column to be hyperlinked to navigate to the corresponding record when I click on them. The data table fields and object is passed dynamically at runtime either from Community Page/App Builder page/ Some Lightning container components.
Problem:
I couldn’t figure out a way to make the first column as hyperlinked. I tried to work around by creating a formula field with HYPERLINK(“/” &Id, “View Record”). But it generates this(Ref My Screenshot) on the data table in UI. If anyone can help with some workaround?
Component:
<aura:component controller="lightningTableController" implements="flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,force:appHostable" access="global" > <aura:attribute name="title" type="string" default="My Interations" /> <aura:attribute name="recLimit" type="String" default="10" /> <aura:attribute name="object" type="string" default="Case" /> <aura:attribute name="fields" type="String" default="RecIdURL__c,FSA_BTO_Date_Of_Service__c,Subject,Type,FSA_BTO_Service_Requested__c" /> <aura:attribute name="sortedBy" type="string" default="FSA_BTO_Date_Of_Service__c" /> <aura:attribute name="sortedDirection" type="string" default="DESC" /> <aura:attribute name="mydata" type="object" /> <aura:attribute name="mycolumn" type="object" /> <aura:handler name="init" value="{!this}" action="{!c.init}" /> <lightning:card title="{!v.title}" > <lightning:datatable data="{!v.mydata}" columns="{!v.mycolumn}" onsort="{!c.updateColumnSorting}" sortedBy="{!v.sortedBy}" sortedDirection="{!v.sortedDirection}" hideCheckboxColumn="true" onrowselection="{!c.getSelectedName}" keyField="Id" /> </lightning:card>
Controller.JS:
({ init : function(component, event, helper) { helper.getLightningTableData(component); }, updateColumnSorting: function (cmp, event, helper) { var fieldName = event.getParam('fieldName'); var sortDirection = event.getParam('sortDirection'); cmp.set("v.sortedBy", fieldName); cmp.set("v.sortedDirection", sortDirection); helper.sortData(cmp, fieldName, sortDirection); }, getSelectedName: function (component, event) { var selectedRows = event.getParam('selectedRows'); for (var i = 0; i < selectedRows.length; i++){ console.log('>>>',selectedRows[i].Subject); } } })
Helper.JS
({ getLightningTableData : function(component) { var recLimit = component.get("v.recLimit"); var sColumn = component.get("v.fields"); var sObject = component.get("v.object"); var action = component.get("c.getsObjectRecords"); action.setParams({ ObjectName : sObject, fieldstoget : sColumn, recLimit : recLimit }); action.setCallback(this,function(response){ var state = response.getState(); if(state == 'SUCCESS'){ var rtnValue = response.getReturnValue(); component.set("v.mycolumn",rtnValue.tableColumn); component.set("v.mydata",rtnValue.tableRecord); } }); $A.enqueueAction(action); }, sortData: function (cmp, fieldName, sortDirection) { var data = cmp.get("v.mydata"); var reverse = sortDirection !== 'asc'; data.sort(this.sortBy(fieldName, reverse)) cmp.set("v.mydata", data); }, sortBy: function (field, reverse, primer) { var key = primer ? function(x) {return primer(x[field])} : function(x) {return x[field]}; reverse = !reverse ? 1 : -1; return function (a, b) { return a = key(a), b = key(b), reverse * ((a > b) - (b > a)); } } })
Design:
<design:component > <design:attribute name="title" label="Header Title" description="Title for the data table" /> <design:attribute name="object" label="Object API Name" description="API Name of the Object" /> <design:attribute name="fields" label="Fields API Name" /> <design:attribute name="recLimit" label="Number of Records to Display" description="Limit value for SOQL"/>
APEX:
public with sharing class lightningTableController { @AuraEnabled public static lightningTableWraper getsObjectRecords(String ObjectName,String fieldstoget,Integer recLimit){ List<String> lstfieldstoget = fieldstoget.split(','); List<lightningTableColumnWrapper> lstTableColumn = new list<lightningTableColumnWrapper> (); DescribeSObjectResult objResult = Schema.getGlobalDescribe().get(ObjectName).getDescribe(); for(String field : lstfieldstoget){ lightningTableColumnWrapper colWrapper = new lightningTableColumnWrapper(); DescribeFieldResult fieldResult = objResult.fields.getMap().get(field).getDescribe(); colWrapper.label = fieldResult.getLabel(); colWrapper.fieldName = fieldResult.getName(); colWrapper.type = String.valueof(fieldResult.getType()).toLowerCase(); colWrapper.sortable = true; lstTableColumn.add(colWrapper); } Id loggedUser = UserInfo.getUserId(); String queryString = 'Select '+ String.escapeSingleQuotes(String.join(lstfieldstoget,','))+ ' from '+ String.escapeSingleQuotes(ObjectName) + ' Limit ' +recLimit; LightningTableWraper ltngTableWrapper = new LightningTableWraper(); ltngTableWrapper.tableRecord = database.query(queryString); ltngTableWrapper.tableColumn = lstTableColumn; return ltngTableWrapper; } public class lightningTableColumnWrapper { @AuraEnabled public string label {get;set;} @AuraEnabled public String fieldName {get;set;} @AuraEnabled public string type {get;set;} @AuraEnabled public boolean sortable {get;set;} } public class lightningTableWraper{ @AuraEnabled public List<sObject> tableRecord {get;Set;} @AuraEnabled public List<lightningTableColumnWrapper> tableColumn {get;set;} } }
Answer
We can take help of the type: url
and typeAttributes: {label: { fieldName: 'linkLabel' }}
to show some useful link label of the column;
Working with Column Data
Here we have two options
type
possible values are(action, …, url);typeAttributes
value depends on thetype
option value like for url we have (label, target);
Here is the example of the same: lightning:datatable
Below is the example of the options:
And we can also do this type adjustment just before assigning the columns settings to the attribute in the helper(if not want to do in the Apex):
({
getLightningTableData: function (component) {
var recLimit = component.get('v.recLimit');
var sColumn = component.get('v.fields');
var sObject = component.get('v.object');
var action = component.get('c.getsObjectRecords');
action.setParams({
ObjectName: sObject,
fieldstoget: sColumn,
recLimit: recLimit
});
action.setCallback(this, function (response) {
var state = response.getState();
if (state === 'SUCCESS') {
var rtnValue = response.getReturnValue();
rtnValue.tableColumn.forEach(function (column) {
switch (column.fieldName) {
case 'Show_Record__c':
column.type = 'url';
column['typeAttributes'] = { label: { fieldName: 'Name' } };
break;
default:
break;
}
});
component.set('v.mycolumn', rtnValue.tableColumn);
component.set('v.mydata', rtnValue.tableRecord);
}
});
$A.enqueueAction(action);
},
/* more methods */
})
Attribution
Source : Link , Question Author : Guha Arumugam , Answer Author : itzmukeshy7