6

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

  }
}
  • Share the current UI as well. – itzmukeshy7 Mar 27 '18 at 1:46
  • Commenting to follow. Could be useful to me too. – Charles T Mar 27 '18 at 1:59
  • Added my screenshot. @itzmukeshy7 – Guha Arumugam Mar 27 '18 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; – itzmukeshy7 Mar 27 '18 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 '18 at 3:51
5

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 */
})
  • 1
    Thanks so much @itzmukeshy7 That worked like a charm. Except that i changed my formula of the field to => "/"&id. – Guha Arumugam Mar 27 '18 at 14:47
  • 1
    Yes that I missed to mention here. :) – itzmukeshy7 Mar 27 '18 at 15:00
  • @itzmukeshy7 how did you hid the Name column? – sebascanseco Jan 21 at 22:44
  • @sebascanseco I didn't hide any column, can you please explain what you want to achieve? – itzmukeshy7 Jan 22 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. – sebascanseco Jan 22 at 21:29
0

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

  • 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 at 12:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.