• Juan García
  • NEWBIE
  • 30 Points
  • Member since 2016

  • Chatter
    Feed
  • 0
    Best Answers
  • 1
    Likes Received
  • 0
    Likes Given
  • 4
    Questions
  • 7
    Replies
I have a table for create expenses. The table shows 3columns (a picklist, a decimal, and a text). I create a ui:inputSelect for the picklist. The table load the values of picklist, and save the value, but not show the data of the data base (always show --None--). How can I load the data os records??
Thanks

Component
<aura:handler name="init" action="{!c.doInit}" value="{!this}" />
<aura:handler event="force:refreshView" action="{!c.doInit}" />

<aura:attribute name="expenses" type="Expenses__c[]"/>
<aura:attribute name="options" type="String[]" />
<aura:attribute name="selectedValue" type="String"/>

<ltng:require styles="/resource/slds_resource/assets/styles/salesforce-lightning-design-system.css?v=1" />
<div class="slds">
    <div class="slds-page-header noborderbottom" role="banner"> 
        <div class="slds-grid">
            <div class="slds-col slds-has-flexi-truncate">
                <div class="slds-media slds-no-space slds-grow">
                    <div class="slds-media__figure">
                        <lightning:icon iconName="custom:custom17" size="large" alternativeText="Indicates approval"/>
                    </div>
                    <div class="slds-media__body">
                        <p class="slds-text-title_caps slds-line-height_reset">Expenses</p>
                        <h1 class="slds-page-header__title slds-m-right_small slds-align-middle slds-truncate" title="My Expenses">My expenses</h1>
                    </div>
                    <lightning:button class="slds-float_right" iconName="utility:refresh" onclick="{!c.refreshTable}" label="Refresh"/>
                    <lightning:button class="slds-float_right" iconName="utility:add" onclick="{!c.addRow}" label="Create expense"/>
                    <lightning:button class="slds-float_right" iconName="utility:clear" onclick="{!c.removeRow}" label="Delete expense"/>
                </div>
            </div>
        </div>
    </div>   
</div>

<div class="slds" style="overflow-x:auto;">
    <table class="slds-table slds-table--bordered slds-table--cell-buffer slds-max-medium-table--stacked-horizontal">
        <thead>
            <tr class="slds-text-heading--label">
                <th scope="col" class="nobordertop" title="Type">
                    <div>Type</div>
                </th>
                <th scope="col" class="nobordertop" title="Import">
                    <div>Import</div>
                </th>
                <th scope="col" class="{nobordertop'}" title="Description">
                    <div>Description</div>
                </th>
            </tr>
        </thead>
        <tbody>
            <aura:iteration items="{!v.expenses}" var="expenses">
                <tr>
                    <td data-label="{!expenses.PL_Expenses__c}" title="{!expenses.PL_Expenses__c}">
                        <div>
                            <ui:inputSelect aura:id="acc" required="true" value="{!expenses.PL_Expenses__c}">
                                <ui:inputSelectOption text="" label="--None--" />
                                <aura:iteration items="{!v.options}" var="ac">
                                    <ui:inputSelectOption text="{!ac}" label="{!ac}"/>
                                </aura:iteration>
                            </ui:inputSelect>
                        </div>
                    </td>
                    <td data-label="{!expenses.Import__c}" title="{!expenses.Import}">
                        <div><ui:inputNumber class="slds-input" value="{!expenses.Import__c}"/></div>
                    </td>
                    <td data-label="{!expenses.Description__c}" title="{!expenses.Description}">
                        <div><ui:inputText class="slds-input" value="{!expenses.Description}"/></div>
                    </td>
                </tr>
            </aura:iteration>
        </tbody>
    </table> 
    <lightning:button class="slds-align_absolute-center slds-button slds-button_brand slds-m-top_small" onclick="{!c.save}" label="Save"/>
</div>

Controller and helper
doInit : function(component, event, helper) {       
    helper.getExpenses(component, helper, event);
},

//Fetch the expenses from the Apex controller
getExpenses: function(component, helper, event) {
    var action = component.get("c.getAllDesgloseCoste");
    action.setParams({opportunityId: component.get('v.recordId')});   
    //Set up the callback
    action.setCallback(this, function(actionResult) {
        component.set("v.expenses", actionResult.getReturnValue());
        this.fetchPickListVal(component, helper, event);
    }); 
    $A.enqueueAction(action);  
},


Controller - apex
@AuraEnabled
public static list<Expenses__c> getAllDesgloseCoste(Id opportunityId){
    return [SELECT Name, PL_Expenses__c, Import__c , Description__c 
            FROM Expenses__c
            WHERE Opportunity__c =:opportunityId];
}

@AuraEnabled
public static List<String> getPickListValuesIntoList(){
    List<String> pickListValuesList= new List<String>();
    Schema.DescribeFieldResult fieldResult = Expenses__c.PL_Expenses__c.getDescribe();
    List<Schema.PicklistEntry> ple = fieldResult.getPicklistValues();
    for( Schema.PicklistEntry pickListVal : ple){
        pickListValuesList.add(pickListVal.getLabel());
    }    
    return pickListValuesList;
}

User-added image
Hi,

I have a doubt creating a lightning datatable. Can I edit the columns doing double click ?
I only can edit the data clicking to the edit icon. In standard List View, we can edit the value doing double click anywhere in the column.

User-added image

Thanks
Hi,

I have a datatable, and I need a text column with hiperlink to the reference object.
I want a similar table to a standard list view, the name of the column record is a hiperlink of the record page

Example:
List view of a record:
User-added image

Datatable with a colum type url
User-added image

Datatable with a colum type text
User-added image

Code:
cmp.set('v.columns', [
            {label: 'Recurso', fieldName: 'Name', type: 'url', sortable: true, editable:'true', initialWidth: 120},
        ]);

Thanks
Hi Devs,

I have some problems with a component that is going to be using a <lightning:datatable /> object.
There are data not visible, and the ddbb this values are filled. This values not load in the table.
Name is ok, the table can be editabled, and the sort works, but values not load (the fields are number, 16 with 2decimals). If I click on the column, show the value, but if I dont click, the value not is shown)
Thanks

Component:
<aura:component controller="TCK_DesglCoste_ByOpp_Ctr"
                implements="force:hasRecordId,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,lightning:actionOverride,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:appHostable"
                access="global" >
    
    <!-- handlers-->
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    <aura:handler event="force:refreshView" action="{!c.doInit}" />
    
    <!-- attributes -->
    <aura:attribute name="columnsDesglose" type="List"/>
    <aura:attribute name="desgloseCosteList" type="Desglose_Coste__c[]"/>
    <aura:attribute name="sortedBy" type="String" default="Name"/>
    <aura:attribute name="sortedDirection" type="String" default="asc"/>
    
    <div class="slds-page-header">
        <div class="slds-grid">
            <div class="slds-col slds-has-flexi-truncate">
                <div class="slds-media slds-no-space slds-grow">
                    <div class="slds-media__figure">
                        <lightning:icon iconName="custom:custom105" size="large" alternativeText="Indicates approval"/>
                    </div>
                    <div class="slds-media__body">
                        <p class="slds-text-title_caps slds-line-height_reset">Object</p>
                        <h1 class="slds-page-header__title slds-m-right_small slds-align-middle slds-truncate" title="My Contacts">My object</h1>
                    </div>
                </div>
            </div>
        </div>
    </div>
    
    <lightning:datatable
                         aura:id="desgloseCosteDataTable"
                         columns="{! v.columnsDesglose }"
                         data="{! v.desgloseCosteList }"
                         keyField="Id"
                         hideCheckboxColumn="true"
                         onsort="{!c.updateColumnSorting}"
                         sortedBy="{!v.sortedBy}"  
                         sortedDirection="{!v.sortedDirection}"
                         onsave ="{!c.onSave}"
                         onrowaction="{! c.handleRowAction }"
                         />
    
</aura:component>
Controller, helper and CTR
Controler:
({
    doInit : function(cmp, event, helper) {
        cmp.set('v.columnsDesglose', [
            {label: 'Name', fieldName: 'Name', type: 'text', sortable: true, editable:'true'},
            {label: 'Month 1', fieldName: 'Mes_1__c', type: 'double', sortable: true, editable:'true'},
            {label: 'Month 2', fieldName: 'Mes_2__c', type: 'double', sortable: true, editable:'true'},
            {label: 'Month 3', fieldName: 'Mes_3__c', type: 'double', sortable: true, editable:'true'},
            {label: 'Month 4', fieldName: 'Mes_4__c', type: 'double', sortable: true, editable:'true'},
            {label: 'Month 5', fieldName: 'Mes_5__c', type: 'double', sortable: true, editable:'true'},
        ]);
            
            helper.loadDesglose(cmp, helper);
            
            },
            
    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);
            },
            
    onSave : function (component, event, helper) {
            helper.saveDataTable(component, event, helper);
            },
            
})

__________
helper:
({
    loadDesglose : function(cmp, helper) {
        var action = cmp.get("c.getAllDesgloseCoste");
        action.setParams({opportunityId: cmp.get('v.recordId')});   
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                cmp.set("v.desgloseCosteList", response.getReturnValue());
                helper.sortData(cmp, cmp.get("v.sortedBy"), cmp.get("v.sortedDirection"));
            }
        });
        $A.enqueueAction(action);
    },
    
    sortData: function (cmp, fieldName, sortDirection) {
        var data = cmp.get("v.desgloseCosteList");
        var reverse = sortDirection !== 'asc';
        data.sort(this.sortBy(fieldName, reverse))
        cmp.set("v.desgloseCosteList", 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));
        }
    },
    
    saveDataTable : function(component, event, helper) {
        var editedRecords =  component.find("desgloseCosteDataTable").get("v.draftValues");
        var totalRecordEdited = editedRecords.length;
        var action = component.get("c.updateDesgloseCoste");
        action.setParams({
            'editedDesglCosteList' : editedRecords
        });
        action.setCallback(this,function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                //if update is successful
                if(response.getReturnValue() === true){
                    helper.showToast({
                        "title": "Record Update",
                        "type": "success",
                        "message": totalRecordEdited+" Registros actualizados"
                    });
                    helper.reloadDataTable();
                } else{ //if update got failed
                    helper.showToast({
                        "title": "Error!!",
                        "type": "error",
                        "message": "Error en la actualización"
                    });
                }
            }
        });
        $A.enqueueAction(action);
    },

    /*
     * Show toast with provided params
     * */
    showToast : function(params){
        var toastEvent = $A.get("e.force:showToast");
        if(toastEvent){
            toastEvent.setParams(params);
            toastEvent.fire();
        } else{
            alert(params.message);
        }
    },

    /*
     * reload data table
     * */
    reloadDataTable : function(){
    var refreshEvent = $A.get("e.force:refreshView");
        if(refreshEvent){
            refreshEvent.fire();
        }
    },
    
})


__________
CTR:
    @AuraEnabled
    public static list<Desglose_Coste__c> getAllDesgloseCoste(Id opportunityId){
        return [SELECT Name, Mes_1__c, Mes_2__c, Mes_3__c, Mes_4__c, Mes_5__c, Mes_6__c, Mes_7__c, Mes_8__c, Mes_9__c, Mes_10__c, Mes_11__c, Mes_12__c,
                Opportunity__c, Opportunity__r.Name, LastModifiedById
                FROM Desglose_Coste__c
                WHERE Opportunity__c =:opportunityId];
    }
    
    @AuraEnabled
    public static boolean updateDesgloseCoste(List<Desglose_Coste__c> editedDesglCosteList){
        try{
            system.debug('Total de registros: ' + editedDesglCosteList);
            update editedDesglCosteList;
            return true;
        } catch(Exception e){
            return false;
        }
    }



 
I have a table for create expenses. The table shows 3columns (a picklist, a decimal, and a text). I create a ui:inputSelect for the picklist. The table load the values of picklist, and save the value, but not show the data of the data base (always show --None--). How can I load the data os records??
Thanks

Component
<aura:handler name="init" action="{!c.doInit}" value="{!this}" />
<aura:handler event="force:refreshView" action="{!c.doInit}" />

<aura:attribute name="expenses" type="Expenses__c[]"/>
<aura:attribute name="options" type="String[]" />
<aura:attribute name="selectedValue" type="String"/>

<ltng:require styles="/resource/slds_resource/assets/styles/salesforce-lightning-design-system.css?v=1" />
<div class="slds">
    <div class="slds-page-header noborderbottom" role="banner"> 
        <div class="slds-grid">
            <div class="slds-col slds-has-flexi-truncate">
                <div class="slds-media slds-no-space slds-grow">
                    <div class="slds-media__figure">
                        <lightning:icon iconName="custom:custom17" size="large" alternativeText="Indicates approval"/>
                    </div>
                    <div class="slds-media__body">
                        <p class="slds-text-title_caps slds-line-height_reset">Expenses</p>
                        <h1 class="slds-page-header__title slds-m-right_small slds-align-middle slds-truncate" title="My Expenses">My expenses</h1>
                    </div>
                    <lightning:button class="slds-float_right" iconName="utility:refresh" onclick="{!c.refreshTable}" label="Refresh"/>
                    <lightning:button class="slds-float_right" iconName="utility:add" onclick="{!c.addRow}" label="Create expense"/>
                    <lightning:button class="slds-float_right" iconName="utility:clear" onclick="{!c.removeRow}" label="Delete expense"/>
                </div>
            </div>
        </div>
    </div>   
</div>

<div class="slds" style="overflow-x:auto;">
    <table class="slds-table slds-table--bordered slds-table--cell-buffer slds-max-medium-table--stacked-horizontal">
        <thead>
            <tr class="slds-text-heading--label">
                <th scope="col" class="nobordertop" title="Type">
                    <div>Type</div>
                </th>
                <th scope="col" class="nobordertop" title="Import">
                    <div>Import</div>
                </th>
                <th scope="col" class="{nobordertop'}" title="Description">
                    <div>Description</div>
                </th>
            </tr>
        </thead>
        <tbody>
            <aura:iteration items="{!v.expenses}" var="expenses">
                <tr>
                    <td data-label="{!expenses.PL_Expenses__c}" title="{!expenses.PL_Expenses__c}">
                        <div>
                            <ui:inputSelect aura:id="acc" required="true" value="{!expenses.PL_Expenses__c}">
                                <ui:inputSelectOption text="" label="--None--" />
                                <aura:iteration items="{!v.options}" var="ac">
                                    <ui:inputSelectOption text="{!ac}" label="{!ac}"/>
                                </aura:iteration>
                            </ui:inputSelect>
                        </div>
                    </td>
                    <td data-label="{!expenses.Import__c}" title="{!expenses.Import}">
                        <div><ui:inputNumber class="slds-input" value="{!expenses.Import__c}"/></div>
                    </td>
                    <td data-label="{!expenses.Description__c}" title="{!expenses.Description}">
                        <div><ui:inputText class="slds-input" value="{!expenses.Description}"/></div>
                    </td>
                </tr>
            </aura:iteration>
        </tbody>
    </table> 
    <lightning:button class="slds-align_absolute-center slds-button slds-button_brand slds-m-top_small" onclick="{!c.save}" label="Save"/>
</div>

Controller and helper
doInit : function(component, event, helper) {       
    helper.getExpenses(component, helper, event);
},

//Fetch the expenses from the Apex controller
getExpenses: function(component, helper, event) {
    var action = component.get("c.getAllDesgloseCoste");
    action.setParams({opportunityId: component.get('v.recordId')});   
    //Set up the callback
    action.setCallback(this, function(actionResult) {
        component.set("v.expenses", actionResult.getReturnValue());
        this.fetchPickListVal(component, helper, event);
    }); 
    $A.enqueueAction(action);  
},


Controller - apex
@AuraEnabled
public static list<Expenses__c> getAllDesgloseCoste(Id opportunityId){
    return [SELECT Name, PL_Expenses__c, Import__c , Description__c 
            FROM Expenses__c
            WHERE Opportunity__c =:opportunityId];
}

@AuraEnabled
public static List<String> getPickListValuesIntoList(){
    List<String> pickListValuesList= new List<String>();
    Schema.DescribeFieldResult fieldResult = Expenses__c.PL_Expenses__c.getDescribe();
    List<Schema.PicklistEntry> ple = fieldResult.getPicklistValues();
    for( Schema.PicklistEntry pickListVal : ple){
        pickListValuesList.add(pickListVal.getLabel());
    }    
    return pickListValuesList;
}

User-added image
I have a table for create expenses. The table shows 3columns (a picklist, a decimal, and a text). I create a ui:inputSelect for the picklist. The table load the values of picklist, and save the value, but not show the data of the data base (always show --None--). How can I load the data os records??
Thanks

Component
<aura:handler name="init" action="{!c.doInit}" value="{!this}" />
<aura:handler event="force:refreshView" action="{!c.doInit}" />

<aura:attribute name="expenses" type="Expenses__c[]"/>
<aura:attribute name="options" type="String[]" />
<aura:attribute name="selectedValue" type="String"/>

<ltng:require styles="/resource/slds_resource/assets/styles/salesforce-lightning-design-system.css?v=1" />
<div class="slds">
    <div class="slds-page-header noborderbottom" role="banner"> 
        <div class="slds-grid">
            <div class="slds-col slds-has-flexi-truncate">
                <div class="slds-media slds-no-space slds-grow">
                    <div class="slds-media__figure">
                        <lightning:icon iconName="custom:custom17" size="large" alternativeText="Indicates approval"/>
                    </div>
                    <div class="slds-media__body">
                        <p class="slds-text-title_caps slds-line-height_reset">Expenses</p>
                        <h1 class="slds-page-header__title slds-m-right_small slds-align-middle slds-truncate" title="My Expenses">My expenses</h1>
                    </div>
                    <lightning:button class="slds-float_right" iconName="utility:refresh" onclick="{!c.refreshTable}" label="Refresh"/>
                    <lightning:button class="slds-float_right" iconName="utility:add" onclick="{!c.addRow}" label="Create expense"/>
                    <lightning:button class="slds-float_right" iconName="utility:clear" onclick="{!c.removeRow}" label="Delete expense"/>
                </div>
            </div>
        </div>
    </div>   
</div>

<div class="slds" style="overflow-x:auto;">
    <table class="slds-table slds-table--bordered slds-table--cell-buffer slds-max-medium-table--stacked-horizontal">
        <thead>
            <tr class="slds-text-heading--label">
                <th scope="col" class="nobordertop" title="Type">
                    <div>Type</div>
                </th>
                <th scope="col" class="nobordertop" title="Import">
                    <div>Import</div>
                </th>
                <th scope="col" class="{nobordertop'}" title="Description">
                    <div>Description</div>
                </th>
            </tr>
        </thead>
        <tbody>
            <aura:iteration items="{!v.expenses}" var="expenses">
                <tr>
                    <td data-label="{!expenses.PL_Expenses__c}" title="{!expenses.PL_Expenses__c}">
                        <div>
                            <ui:inputSelect aura:id="acc" required="true" value="{!expenses.PL_Expenses__c}">
                                <ui:inputSelectOption text="" label="--None--" />
                                <aura:iteration items="{!v.options}" var="ac">
                                    <ui:inputSelectOption text="{!ac}" label="{!ac}"/>
                                </aura:iteration>
                            </ui:inputSelect>
                        </div>
                    </td>
                    <td data-label="{!expenses.Import__c}" title="{!expenses.Import}">
                        <div><ui:inputNumber class="slds-input" value="{!expenses.Import__c}"/></div>
                    </td>
                    <td data-label="{!expenses.Description__c}" title="{!expenses.Description}">
                        <div><ui:inputText class="slds-input" value="{!expenses.Description}"/></div>
                    </td>
                </tr>
            </aura:iteration>
        </tbody>
    </table> 
    <lightning:button class="slds-align_absolute-center slds-button slds-button_brand slds-m-top_small" onclick="{!c.save}" label="Save"/>
</div>

Controller and helper
doInit : function(component, event, helper) {       
    helper.getExpenses(component, helper, event);
},

//Fetch the expenses from the Apex controller
getExpenses: function(component, helper, event) {
    var action = component.get("c.getAllDesgloseCoste");
    action.setParams({opportunityId: component.get('v.recordId')});   
    //Set up the callback
    action.setCallback(this, function(actionResult) {
        component.set("v.expenses", actionResult.getReturnValue());
        this.fetchPickListVal(component, helper, event);
    }); 
    $A.enqueueAction(action);  
},


Controller - apex
@AuraEnabled
public static list<Expenses__c> getAllDesgloseCoste(Id opportunityId){
    return [SELECT Name, PL_Expenses__c, Import__c , Description__c 
            FROM Expenses__c
            WHERE Opportunity__c =:opportunityId];
}

@AuraEnabled
public static List<String> getPickListValuesIntoList(){
    List<String> pickListValuesList= new List<String>();
    Schema.DescribeFieldResult fieldResult = Expenses__c.PL_Expenses__c.getDescribe();
    List<Schema.PicklistEntry> ple = fieldResult.getPicklistValues();
    for( Schema.PicklistEntry pickListVal : ple){
        pickListValuesList.add(pickListVal.getLabel());
    }    
    return pickListValuesList;
}

User-added image
Hi,

I have a doubt creating a lightning datatable. Can I edit the columns doing double click ?
I only can edit the data clicking to the edit icon. In standard List View, we can edit the value doing double click anywhere in the column.

User-added image

Thanks
Hi,

I have a datatable, and I need a text column with hiperlink to the reference object.
I want a similar table to a standard list view, the name of the column record is a hiperlink of the record page

Example:
List view of a record:
User-added image

Datatable with a colum type url
User-added image

Datatable with a colum type text
User-added image

Code:
cmp.set('v.columns', [
            {label: 'Recurso', fieldName: 'Name', type: 'url', sortable: true, editable:'true', initialWidth: 120},
        ]);

Thanks
Hi Devs,

I have some problems with a component that is going to be using a <lightning:datatable /> object.
There are data not visible, and the ddbb this values are filled. This values not load in the table.
Name is ok, the table can be editabled, and the sort works, but values not load (the fields are number, 16 with 2decimals). If I click on the column, show the value, but if I dont click, the value not is shown)
Thanks

Component:
<aura:component controller="TCK_DesglCoste_ByOpp_Ctr"
                implements="force:hasRecordId,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,lightning:actionOverride,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:appHostable"
                access="global" >
    
    <!-- handlers-->
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    <aura:handler event="force:refreshView" action="{!c.doInit}" />
    
    <!-- attributes -->
    <aura:attribute name="columnsDesglose" type="List"/>
    <aura:attribute name="desgloseCosteList" type="Desglose_Coste__c[]"/>
    <aura:attribute name="sortedBy" type="String" default="Name"/>
    <aura:attribute name="sortedDirection" type="String" default="asc"/>
    
    <div class="slds-page-header">
        <div class="slds-grid">
            <div class="slds-col slds-has-flexi-truncate">
                <div class="slds-media slds-no-space slds-grow">
                    <div class="slds-media__figure">
                        <lightning:icon iconName="custom:custom105" size="large" alternativeText="Indicates approval"/>
                    </div>
                    <div class="slds-media__body">
                        <p class="slds-text-title_caps slds-line-height_reset">Object</p>
                        <h1 class="slds-page-header__title slds-m-right_small slds-align-middle slds-truncate" title="My Contacts">My object</h1>
                    </div>
                </div>
            </div>
        </div>
    </div>
    
    <lightning:datatable
                         aura:id="desgloseCosteDataTable"
                         columns="{! v.columnsDesglose }"
                         data="{! v.desgloseCosteList }"
                         keyField="Id"
                         hideCheckboxColumn="true"
                         onsort="{!c.updateColumnSorting}"
                         sortedBy="{!v.sortedBy}"  
                         sortedDirection="{!v.sortedDirection}"
                         onsave ="{!c.onSave}"
                         onrowaction="{! c.handleRowAction }"
                         />
    
</aura:component>
Controller, helper and CTR
Controler:
({
    doInit : function(cmp, event, helper) {
        cmp.set('v.columnsDesglose', [
            {label: 'Name', fieldName: 'Name', type: 'text', sortable: true, editable:'true'},
            {label: 'Month 1', fieldName: 'Mes_1__c', type: 'double', sortable: true, editable:'true'},
            {label: 'Month 2', fieldName: 'Mes_2__c', type: 'double', sortable: true, editable:'true'},
            {label: 'Month 3', fieldName: 'Mes_3__c', type: 'double', sortable: true, editable:'true'},
            {label: 'Month 4', fieldName: 'Mes_4__c', type: 'double', sortable: true, editable:'true'},
            {label: 'Month 5', fieldName: 'Mes_5__c', type: 'double', sortable: true, editable:'true'},
        ]);
            
            helper.loadDesglose(cmp, helper);
            
            },
            
    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);
            },
            
    onSave : function (component, event, helper) {
            helper.saveDataTable(component, event, helper);
            },
            
})

__________
helper:
({
    loadDesglose : function(cmp, helper) {
        var action = cmp.get("c.getAllDesgloseCoste");
        action.setParams({opportunityId: cmp.get('v.recordId')});   
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                cmp.set("v.desgloseCosteList", response.getReturnValue());
                helper.sortData(cmp, cmp.get("v.sortedBy"), cmp.get("v.sortedDirection"));
            }
        });
        $A.enqueueAction(action);
    },
    
    sortData: function (cmp, fieldName, sortDirection) {
        var data = cmp.get("v.desgloseCosteList");
        var reverse = sortDirection !== 'asc';
        data.sort(this.sortBy(fieldName, reverse))
        cmp.set("v.desgloseCosteList", 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));
        }
    },
    
    saveDataTable : function(component, event, helper) {
        var editedRecords =  component.find("desgloseCosteDataTable").get("v.draftValues");
        var totalRecordEdited = editedRecords.length;
        var action = component.get("c.updateDesgloseCoste");
        action.setParams({
            'editedDesglCosteList' : editedRecords
        });
        action.setCallback(this,function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                //if update is successful
                if(response.getReturnValue() === true){
                    helper.showToast({
                        "title": "Record Update",
                        "type": "success",
                        "message": totalRecordEdited+" Registros actualizados"
                    });
                    helper.reloadDataTable();
                } else{ //if update got failed
                    helper.showToast({
                        "title": "Error!!",
                        "type": "error",
                        "message": "Error en la actualización"
                    });
                }
            }
        });
        $A.enqueueAction(action);
    },

    /*
     * Show toast with provided params
     * */
    showToast : function(params){
        var toastEvent = $A.get("e.force:showToast");
        if(toastEvent){
            toastEvent.setParams(params);
            toastEvent.fire();
        } else{
            alert(params.message);
        }
    },

    /*
     * reload data table
     * */
    reloadDataTable : function(){
    var refreshEvent = $A.get("e.force:refreshView");
        if(refreshEvent){
            refreshEvent.fire();
        }
    },
    
})


__________
CTR:
    @AuraEnabled
    public static list<Desglose_Coste__c> getAllDesgloseCoste(Id opportunityId){
        return [SELECT Name, Mes_1__c, Mes_2__c, Mes_3__c, Mes_4__c, Mes_5__c, Mes_6__c, Mes_7__c, Mes_8__c, Mes_9__c, Mes_10__c, Mes_11__c, Mes_12__c,
                Opportunity__c, Opportunity__r.Name, LastModifiedById
                FROM Desglose_Coste__c
                WHERE Opportunity__c =:opportunityId];
    }
    
    @AuraEnabled
    public static boolean updateDesgloseCoste(List<Desglose_Coste__c> editedDesglCosteList){
        try{
            system.debug('Total de registros: ' + editedDesglCosteList);
            update editedDesglCosteList;
            return true;
        } catch(Exception e){
            return false;
        }
    }