+ Start a Discussion
louisa barrett 7louisa barrett 7 

lightning:unsavedChanges and record edit form

Hi,

I have a aura component which uses a lightning:recordEditForm and a standard Lighting:button of type 'submit' to save the data. I want to implement the lightning:unsavedChanges component, which is halfway there, but when the user presses 'Save' on the unsaved changes dialog I cannot figure out how to either call the standard save function from submit button or to close the unsaved changes dialog so the user has to press save on the form.
Here is my code:

Component:
<aura:component controller="CaseController" implements="flexipage:availableForRecordHome,force:hasRecordId" access="global" >
    <aura:attribute name="reloadForm" type="boolean" default="true"/>
    <aura:attribute name="saveDisabled" type="boolean" default="true"/>
    <aura:attribute name="cancelDisabled" type="boolean" default="true"/>
    
    <lightning:unsavedChanges aura:id="unsaved"
                              onsave="{!c.handleSave}"
                              ondiscard="{!c.handleDiscard}"/>
    
    <!-- Notification library to show notifications-->
    <lightning:notificationsLibrary aura:id="notifLib"/>
    
    <lightning:card title="Case #">
        <div class="slds-p-left_large slds-p-right_medium">	
            <lightning:recordEditForm aura:id="recordEditForm" 
                                      objectApiName="Case"
                                      recordId="{!v.recordId}"
                                      onsuccess="{!c.handleSuccess}"
                                      density="comfy">
                <aura:if isTrue="{!v.reloadForm}">
                    <lightning:messages />             
                    <div class="slds-grid slds-wrap">
                        <div class="slds-col slds-size_1-of-2">
                            <lightning:inputField fieldName="Status" onchange="{!c.enableButtons}"/>
                            <lightning:inputField aura:id="asset" fieldName="AssetId" onchange="{!c.handleAssetChange}"/>
                            <lightning:inputField aura:id="assFaultCat" fieldName="Fault_Category__c" disabled="true" onchange="{!c.enableButtons}" />
                            <lightning:inputField aura:id="assFaultType" fieldName="Fault_Type__c" onchange="{!c.enableButtons}" />
                        </div>
                        <div class="slds-col slds-size_1-of-2">
                            <lightning:inputField fieldName="Priority" onchange="{!c.enableButtons}"/>
                            <lightning:inputField aura:id="assMakeModel" fieldName="Asset_Make_and_Model__c" />
                            <lightning:inputField fieldName="Interface_Type__c"/>    
                            <lightning:inputField fieldName="Connection_Method__c"/>
                        </div>
                    </div>
                    <div class="slds-grid slds-wrap">
                        <div class="slds-col slds-size_1-of-1">
                            <lightning:inputField fieldName="Description" onchange="{!c.enableButtons}"/>
                        </div>
                        <div class="slds-col slds-size_1-of-1">
                            <lightning:inputField fieldName="Help_Required__c" onchange="{!c.enableButtons}"/>
                        </div>
                    </div>
                    <div class="slds-grid slds-wrap">
                        <div class="slds-col slds-size_1-of-2">
                            <lightning:inputField fieldName="Solution__c"/>
                        </div>
                        <div class="slds-col slds-size_1-of-2">
                            <lightning:inputField fieldName="Solution_Details__c" onchange="{!c.enableButtons}" />
                        </div>
                    </div>
                    <aura:set attribute="else">
                        Saving...
                    </aura:set>
                </aura:if>
                <lightning:button class="slds-m-top_small"  name="cancel" label="Cancel" disabled = "{!v.cancelDisabled}" onclick="{!c.handleReset}"/>
                <lightning:button class="slds-m-top_small" variant="brand" type="submit" name="save" label="Save" disabled = "{!v.saveDisabled}" />
            </lightning:recordEditForm>
        </div>
    </lightning:card>	
</aura:component>
Controller:
({
    handleAssetChange: function(component, event, helper) {
        console.log('asset changed');
        var newID = event.getParam("value");
        if(newID.length >0)
        {
            if(newID.length > 0)
            {
                console.log('helper called');
                console.log(newID[0]);
                helper.updateAsset(component, newID[0]);  
            } 
        } 
    },
    
    enableButtons: function(component, event, helper) {
        console.log('field changed');
        var unSavedChange = component.find('unsaved');
        unSavedChange.setUnsavedChanges(true, { label: 'You have unsaved changes. Do you want to Continue?' }); 
        helper.toggleButtons(component, false, false);
    },
    
    handleSave : function(component, event, helper) {
        var unSavedChange = component.find('unsaved');
        unSavedChange.setUnsavedChanges(false);
    },
   
    handleSuccess : function(component, event, helper) {
        console.log('success handled');
        helper.handleSuccess(component, event, helper);
    },
    
    handleReset: function(component, event, helper) {
        console.log('Cancel clicked');
        helper.toggleButtons(component, true, true);
        helper.reshowForm(component);
    }
})

Helper:
({
    updateAsset : function(component, assetId){
        var action = component.get("c.fetchAsset");
        console.log('Helper - New asset Id = ' + assetId);
        action.setParams({
            "assetId": assetId
        });
        action.setCallback(this, function(result){
            var serverState = result.getState();
            console.log('Server state = ' + serverState);
            console.log('Asset Update');
            var res = result.getReturnValue();
            console.log('res result');
            console.log(res);
            //Ideally put a check in here to see if the new asset is covered under contract and if not, display an error. Will also have to check that the case doesn't already have a PO number assigned
            if (component.isValid() && serverState === "SUCCESS"){
                component.find('assFaultCat').set('v.value', res.Product_Category__c);
                component.find('assFaultType').set('v.value', null);
                var toastEvent = $A.get("e.force:showToast");
                console.log('the asset was changed');
                /*toastEvent.setParams({
                    "title": "Success",
                    "message": "The asset has been updated",
                    "type" : "success"
                });
                toastEvent.fire();*/
            }
            else if (serverState === "ERROR") {
                var errors = result.getError();
                console.log('There are errors');
                console.error(errors);
                if(errors){
                    if(errors[0] && errors[0].message){
                        var toastEvent = $A.get("e.force:showToast");
                        toastEvent.setParams({
                            "title": "Error!",
                            "message": errors[0].message,
                            "mode" : "sticky",
                            "type" : "error"
                        });
                        toastEvent.fire();
                    }
                }
            }
        });
        $A.enqueueAction(action);  
    },
    
    handleSuccess : function(component, event, helper){
        console.log('handle success helper called');
        component.find('notifLib').showToast({
            "variant": "success",
            "title": "Success!",
            "message": "The record has been successfully updated"
        });
        this.toggleButtons(component, true, true);
    },
    
    
    toggleButtons: function(component, saveDisabled, cancelDisabled)
    {
        console.log('toggle buttons -' + 'Save = ' + saveDisabled + 'Cancel = '+ cancelDisabled);
        component.set("v.saveDisabled", saveDisabled);
        component.set("v.cancelDisabled", cancelDisabled);
    },
    
    reshowForm: function(component)
    {
        console.log('reshow form');
        component.set("v.reloadForm", false);
        component.set("v.reloadForm", true);
    }
})

Many thanks​​​​​​​
 
ShivankurShivankur (Salesforce Developers) 
Hi Louisa,

Please check out the implementation over below link to understand the code as well as behavior via a video simulation of the same:
https://www.salesforcecodecrack.com/2019/01/notify-unsaved-changes-to-user.html

For more information on lightning:unsavedChanges, you can refer to below standard documentation:
https://developer.salesforce.com/docs/component-library/bundle/lightning:unsavedChanges/documentation

Hope above information helps. Please mark as Best Answer so that it can help others in future.

Thanks.