Reading Time: 3 minutes

Result
![]()
Lightning Component
Create the component thus:
![]()
<aura:component implements="force:appHostable"
controller="OpportunitiesTabController">
<aura:attribute name="data" type="Object"/>
<aura:attribute name="columns" type="List"/>
<aura:handler name="init" value="{! this <}" action="{! c.doInit }"/>
<article class="slds-card slds-p-bottom_x-small">
<div class="slds-card__body slds-card__body_inner">
<div class="slds-m-top_x-small">
<lightning:button
aura:id="refresh"
label="Refresh"
title="Refresh"
onclick="{!c.doInit}"
/>
</div>
<div class="slds-text-heading_medium slds-m-top_x-small">Opportunities</div>
<lightning:datatable
columns="{! v.columns }"
data="{! v.data }"
keyField="id"
onrowaction="{! c.handleRowAction }"/>
</div>
</article>
</aura:component>
JS controller
({
doInit : function(component, event, helper) {
helper.loadOpportunities(component);
},
handleRowAction: function (component, event, helper) {
var action = event.getParam('action');
var row = event.getParam('row');
switch (action.name) {
case 'toLowerCase':
helper.execute(component, row.Id, 'c.toLowerCase');
break;
case 'toUpperCase':
helper.execute(component, row.Id, 'c.toUpperCase');
break;
}
},
})
JS helper
({
execute : function(component, opptyId, method) {
console.info('executing: '+method + ' oppty id: '+opptyId)
const action = component.get(method);
action.setParams({
opptyId: opptyId
});
action.setCallback(this, function(response) {
const state = response.getState();
if (state === "SUCCESS") {
console.info(method+' done');
this.loadOpportunities(component);
}else {
console.error(" Error: " + JSON.stringify(response.getError()));
alert(JSON.stringify(response.getError()));
}
});
$A.enqueueAction(action);
},
loadOpportunities : function(component) {
console.info('loading opportunities')
const actions = [{ label: 'To Lower Case', name: 'toLowerCase' },
{ label: 'To Upper Case', name: 'toUpperCase' }];
component.set('v.columns', [
{ label: 'Name', fieldName: 'linkName', type: 'url',
typeAttributes:{label:{fieldName: 'Name'}} },
{ label: 'Account', fieldName: 'linkAccount', type: 'url',
typeAttributes:{label:{fieldName: 'nameAccount'}} },
{ label: 'Stage Name', fieldName: 'StageName', type: 'text' },
{ label: 'Created Date', fieldName: 'CreatedDate', type: 'datetime' },
{ type: 'action', typeAttributes: { rowActions: actions } }
]);
const action = component.get("c.getOpportunities");
action.setCallback(this, function(response) {
const state = response.getState();
if (state === "SUCCESS") {
console.info(" opportunities loaded");
const records = response.getReturnValue();
records.forEach(function(record){
record.linkName = '/'+record.Id;
if(record.Account){
record.linkAccount = '/'+record.AccountId;
record.nameAccount = record.Account.Name
} else {
record.linkAccount = '/#';
record.nameAccount = 'no account';
}
});
component.set('v.data', records);
}else {
console.error(" Error: " + JSON.stringify(response.getError()));
}
});
$A.enqueueAction(action);
},
})
Apex class controller
public class OpportunitiesTabController {
@AuraEnabled
public static void toLowerCase(Id opptyId){
try{
Opportunity opp = [SELECT Id, Name FROM Opportunity WHERE Id = :opptyId];
opp.Name = opp.Name.toLowerCase();
update opp;
}catch(Exception e){
throw new AuraException(e.getMessage());
}
}
@AuraEnabled
public static void toUpperCase(Id opptyId){
try{
Opportunity opp = [SELECT Id, Name FROM Opportunity WHERE Id = :opptyId];
opp.Name = opp.Name.toUpperCase();
update opp;
}catch(Exception e){
throw new AuraException(e.getMessage());
}
}
@AuraEnabled
public static List<Opportunity> getOpportunities(){
return [SELECT Id, Name, StageName, CreatedDate, Account.Name, AccountId
FROM Opportunity ORDER BY CreatedDate DESC LIMIT 10];
}
}
Add a tab with our component
![]()
![]()