3

I have two visualforce pages, each containing a different visualforce component, that are on the same object layout, and now I have to make them communicate between each other.

I have tried making them share the controller, but quickly realized this won't work because that method relies (the descriptions I found at least) on the components inside the page belonging to the same page - which isn't the case.

I have found since a lot of help regarding communication between lightning and visualforce, so I've tried to implement solution in this link, making the event fire from vf component #1, and receiving the event on the vf component #2, but I only managed to fire the event, and I haven't managed to receive it.

Does anyone know is it possible to make them communicate somehow?

2
  • Can you provide any information on why you want them to communicate? As in what you are trying to accomplish?
    – stackasaur
    May 4, 2020 at 15:48
  • The linked article is not fit for purpose with production because there is no way to automatically get the vfHost and lexOrigin values. You have to hard code them (and this makes it unportable between production and dev/sandboxes). Don't even try to use it. I wasted days with this.
    – Phil W
    May 4, 2020 at 16:08

2 Answers 2

4

You can use onstorage to send data via storage.

Sender

sessionStorage.setItem("value", data);

Receiver

window.addEventListener("storage", handleStorage);

...

function handleStorage(e) {
  if(e.key === 'value') {
    var data = e.newValue;
    ...
  }
}

MessageChannel/ServiceWorker

In Visualforce, you can load a ServiceWorker as a common channel. This is a bit more complicated, so check the docs.


sforce.one.sendMessage

sendMessage can communicate across any subscribers within the same window (including iframes). Example from the docs:

<apex:page >
    <apex:includeScript value="/support/console/48.0/integration.js"/>
    <a href="#" onClick="testSendMessage();">Send Message</a> 

    <script type="text/javascript">

        function testSendMessage() {
            //Get the value for 'myChatKey'from the sforce.console.chat.getDetailsByPrimaryTabId() or other chat methods. 
            //These values are for example purposes only
            var chatKey = 'myChatKey';
            var text ='This is sample text to send as a message';
            sforce.console.chat.sendMessage(chatKey, text, sendMessageSuccess);
        }

        function sendMessageSuccess(result) {
            //Report whether getting the chat log was successful
            if (result.success == true) {
                alert('Message Sent');
            } else {
                alert('Sending the message was not successful');
            }
        };


    </script>
</apex:page>

And, of course, see Sebatian's answer on LMS.

1
  • Thank you, onstorage method of communication has worked wonders! May 4, 2020 at 16:32
3

Even though it was conceived as a way to communicate between Aura and LWC, you should be able to get the Lightning Message Service to work for VF as well. (Thanks sfdcfox for the nudge here).

(Shamless plug) I wrote a blog post, here, describing the entire approach in detail but here are the highlights.

1) You create a Message Channel (similar method to a Platform Event). This is a sample file format (you will have to deploy this via workbench or similar to get it to work)

<?xml version="1.0" encoding="UTF-8"?>
<LightningMessageChannel xmlns="http://soap.sforce.com/2006/04/metadata">
   <masterLabel>SayWhat</masterLabel>
   <isExposed>true</isExposed>
   <description>This Lightning Message Channel sends information from VF to LWC and back.</description>
   <lightningMessageFields>
       <fieldName>messageToSend</fieldName>
       <description>The message to communicate to others</description>
   </lightningMessageFields>
   <lightningMessageFields>
       <fieldName>sourceSystem</fieldName>
       <description>Who Is Saying This?</description>
   </lightningMessageFields>
</LightningMessageChannel>

2) In your first VF page, you can submit the event (using js)

// Load the MessageChannel token in a variable
var SAYWHATMC = "{!$MessageChannel.SayWhat__c}";
var subscriptionToMC;

function publishMessage() {
   const payload = {
       sourceSystem: "VF",
       messageToSend: "Some Message"
   };

   sforce.one.publish(SAYWHATMC, payload);
}

3) In your second VF page, you can subscribe and process the event (again using JS)

// Load the MessageChannel token in a variable
var SAYWHATMC = "{!$MessageChannel.SayWhat__c}";
var subscriptionToMC;

function subscribeMC() {
   if (!subscriptionToMC) {
       subscriptionToMC = sforce.one.subscribe(SAYWHATMC, onMCPublished, {scope: "APPLICATION"});
   }
}

function unsubscribeMC() {
   if (subscriptionToMC) {
       sforce.one.unsubscribe(subscriptionToMC);
       subscriptionToMC = null;
   }
}

function onMCPublished(message) {
   var textArea = document.querySelector("#ReceivedMessage");

   textArea.innerHTML = message ? 'Message: ' + message.messageToSend + '. Sent From: ' + message.sourceSystem : 'no message payload';
}

Again, the post has a lot more detail and steps, but the gist is above.

14
  • Great but for the fact it isn't GA yet (and therefore cannot be used in a production org AFAIK).
    – Phil W
    May 4, 2020 at 16:09
  • I used a Dev Org to produce the samples above. I am not sure that i cannot be used in a production org. I know it can't be packaged, but i don't think there are restrictions on environments and, of course, you must understand that things can change. May 4, 2020 at 16:11
  • 1
    @PhilW I don't see any problem with taking the risk as long as the developer(s) are willing to unit test their logic every release until LMS goes GA. Our org can't afford to do it because of The Thing That Shan't Be Named, but with due diligence, it could be acceptable.
    – sfdcfox
    May 4, 2020 at 16:22
  • 1
    Oh, and LMS wasn't meant strictly to be VF<=>Lightning communication, but a channel for Aura<=>LWC. The VF support was actually the bonus (see this).
    – sfdcfox
    May 4, 2020 at 16:26
  • 3
    As expected, LMS is now GA as of Summer 20. Release notes here: releasenotes.docs.salesforce.com/en-us/summer20/release-notes/… May 4, 2020 at 17:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .