Lightning datatable with dynamic row action

Lightning data tables are very very common for aura components.

We will see how see can we have different row action name and different behaviour for data table

Here is the query

 List<Resource__c> resourceList = [Select Id,Name,Week__c,Type__c,RecordType.Name,Resource_URL__c,Description__c,Curriculum__c from Resource__c where Curriculum__c IN :curriculumSet  ORDER BY Week__c ASC]; 

List<ResourceRecord> rrList = new List<ResourceRecord>();
for(Resource__c res : resourceList){
                        ResourceRecord rec = new ResourceRecord();
                        rec.resourceName=res.Name;
                        rec.week=res.Week__c;
                        rec.recordId=res.Id;
                        rec.recordtypename=res.recordtype.Name;
                        rec.type=res.Type__c;
                        rec.url=res.Resource_URL__c;
                        rrList.add(rec);                        
                    }
return rrList;

I will only include the relevant section in the aura component for better clarity

Component

 <lightning:datatable data="{!resourceData}"
              columns="{!v.resourceTableColumns}"
              keyField="Id"
              showRowNumberColumn="false"
              onrowaction="{!c.handleRowAction}"
              hideCheckboxColumn="true"/> 

Controller js

doInit : function(component, event, helper) {
        helper.getResourcesData(component);
        helper.setResourceTableColumns(component);

    },
 handleRowAction: function (component, event, helper) {
        var action = event.getParam('action');
        var row = event.getParam('row');
        switch (row.actionLabel) {
            case 'View Record':                             
                helper.getResourceRecord(component,event);
                break;
            case 'Download':                
                helper.downloadResource(component,event);
                break;
            case 'Go to Link':
            
                if(row.url==null || row.url==undefined){
                    helper.showToast("error", "Error!", 'There is no link to show')
                    break;
                }
                var urlEvent = $A.get("e.force:navigateToURL");
                var targetUrl = row.url;
                urlEvent.setParams({
                "url": targetUrl
                });
                urlEvent.fire();
                break;
      }
    },

Helper js

getResourcesData: function(component) {        
        var action = component.get("c.getResourcesData");        
        action.setCallback(this, function(response) {
            var status = response.getState();
            if (status === "SUCCESS") {                
                var resourceData = response.getReturnValue();
                    console.log('resourceData --> '+JSON.stringify(resourceData));                   
                    resourceData = this.prepareDataForTableDisplay(resourceData);                
                    component.set("v.resourceData", resourceData);
            }
            else {
                var errors = response.getError();
                this.handleError(errors);
            }
        });
        $A.enqueueAction(action);
    },
setResourceTableColumns : function(component) {        
        var columns = [
            {label: 'Resource Name', fieldName: 'resourceName', type:'text' },
            {label: 'Type', fieldName: 'type', type:'text' },
            {label: 'Week #', fieldName: 'week', type:'text' },
            {label: 'Action', type: 'button', initialWidth: 150, typeAttributes:
            { label: { fieldName: 'actionLabel' }, name: 'edit_status' , variant: 'base' }}
        ];
        component.set('v.resourceTableColumns', columns);
    },
prepareDataForTableDisplay: function(resourceData){
		let instanceDataToDisplay = [];
        for (let k=0; k<resourceData.length; k++){
                   let instance = resourceData[k];
                   let isUpcomingClass = false;
                   let classInstance = {
                        type: instance.recordtypename,
                        week: instance.week,
                        resourceName: instance.resourceName,
                        url:instance.url,
                        recordId:instance.recordId
                   };
                   switch(instance.recordtypename) {
                    case 'URL':
                        classInstance.actionLabel = 'Go to Link';
                        break;
                    case 'Document':
                        classInstance.actionLabel = 'View Record';
                        break;
                    case 'Download':
                        classInstance.actionLabel = 'Download';
                        break;
                    default:
                        break;
                }

                   instanceDataToDisplay.push(classInstance);
               }
               
        return instanceDataToDisplay;
   },

As you can see in the above code block, I am checking the type of instance record type and based on that the row action labels are changed.

When user clicks the row action , for instance Go to Link, the business logic based on that label and record type will be executed

Permanent link to this article: https://salesforcebuddy.com/2021/03/lightning-datatable-with-dynamic-row-action/

Leave a Reply

Your email address will not be published.