Dynamic Row Actions in Lightning Datatable using Lightning Web Component in Salesforce

Dynamic Row Actions in Lightning Datatable using Lightning Web Component in Salesforce

We can use JavaScript method in action attribute to dynamically assign Row Actions in Lightning Datatable using Lightning Web Component in Salesforce.

Check the following code for example. If the Opportunity Amount is greater than 1000, then it will display View and Edit Actions. Else, it will display just View action.

Sample Code:

Apex Class:
public with sharing class OpportunityController {
    
    @AuraEnabled( cacheable = true )
    public static List < Opportunity > fetchOpptys(){
        
        return [
            SELECT Id, Name, AccountId, Account.Name, Amount
            FROM Opportunity LIMIT 10
        ];
        

    }
}

Lightning Web Component:
HTML:
<template>  
    <lightning-card title="Opportunities" icon-name="custom:custom63">  
        <div class="slds-m-around_medium">  
            <template if:true={availableOpportunities}>      
                <lightning-datatable
                    key-field="Id"
                    data={availableOpportunities}
                    columns={columns}
                    hide-checkbox-column="true"
                    show-row-number-column="true"
                    onrowaction={handleRowAction}>
                </lightning-datatable>  
            </template>      
            <template if:true={error}>  
                {error}>                  
            </template>  
        </div>  
    </lightning-card>
</template>

JavaScript:
import { LightningElement, wire } from 'lwc';
import fetchOpptys from '@salesforce/apex/OpportunityController.fetchOpptys';
import { NavigationMixin } from 'lightning/navigation';
 
const COLUMNS = [
    { label: 'Name', fieldName: 'Name' },
    { label: 'Amount', fieldName: 'Amount', type: 'currency',
    typeAttributes: { maximumFractionDigits: '2' } },
    { label: 'Account Name', fieldName: 'AccountURL', type: 'url',
    typeAttributes: { label: { fieldName: 'AccountName' }, target: '_blank'} }
];

export default class SampleLWC extends NavigationMixin( LightningElement ) {
     
    availableOpportunities;
    error;
    columns = COLUMNS;

    constructor() {
        super();
        this.columns = this.columns.concat( [
            { type: 'action', typeAttributes: { rowActions: this.getRowActions } }
        ] );
    }

    @wire( fetchOpptys )  
    wiredAccount( { error, data } ) {

        if ( data ) {

            let tempRecs = [];
            console.log( 'Fetched Data - ' + JSON.stringify( data ) );
            data.forEach( ( record ) => {

                let tempRec = Object.assign( {}, record );  

                if ( tempRec.AccountId ) {

                    tempRec.AccountName = tempRec.Account.Name;
                    tempRec.AccountURL = '/' + tempRec.AccountId;

                }
                
                tempRecs.push( tempRec );
                
            });
            this.availableOpportunities = tempRecs;
            this.error = undefined;

        } else if ( error ) {

            this.error = error;
            this.availableOpportunities = undefined;

        }

    }

    getRowActions( row, doneCallback ) {

        const actions = [];
        actions.push( {
            'label': 'View',
            'name': 'view'
        } );
        if ( row[ 'Amount' ] > 1000 ) {
            actions.push( {
                'label': 'Edit',
                'name': 'edit'
            } );
        } 
        setTimeout( () => {
            doneCallback( actions );
        }, 200 );

    }
    
    handleRowAction( event ) {

        const actionName = event.detail.action.name;
        const row = event.detail.row;
        switch ( actionName ) {
            case 'view':
                this[NavigationMixin.Navigate]({
                    type: 'standard__recordPage',
                    attributes: {
                        recordId: row.Id,
                        actionName: 'view'
                    }
                });
                break;
            case 'edit':
                this[NavigationMixin.Navigate]({
                    type: 'standard__recordPage',
                    attributes: {
                        recordId: row.Id,
                        objectApiName: 'Opportunity',
                        actionName: 'edit'
                    }
                });
                break;
            default:
        }

    }

}

JS-meta.xml:
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__Tab</target>
    </targets>
</LightningComponentBundle>

Output:

Leave a Reply