How to Add Hyperlink and icons in Lightning:datatable

Lightning, Lightning Component, Lightning Tutorials, Lightning Web Components

Hey Everyone,

Welcome again. In this blog post, we are going to learn how we can add hyperlink in datatable and how to add custom icons based on some conditions in lightning datatable

Use Case: – Business wants to display the list of top 10 cases in a datatable. There are few catches here that are given below

  1. CaseNumber & Subject Field must be hyperlink and when click on those it should redirect to case detail page.
  2. Contact Name & Account Name field also should be hyperlink field and clicking on it should redirect to contact or account record.
  3. An icon should be displayed left to priority field and icon should be changed based on priority.

Now, as we have got the use case. Let’s see what all it will take to develop.

  1. An Apex class
  2. Lightning Web Component

Before we directly jump into the final outcome, we will break the requirement into multiple steps. So, let’s create the apex class first.

Use below code and Name it as CaseLWCService

public with sharing class CaseLWCService {
    @AuraEnabled
    public static List<Case> fetchCases(){
        return [SELECT Id, CaseNumber, Subject, Description, AccountId, Account.Name, ContactId,
        Contact.Name, Status, Priority 
        FROM CASE
        LIMIT 10];
    }
}

We have got our apex class which will return the Top10 Case records.

Now, let’s develop the component which will be using Lightning:datatable for displaying the records. Use below code for .html file

<template>
    <lightning-card  variant="Narrow"  title="Case List" icon-name="standard:case">
        <div class="slds-m-around_small">
            <lightning-datatable
                key-field="id"
                data={result}
                show-row-number-column
                hide-checkbox-column
                columns={columnsList}
                onrowaction={handleRowAction}>
            </lightning-datatable>
        </div>
    </lightning-card>
</template>

We have got the UI part, however we need to have the associated JavaScript class so that we can pull the data from Apex Class and that data can be displayed into component. Below is the code for the JS Class.

import { LightningElement, wire, api, track } from 'lwc';
import fetchCases from '@salesforce/apex/CaseLWCService.fetchCases';

const columns = [
    { label: 'CaseNumber', fieldName: 'CaseNumber' },
    { label: 'Subject', fieldName: 'Subject', wrapText: true},
    { label: 'Status', fieldName: 'Status' },
    { label: 'Priority', fieldName: 'Priority' },
    { label: 'Contact', fieldName: 'ContactName', wrapText: true },
    { label: 'Account', fieldName: 'AccountName', wrapText: true }
];
export default class CaseDatatable extends LightningElement {
    
    @api result;
    @track error;

    columnsList = columns;
    
    connectedCallback(){
        this.getAllCaseDetails();
    }

    getAllCaseDetails(){
        fetchCases()
            .then(data => {
                /* Iterate with Each record and check if the Case is Associated with Account or Contact
                    then get the Name and display into datatable
                */
                data.forEach(caseRec => {
                    if(caseRec.ContactId){
                        caseRec.ContactName = caseRec.Contact.Name;
                    }
                    if(caseRec.AccountId){
                        caseRec.AccountName = caseRec.Account.Name;
                    }
                });
                this.result = data;
                window.console.log(' data ', data);
                this.error = undefined;
            })
            .catch(error => {
                this.error = error;
                window.console.log(' error ', error);
                this.result = undefined;
            });
    }
    
    handleRowAction(){
        
    }
}

and below is the code for meta file

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>48.0</apiVersion>
    <isExposed>true</isExposed>
    <masterLabel>Case Details</masterLabel>
    <targets>
        <target>lightning__RecordPage</target>
        <target>lightning__AppPage</target>
        <target>lightning__HomePage</target>
        <target>lightningCommunity__Page</target>
        <target>lightningCommunity__Default</target>
    </targets>
</LightningComponentBundle>

We have developed the component and displayed the case list into datatable. However, we are still remaining with few point. If you will see the output of the above component will look like below

If you notice the above screenshot, there is no hyperlink shown for any of the fields which were mentioned in the use case.

Let’s modify the columns of datatable to display the link.

We are going to use same column which is CaseNumber and Subject. To display the url what we need to do is specify the type for the column like below

{ label: 'CaseNumber', fieldName: 'CaseNumber', type:'url' },

However, doing this will not work. What we need to do is to add some attributes in the same column under typeAttributes so that we can specify the text which we wanted to display. See code below, inside typeAttributes we can specify the target as well and many more. Learn Here

typeAttributes: {
           label: { fieldName: 'CaseNumber' },
           target : '_blank'
       }

Now, if we merge the code it will look like below

{ 
        label: 'CaseNumber', fieldName: 'CaseNumber', type:'url',
        typeAttributes: {
            label: { 
                fieldName: 'CaseNumber' 
            },
            target : '_blank'
        }
    },

We have prepared the column and there is one more thing remaining which is the actual URL. As if you noticed on the above code we are using CaseNumber in both places and the record details url look like below

https://+host+/+recordId

So, we have to prepare the URL and a new field so that we can use that new field in place of CaseNumber in the first place of fieldName: ‘CaseNumber’, type:’url’,

We will follow the same approach for the rest 3 fields ( Subject, Contact Name & Account Name). That means we will be needing 3 New fields which will contain the record detail page Link.

Now, here is the update code for JavaScript Class with URL/HyperLink in Datatable

import { LightningElement, wire, api, track } from 'lwc';
import fetchCases from '@salesforce/apex/CaseLWCService.fetchCases';

const columns = [
    { 
        label: 'CaseNumber', fieldName: 'caseUrl', type:'url',
        typeAttributes: {
            label: { 
                fieldName: 'CaseNumber' 
            },
            target : '_blank'
        }
    },
    { 
        label: 'Subject', fieldName: 'caseUrl', wrapText: true,
        type: 'url',
        typeAttributes: {
            label: { 
                fieldName: 'Subject' 
            },
            target : '_blank'
        }
    },
    { label: 'Status', fieldName: 'Status' },
    { label: 'Priority', fieldName: 'Priority' },
    { 
        label: 'Contact', fieldName: 'ContactUrl', wrapText: true,
        type: 'url',
        typeAttributes: {
            label: { 
                fieldName: 'ContactName' 
            },
            target : '_blank'
        } 
    },
    { 
        label: 'Account', fieldName: 'AccountUrl', wrapText: true,
        type: 'url',
        typeAttributes: {
            label: { 
                fieldName: 'AccountName' 
            },
            target : '_blank'
        } 
    }
];
export default class CaseDatatable extends LightningElement {
    
    @api result;
    @track error;

    columnsList = columns;
    
    connectedCallback(){
        this.getAllCaseDetails();
    }

    getAllCaseDetails(){
        fetchCases()
            .then(data => {
                /* Iterate with Each record and check if the Case is Associated with Account or Contact
                    then get the Name and display into datatable
                */
                /* Prepare the Org Host */
                let baseUrl = 'https://'+location.host+'/';
                data.forEach(caseRec => {
                    caseRec.caseUrl = baseUrl+caseRec.Id;
                    if(caseRec.ContactId){
                        caseRec.ContactName = caseRec.Contact.Name;
                        /* Prepare Contact Detail Page Url */
                        caseRec.ContactUrl = baseUrl+caseRec.ContactId;
                    }
                    if(caseRec.AccountId){
                        caseRec.AccountName = caseRec.Account.Name;
                        /* Prepare Account Detail Page Url */
                        caseRec.AccountUrl = baseUrl+caseRec.AccountId;
                    }
                });
                this.result = data;
                window.console.log(' data ', data);
                this.error = undefined;
            })
            .catch(error => {
                this.error = error;
                window.console.log(' error ', error);
                this.result = undefined;
            });
    }
    
    handleRowAction(){
        
    }
}

If you will preview the code, you will see the screen like below

We are done with 75% of the requirement however still we need to display the icons next to Priority based on priority. For this, we need to use cellAttributes property of the datatable column instead of typeattributes.

Let;s see how to display the icon and we can get the icons from here

{
        label: 'Priority', fieldName: 'Priority',
        cellAttributes: { 
            iconName: 'utility:sentiment_negative', 
            iconAlternativeText: 'Priority' 
        }
    },

If you have noticed, we are using icon name which is static and will display the same icon. So to display the icon dynamically we need to generate the icon in JS and use like below

{
        label: 'Priority', fieldName: 'Priority',
        cellAttributes:{ 
            iconName: { 
                fieldName: 'priorityIcon' 
            },
            iconPosition: 'left', 
            iconAlternativeText: 'Priority Icon' 
        }
    },

Below is the complete code for the blog

If you will preview the code you will see the output like below

Thanks for Reading. Sharing is Caring 🙂

If you have any questions or suggestions, please feel free to reach out to me.