Lightning · Salesforce · Salesforce Releases

Usage of Spring ’19 component — lightning:unsavedChanges

Accidents are commonplace! And yeah, Spring  ’19 has come up with a new component lightning:unsavedChanges. Voila!!

We often come across situations where we type in data and then we accidentally refreshes, closes the page or press back button and all the entered data is lost!!  lightning:unsavedChanges  comes in to help here! It notifies the user about the unsaved changes in the page during the above mentioned situations and provides them the choice to continue, discard or save the data and handles the process accordingly. No more frustrations over data loss!!

Before we move ahead, it would be handy to remember that this component requires API version 45.0 or later and is not supported by one.app

In this blog, we demonstrate a sample of how this component works.

	 <aura:component controller="unsavedChangesClass" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global" >
		<lightning:unsavedChanges aura:id="unsavedData"
								  onsave="{!c.handleSave}"
								  ondiscard="{!c.handleDiscard}"/>
		<aura:attribute name="contactDetail" type="Contact" default="{'sobjectType' : 'Contact'}"/>

		<lightning:card title="Create Related Contact">
			<lightning:input aura:id="firstName"  label="FirstName"  value="{!v.contactDetail.firstName}" onchange="{!c.handleDataChange}"/><br/>
			<lightning:input aura:id="lastName"  label="LastName"  required="true" value="{!v.contactDetail.LastName}" onchange="{!c.handleDataChange}"/><br/>
			<lightning:input aura:id="phone"  label="Phone"   value="{!v.contactDetail.Phone}" onchange="{!c.handleDataChange}"/><br/>
			<lightning:button variant="brand"  label="Create Contact" onclick="{!c.saveContact}"/>
		</lightning:card>
	</aura:component>
	

CONTROLLER


    ({
    //Method call on Create Button Click
    saveContact : function(component, event, helper){
        helper.createContact(component, event);
    },

    /*This method sets the boolean for unsavedChanges to true,
     * so that it indicates the containment that unsaved data is rpesent
     * */
    handleDataChange: function(component, event, helper) {
        var unsavedData = component.find('unsavedData');
        unsavedData.setUnsavedChanges(true, {label: 'creating related contact?'});
    },

    /**
     * This method will be called when user click save button from dialog window
     * Save your unsaved changes here
     * */
    handleSave: function(component, event, helper) {
        helper.createContact(component, event);
    },

    /**
     * This method will be called when user clicks 'discard changes' button from dialog window
     * */
    handleDiscard: function(component, event, helper) {
        var unsavedData = component.find('unsavedData');
        unsavedData.setUnsavedChanges(false);
      }
})

HELPER

({
    createContact : function(component, event){
        var action = component.get('c.createContact');
        action.setParams({'accId' : component.get('v.recordId'),
                          'lName' : component.find('lastName').get('v.value')});
        action.setCallback(this, function(response){
            var state = response.getState();
            if(state === 'SUCCESS'){
                var unsavedData = component.find('unsavedData');
                unsavedData.setUnsavedChanges(false);

                var navEvt = $A.get("e.force:navigateToSObject");	//To navigate
                navEvt.setParams({
                    "recordId": response.getReturnValue().Id,
                });
                navEvt.fire();
            }else{
                console.log('error');
            }
        });
        $A.enqueueAction(action);
    }
})

APEX

public with sharing class unsavedChangesClass {
    @AuraEnabled
    public static Contact createContact(Id accId, String lName){
        Contact con = new Contact(lastname=lName,
                                 accountId = accId);
        insert con;
        return con;
    }
}

The process is majorly handled by the function setUnsavedChanges within the lightning component.  This method holds two arguments  –

  • A Boolean argument to indicate if usaved data is present in the page or not. (True if unsaved content is present, false otherwise)
  • An optional object argument.

Upon data entry, we set the setUnsavedChanges to true; And therefore, when the user takes any action that loses data, it notifies the containment that unsaved data is present in the page and the dialogue window pops up as shown in the screenshot. Now, depending on the user’s decision, the handleSave  or handleDiscard custom methods will be invoked. The onsave attribute controls the action to  handle saving unsaved content  and the  ondiscard attribute  controls the action to handle discarding unsaved content. Also, keep in mind that, these methods should call the setUnsavedChanges() method again to return control back to the Lightning UI.

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s