Thursday, June 27, 2019

Send data from Lightning Component to Visualforce page Using Custom Event

This post explains how to send the data from the Lightning component to the visualforce page by using Custom Event.

In this demo, I am displaying the Account data in both Lighting component and visualforce page.

Example

Create a Custom Event this event used to send the data to visualforce page

SendDataToVFPage.evt
<!-- this event used in SendDataToVFPageComponent -->
<aura:event type="APPLICATION">
    <aura:attribute name="currentRecId" type="String"/>
    <aura:attribute name="CurrentRecDetails" type="Object" />
</aura:event>
Create Lightning Component and register the custom event in Lighting Component

SendDataToVFPage.cmp
<aura:component>

    <aura:attribute name="strParentId" type="String"/>
    <aura:attribute name="recordFields" type="Object"/>

    <!--This event used to send the data from Lightning component to vf page-->
    <aura:registerEvent name="vfEvent" type="c:SendDataToVFPage"/>

    <aura:if isTrue="{!not(empty(v.strParentId))}">
        <force:recordData aura:id="currentRecord" layoutType="FULL" recordId="{!v.strParentId}" targetFields="{!v.recordFields}"/>
        <h3><b>Showing data from Lightning Component</b></h3><br/>
        <div>
            <lightning:card iconName="standard:account" title="{!v.recordFields.Name}">
                <div class="slds-p-horizontal--small">
                    <p class="slds-text-heading--medium"><lightning:formattedText title="Type" value="{!v.recordFields.Type}"/></p>
                    <p class="slds-truncate">
                        <lightning:formattedText title="Industry" value="{!v.recordFileds.Industry}"/></p>
                    <p class="slds-truncate"><lightning:formattedPhone title="Phone" value="{!v.recordFields.Phone}"/></p>
                </div>
            </lightning:card>
        </div><br/>
        <div style="text-align: center">
            <lightning:button variant="brand" label="Send Data VF Page" onclick="{!c.sendDataVFPage}" />
        </div>
    </aura:if>

</aura:component>
when you click the 'sendDataVFPage' button in the Component custom event will fire and it sets the data to the event parameters.
SendDataToVFPageController.js
({
    sendDataVFPage : function(component, event, helper) {
        console.log('current rec details ===> '+JSON.stringify(component.get('v.recordFields')));
        console.log('Parent Id  ===> '+component.get('v.strParentId'));
        if(component.get('v.strParentId')) {
            var myEvent = $A.get("e.c:SendDataToVFPage");
            myEvent.setParams({
                currentRecId: component.get('v.strParentId'),
                CurrentRecDetails: component.get('v.recordFields')
            });
            myEvent.fire();
        }
    }
})

Create Lightning out App to call the lighting component from the visualforce page.
add your component in lightning out App.

DemoLightingOutApp.app
<aura:application extends="ltng:outApp" access="GLOBAL">
    <aura:dependency resource="c:SendDataToVFPage"/>
</aura:application>
Create Visualforce page and include  <apex:includeLightning /> in page.

LightingOutPageDemo.page
<apex:page standardController="Account">
    <apex:pageMessages />
    <apex:includeLightning />
    <div id="vfDemo" />

    <apex:pageBlock title="Showing data from visualforce page">
        <apex:pageBlockSection>
            <apex:pageBlockSectionItem>
                <apex:outputLabel value="Account Name" />
                <apex:outputText styleClass="accName" />
            </apex:pageBlockSectionItem>
            <apex:pageBlockSectionItem>
                <apex:outputLabel value="Account Industry" />
                <apex:outputText styleClass="accIndustry" />
            </apex:pageBlockSectionItem>
            <apex:pageBlockSectionItem>
                <apex:outputLabel value="Account Phone" />
                <apex:outputText styleClass="accPhone" />
            </apex:pageBlockSectionItem>
        </apex:pageBlockSection>
    </apex:pageBlock> <br/><br/>

    <script>
        // Calling Lightning component from vf page
        $Lightning.use("c:DemoLightingOutApp", function () {
            $Lightning.createComponent("c:SendDataToVFPage", {
                strParentId: '{!Account.Id}', // passing parameters to Lightning Component
            },
                "vfDemo",
                function (component) {
                    console.log("Lightning component rendered successfully!!");
                    // Event Service hander to handele the lightning component cusom event
                    $A.eventService.addHandler({ "event": "c:SendDataToVFPage", "handler": retriveEventData });
                });
        });


        function retriveEventData(event) {
            var recordTypeId = event.getParam("currentRecId");
            var eventRecordData = event.getParam("CurrentRecDetails");

            // passing data to outputtext lables
            document.getElementsByClassName("accName")[0].innerHTML = eventRecordData.Name;
            document.getElementsByClassName("accIndustry")[0].innerHTML = eventRecordData.Industry;
            document.getElementsByClassName("accPhone")[0].innerHTML = eventRecordData.Phone;
        }

    </script>
</apex:page>
Create Detail page button on the account select button type as visualforce and add the button to the Page Layout.
That's it.
Clcik the button from account record the component will render from vf page.

Result

6 comments:

  1. it fails at var myEvent, as the $A.get... is returning undefined

    ReplyDelete
    Replies
    1. make sure that pass the data to the event and register the event.
      verify the data is coming or not.

      Delete
    2. I have registered the event but It still returning undefined.

      Delete
    3. $A can only be accessible if the event is triggered from Salesforce1/lightning.

      Delete
  2. What is the syntax to handle multiple events on VF page?

    ReplyDelete