Replacing a standard redirect Onclick Javascript Button in Lightning Experience

Let's say you have a requirement that you want to create a related object record from a target records detail page. You also want to do some pre-validation and pre-populate fields on the related object record as guidelines for user suggestion.

In Salesforce Classic one way you could have done it was using an OnClick JavaScript button and include it on the target record's page layout. The picture below shows an implementation of a javascript button to accomplish the above requirement. The other way involves create a custom visualforce page and doing the validation on there and based on the complexity of the validation maybe need a controller to query related record fields. So it wasn't a very hard choice in Salesforce classic to go with the OnClick Javascript option.

Lightning Quick Action Implementation (Github)

In the lightning experience we cannot use OnClick Javascript buttons due to compatibility issues with lightning navigation so in this blog I am suggesting an approach I have used to use the replicate the above functionality using Quick Actions and lightning components. Also to make reuse of some of the functionality we have encapsulated the redirection logic into its own lightning component so it can be used in multiple quick action components. Due to the complexity of the pre-validation logic it is best if that is kept in the parent quick action component and keep the redirect component implementation light.

CustomRedirect Component

Encapsulates the redirect functionality to be reused in other quick action components and provides a reusable interface to redirect to create or edit any sobject records with pre-populated values.

CustomRedirect.cmp
<aura:component description="Custom Redirect Quick Action for replacing common standard page redirects for javascript button">

    <!--Global ATTRIBUTES-->
    <aura:attribute name="sObjectApiName" type="String" access="public" required="true"/>
    <aura:attribute name="mode" type="String" access="public" required="true"/>
    <aura:attribute name="recordId" type="String" access="public"/>
    <aura:attribute name="defaultFieldValuePairs" type="String" access="public"/>
    <aura:attribute name="showError" type="Boolean" access="public"/>
    <aura:attribute name="errorMessage" type="String" access="public"/>

    <!--Private ATTRIBUTES-->
    <aura:attribute name="loading" type="Boolean" />

    <!--Events-->
    <aura:registerEvent name="redirectDone" type="c:CustomRedirectDone"/>

    <!--HANDLERS-->
    <aura:handler name="init" action="{!c.doInit}" value="{!this}"/>

    <!--ERROR MSG-->
    <aura:if isTrue="{!v.showError}">
        <div class="slds-box slds-notify_alert slds-theme_alert-texture slds-theme_error" role="alert">
            <span class="slds-assistive-text">error</span>
            <span class="slds-icon_container slds-icon-utility-error slds-m-right_x-small" title="Description of icon when needed">
                    <lightning:icon iconName="utility:error" size="medium"
                                    alternativeText="error" class="iconContainer" />&nbsp;
                </span>
            <h2>{!v.errorMessage}</h2>
        </div>
    </aura:if>
    <!--</div>-->

</aura:component>


CustomRedirectController.js
({
    doInit : function(component, event, helper) {
        helper.doRedirect(component, event, helper);
    }
})


CustomRedirectHelper.js
 ({

    doRedirect : function(component, event, helper) {
        var showError = component.get('v.showError');
        var mode = component.get('v.mode');
        var redirectDoneEvent = component.getEvent('redirectDone');
        redirectDoneEvent.setParams({"isSuccess": false, "message": "Error message shown."});

        if(showError === undefined || showError === false) {
            var sObjectApiName = component.get('v.sObjectApiName');
            var defaultValues = component.get('v.defaultFieldValuePairs');

            switch(mode) {
                case 'CREATE':
                    var createRecordEvent = $A.get("e.force:createRecord");
                    createRecordEvent.setParams({
                        "entityApiName": sObjectApiName,
                        "defaultFieldValues": defaultValues
                    });
                    createRecordEvent.fire();

                    redirectDoneEvent.setParams({"isSuccess": true, "message": "Redirected to create record successfully!"});
                    break;
                case 'EDIT':
                    var editRecordEvent = $A.get("e.force:editRecord");
                    editRecordEvent.setParams({
                        "recordId": component.get("v.recordId"),
                        "defaultFieldValues": defaultValues
                    });
                    editRecordEvent.fire();
                    redirectDoneEvent.setParams({"isSuccess": true, "message": "Redirected to edit record successfully!"});
                    break;
                default:
                    redirectDoneEvent.setParams({"isSuccess": false, "message": "Invalid mode specified for redirect component!"});
                    break;
            }
        }

        redirectDoneEvent.fire();
    },
})

CustomRedirectDone Event

Event fired on success or error from the CustomRedirect component can be handled by the parent component to take appropriate action. One action is to close the quick action on success (as it will redirect to the edit or create component).

CustomRedirectDone.evt
<aura:event type="COMPONENT">
    <aura:attribute name="isSuccess" type="Boolean"/>
    <aura:attribute name="message" type="String"/>
</aura:event>

Demo Usage

Sample usage and demo on account to create a contact with some basic pre-validation. Since the pre-validation logic is still part of the parent quick action component. This can be embellished to be as complex as desired.

ContactRedirectDemo.cmp
<aura:component description="ContactRedirectDemo"
                implements="force:lightningQuickAction,force:hasRecordId">
    
    <aura:attribute name="showCreateContact" type="Boolean" default="false"/>
    <aura:attribute name="defaultValues" type="String" />
    <aura:attribute name="showError" type="Boolean"/>
    <aura:attribute name="errorMessage" type="String"/>

    <aura:attribute name="recordId" type="String"/>
    <aura:attribute name="record" type="Account"/>

    <aura:handler name="redirectDone" event="c:CustomRedirectDone"
    action="{!c.handleRedirectDone}"/>

    <force:recordData aura:id="recordLoader"
        recordId="{!v.recordId}"
        targetFields="{!v.record}"
        fields="['Id',
                'Name',
                'Industry',
                'Type',
                'Phone',
                'BillingStreet',
                'BillingCity',
                'BillingState',
                'BillingPostalCode',
                'BillingCountry']"
        mode="VIEW"
        recordUpdated="{!c.doRedirect}"/>

    <aura:if isTrue="{!v.showCreateContact}">
        <c:CustomRedirect sObjectApiName="Contact"
                          mode="CREATE"
                          showError="{!v.showError}"
                          errorMessage="{!v.errorMessage}"
                          defaultFieldValuePairs="{!v.defaultValues}"/>
    </aura:if>
    
</aura:component> 

ContactRedirectDemoController.js
({
    doRedirect : function(component, event, helper) {
        //Get Account Record
        var account = component.get("v.record");

        if(account.Industry === "Consulting" && account.Type == 'Customer - Direct') {
            var defaultValues = {};
            defaultValues.Phone = account.Phone;
            defaultValues.MailingStreet = account.BillingStreet;
            defaultValues.MailingCity = account.BillingCity;
            defaultValues.MailingPostalCode = account.BillingPostalCode;
            defaultValues.MailingState = account.BillingState;
            defaultValues.MailingCountry = account.BillingCountry;
            defaultValues.AccountId = account.Id;
            component.set("v.defaultValues", defaultValues);
        } else {
            component.set("v.showError", true);
            component.set("v.errorMessage", 'Only available on consulting accounts.');
        }

        //Show redirect component
        component.set("v.showCreateContact", true);
    },

    handleRedirectDone : function(component, event, helper) {
        var isSuccess = event.getParam("isSuccess");
        var message = event.getParam("message");

        console.log("handleRedirectDone-> isSuccess:" + isSuccess + " message: " + message);
        if(isSuccess === true) {
            // Close the action panel if not error
            var dismissActionPanel = $A.get("e.force:closeQuickAction");
            dismissActionPanel.fire();
        }
    }
})


Comments

  1. I think this is an informative post and it is very useful and knowledgeable. therefore, I would like to thank you for the efforts you have made in writing this article.website development agency

    ReplyDelete
  2. Some subdivisions thus dissertation web site using the net literature need unsurprisingly explained in your web-site. javascript developer

    ReplyDelete
  3. Thank you because you have been willing to share information with us. we will always appreciate all you have done here because I know you are very concerned with our. python代写

    ReplyDelete
  4. Subsequent to playing with the $1,000 esteem soon after the New Year, Bitcoin has been consistently exchanging at around $950 on the Mt. Gox trade in the course of the last fortnight and is in effect pleasantly upheld by the multi day moving normal demonstrating Bitcoin is still positively bullish. bitcoin mixer

    ReplyDelete
  5. The Best Casino in Oklahoma for Real Money 2021
    Online 바카라 시스템 배팅 casinos, and 룰렛사이트 sportsbooks, 총판 offer attractive 코드벳 welcome bonuses 룰렛사이트 and promotions as well as promotions, games, bonuses, and more.

    ReplyDelete

Post a Comment