function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Andrew GAndrew G 

lightning inline table hide save button after save event

Hello
I am doing an inline table as a lightning component, but after the save event the button will not disappear.
I have found a post that mentions clearing the default values,
component.find("SADataTable").set("v.draftValues", null);
but playing with that line will cause the button to hide, but the table data does not reload after save.
I have also played with firing a refreshview, but no luck either
$A.get('e.force:refreshView').fire();
My component
<aura:component controller="ServiceAppointmentListController" implements="flexipage:availableForRecordHome,force:hasRecordId" access="global" >
    <aura:attribute name="recordId" type="Id" />
    <aura:attribute name="WorkOrder" type="WorkOrder" />
    <aura:attribute name="ServiceAppointments" type="ServiceAppointment" />
	<aura:attribute name="Columns" type="List" />
    <aura:attribute name="saveDraftValues" type="Object" />
    <aura:handler name="init" value="{!this}" action="{!c.myAction}" />
    <force:recordData aura:id="workOrderRecord" recordId="{!v.recordId}" targetFields="{!v.WorkOrder}" layoutType="FULL" />
    <lightning:card title="{! 'Service Appointment List for ' + v.WorkOrder.WorkOrderNumber}">
        <!-- Service Appointment list goes here -->
        <lightning:datatable 
                aura:id="SADataTable"
                keyField="Id" 
        		data="{! v.ServiceAppointments }" 
                columns="{! v.Columns }" 
                onsave="{!c.handleSave}" />
    </lightning:card> 
</aura:component>
The JS controller
({
	myAction : function(component, event, helper) {
        component.set("v.Columns", [
            {label:"Appt Id", fieldName:"AppointmentNumber", type:"text"},
            {label:"Duration", fieldName:"Duration", type:"number", editable : 'true'},
            {label:"Duration Type", fieldName:"DurationType", type:"text", editable : 'true'}
        ]);
		var action = component.get("c.getServiceAppointments");
        action.setParams({
            recordId: component.get("v.recordId")
        });
        action.setCallback(this, function(data) {
            component.set("v.ServiceAppointments", data.getReturnValue());
        });
        $A.enqueueAction(action);
	},
    handleSave: function (component, event, helper ) {
		helper.saveDataTable(component, event, helper);
    }
})
The helper manages the save and posts toast messages.
({
    saveDataTable : function(component, event, helper) {
        var editedRecords =  component.find("SADataTable").get("v.draftValues");
        var totalRecordEdited = editedRecords.length;
        var action = component.get("c.updateServiceAppointments");
        action.setParams({
            'editedSAList' : 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+" Service Appointment Records Updated"
                    });
                    helper.reloadDataTable();
                } else{ //***if update failed ***
                    helper.showToast({
                        "title": "Error!!",
                        "type": "error",
                        "message": "Error in update"
                    });
                }
            }
        });
        $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();
        }
    }
})
For completeness, my Server Side controller
public class ServiceAppointmentListController {
    @AuraEnabled
    public static List<ServiceAppointment> getServiceAppointments(Id recordId) {
       return [SELECT Id, AppointmentNumber, Duration, DurationType  FROM ServiceAppointment WHERE ParentRecordId = :recordId];
    }
    
    @AuraEnabled
    public static boolean updateServiceAppointments(List<ServiceAppointment> editedSAList) {
        try {
            update editedSAList;
            return true;
        } catch(Exception e){
            return false;
        }
    }
}

Any assistance appreciated.  I have been troubleshooting this for a day, but seem to be going around in circles.
Regards
Andrew 





 
Best Answer chosen by Andrew G
Khan AnasKhan Anas (Salesforce Developers) 
Hi Andrew,

I trust you are doing very well.

To refresh the data table you need to use e.force:refreshView
Below is the sample code which I have tested in my org by updating a few things and it is working fine. Kindly modify the code as per your requirement.

I have used Account object here.

Component:
<aura:component controller="DataTableEditTestC"
                implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global" >
    
    <aura:attribute name="recordId" type="Id" />
    <aura:attribute name="ServiceAppointments" type="Account" />
    <aura:attribute name="Columns" type="List" />
    <aura:attribute name="saveDraftValues" type="Object" />
    
    <aura:handler name="init" value="{!this}" action="{!c.myAction}" />
    <aura:handler event="force:refreshView" action="{!c.myAction}" />
    
    <force:recordData aura:id="workOrderRecord" recordId="{!v.recordId}" targetFields="{!v.WorkOrder}" layoutType="FULL" />
    
    <lightning:card title="{! 'Service Appointment List for ' + v.WorkOrder.WorkOrderNumber}">
        <!-- Service Appointment list goes here -->
        <lightning:datatable 
                             aura:id="SADataTable"
                             keyField="Id" 
                             data="{! v.ServiceAppointments }" 
                             columns="{! v.Columns }" 
                             onsave="{!c.handleSave}" />
    </lightning:card> 
</aura:component>

Controller:
({
    myAction : function(component, event, helper) {
        component.set('v.Columns', [
            {label: 'Account Name', fieldName: 'Name', type: 'text', editable: true, initialWidth: 750},
            {label: 'Phone', fieldName: 'Phone', type: 'phone', editable: true}
        ]);
        
        var action = component.get("c.getServiceAppointments");
        action.setCallback(this, function(response) {
            var state = response.getState();
            
            if (state === "SUCCESS") {
                var res = response.getReturnValue();
                component.set("v.ServiceAppointments", res);
            }
            else if (state === "ERROR") {
                var errors = response.getError();
                if (errors) {
                    if (errors[0] && errors[0].message) {
                        console.log("Error message: " + 
                                    errors[0].message);
                    }
                } 
                else {
                    console.log(response.getReturnValue());
                }
            }
        });
        $A.enqueueAction(action);
    },
    
    handleSave : function(component, event, helper) {
        var editedRecords =  component.find("SADataTable").get("v.draftValues");
        var totalRecordEdited = editedRecords.length;
        var action = component.get("c.updateServiceAppointments");
        action.setParams({
            'editedSAList' : editedRecords
        });
        action.setCallback(this,function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                //***if update is successful ***
                if(response.getReturnValue() === true){
                    $A.get('e.force:refreshView').fire();
                    var showToast = $A.get("e.force:showToast"); 
                    showToast.setParams({ 
                        'title' : 'Record Update',
                        'type': 'success',
                        'message' : totalRecordEdited+" Service Appointment Records Updated" 
                    }); 
                    showToast.fire(); 
                    }
                } 
            else{ 
                //***if update failed ***
                    showToast.setParams({
                        "title": "Error!!",
                        "type": "error",
                        "message": "Error in update"
                    });
                }
            }
        );
        $A.enqueueAction(action);
    },
})

Apex:
public class DataTableEditTestC {
    
    @AuraEnabled
    public static List<Account> getServiceAppointments() {
        return [SELECT Id, Name, Phone  FROM Account LIMIT 10];
    }
    
    @AuraEnabled
    public static boolean updateServiceAppointments(List<Account> editedSAList) {
        try {
            update editedSAList;
            return true;
        } catch(Exception e){
            return false;
        }
    }
}


I hope it helps you.

Kindly let me know if it helps you and close your query by marking it as solved so that it can help others in future.

Thanks and Regards,
Khan Anas

All Answers

Khan AnasKhan Anas (Salesforce Developers) 
Hi Andrew,

I trust you are doing very well.

To refresh the data table you need to use e.force:refreshView
Below is the sample code which I have tested in my org by updating a few things and it is working fine. Kindly modify the code as per your requirement.

I have used Account object here.

Component:
<aura:component controller="DataTableEditTestC"
                implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global" >
    
    <aura:attribute name="recordId" type="Id" />
    <aura:attribute name="ServiceAppointments" type="Account" />
    <aura:attribute name="Columns" type="List" />
    <aura:attribute name="saveDraftValues" type="Object" />
    
    <aura:handler name="init" value="{!this}" action="{!c.myAction}" />
    <aura:handler event="force:refreshView" action="{!c.myAction}" />
    
    <force:recordData aura:id="workOrderRecord" recordId="{!v.recordId}" targetFields="{!v.WorkOrder}" layoutType="FULL" />
    
    <lightning:card title="{! 'Service Appointment List for ' + v.WorkOrder.WorkOrderNumber}">
        <!-- Service Appointment list goes here -->
        <lightning:datatable 
                             aura:id="SADataTable"
                             keyField="Id" 
                             data="{! v.ServiceAppointments }" 
                             columns="{! v.Columns }" 
                             onsave="{!c.handleSave}" />
    </lightning:card> 
</aura:component>

Controller:
({
    myAction : function(component, event, helper) {
        component.set('v.Columns', [
            {label: 'Account Name', fieldName: 'Name', type: 'text', editable: true, initialWidth: 750},
            {label: 'Phone', fieldName: 'Phone', type: 'phone', editable: true}
        ]);
        
        var action = component.get("c.getServiceAppointments");
        action.setCallback(this, function(response) {
            var state = response.getState();
            
            if (state === "SUCCESS") {
                var res = response.getReturnValue();
                component.set("v.ServiceAppointments", res);
            }
            else if (state === "ERROR") {
                var errors = response.getError();
                if (errors) {
                    if (errors[0] && errors[0].message) {
                        console.log("Error message: " + 
                                    errors[0].message);
                    }
                } 
                else {
                    console.log(response.getReturnValue());
                }
            }
        });
        $A.enqueueAction(action);
    },
    
    handleSave : function(component, event, helper) {
        var editedRecords =  component.find("SADataTable").get("v.draftValues");
        var totalRecordEdited = editedRecords.length;
        var action = component.get("c.updateServiceAppointments");
        action.setParams({
            'editedSAList' : editedRecords
        });
        action.setCallback(this,function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                //***if update is successful ***
                if(response.getReturnValue() === true){
                    $A.get('e.force:refreshView').fire();
                    var showToast = $A.get("e.force:showToast"); 
                    showToast.setParams({ 
                        'title' : 'Record Update',
                        'type': 'success',
                        'message' : totalRecordEdited+" Service Appointment Records Updated" 
                    }); 
                    showToast.fire(); 
                    }
                } 
            else{ 
                //***if update failed ***
                    showToast.setParams({
                        "title": "Error!!",
                        "type": "error",
                        "message": "Error in update"
                    });
                }
            }
        );
        $A.enqueueAction(action);
    },
})

Apex:
public class DataTableEditTestC {
    
    @AuraEnabled
    public static List<Account> getServiceAppointments() {
        return [SELECT Id, Name, Phone  FROM Account LIMIT 10];
    }
    
    @AuraEnabled
    public static boolean updateServiceAppointments(List<Account> editedSAList) {
        try {
            update editedSAList;
            return true;
        } catch(Exception e){
            return false;
        }
    }
}


I hope it helps you.

Kindly let me know if it helps you and close your query by marking it as solved so that it can help others in future.

Thanks and Regards,
Khan Anas
This was selected as the best answer
Andrew GAndrew G
Hi Khan

I have just quickly implemented your changes and , yes, it now works.

I will spend some time later comparing the two lots of code and work out what the differences are in how things are called.

Unfortunately, I need to rush and get ready for a flight right now.

Thanks for the help.  I will close the query when I return (2 days away) just if I have any questions for you.  
Thanks again

Andrew
 
Andrew GAndrew G
Hi Khan
Thanks for the response.
I'm still not sure why my code didn't work, but will spend some more time reading on lightning components.  Hell of an introduction for me on ligtning components, but I hope to improve my understanding over time 

Regards
Andrew