11

enter image description here

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;}

  }
}
5
  • Share the current UI as well. Mar 27, 2018 at 1:46
  • Commenting to follow. Could be useful to me too.
    – Charles T
    Mar 27, 2018 at 1:59
  • Added my screenshot. @itzmukeshy7 Mar 27, 2018 at 2:25
  • 2
    Here you can take help of the type: 'url' and typeAttributes: {label: { fieldName: 'linkLabel' }} to show some useful link label of the column; Mar 27, 2018 at 3:25
  • 1
    @itzmukeshy7 This is the answer I would have given. Perhaps you might want to fill in some extra details and make it official?
    – sfdcfox
    Mar 27, 2018 at 3:51

2 Answers 2

10

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

  1. type possible values are(action, ..., url);
  2. typeAttributes value depends on the type 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:

Type and type attributes usage

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 */
})
5
  • 1
    Thanks so much @itzmukeshy7 That worked like a charm. Except that i changed my formula of the field to => "/"&id. Mar 27, 2018 at 14:47
  • 1
    Yes that I missed to mention here. :) Mar 27, 2018 at 15:00
  • @itzmukeshy7 how did you hid the Name column? Jan 21, 2019 at 22:44
  • @sebascanseco I didn't hide any column, can you please explain what you want to achieve? Jan 22, 2019 at 11:51
  • @itzmukeshy7 never mind. I missed the Account Name it's been shown in your example. This is a great explanation, but I was wondering if there's a way to hide the Account Name column as it's redundant with the first column. Jan 22, 2019 at 21:29
2

Similar answer here:

component.set('v.columns', [
        {label: 'Header Name', fieldName: 'Link', type: 'url',
        typeAttributes: {label: { fieldName: 'Name' }, target: '_blank'}},
        ]);

Source: http://www.infallibletechie.com/2018/07/how-to-hyperlink-record-in.html

2
  • please elaborate on your answer, otherwise, it might be considered a code dump, which is of no rea value on this forum. While you are ate it, please take a moment to read How to Ask, thanks
    – glls
    May 11, 2019 at 12:47
  • This is a good answer because it shows the exact JSON required to add typeAttributes to the column definition, which seems to be missing from the Salesforce data table docs.
    – Shanerk
    Dec 9, 2020 at 19:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .