[SalesForce] eventlistener not working on VisualForce page

I have a VisualForce page as below:

VFPage1: (https://ap5.visual.force.com/apex/VFPage1)

<apex:page controller="Sampleclasscontroller" >
<apex:pageBlock title="Hello {!$User.FirstName}!">
    This is your new page for the {!name} controller.
</apex:pageBlock>
<script>
    window.opener.postMessage("sample" , "*"); 
</script>
</apex:page>

Controller for the above page is shown below:

Sampleclasscontroller:

global class Sampleclasscontroller
 {
  public String getName() {
  String message = System.currentPagereference().getParameters().get('msg');
  if(message == 'luck')
    {
        message = 'success';           
        }
  else{
        message = 'failure';
     }
  return message;
}
}

In VFPage1, I get the 'msg' parameter through the URL of the page.I want the window.opener.postMessage("sample" , "*") statement to execute only if the 'msg' parameter of the URL is equal to "luck" i.e I want the event to be triggered only if the VFPage1 URL loaded in the browser is https://ap5.visual.force.com/apex/VFPage1?msg=luck

If any other value is passed in the 'msg' parameter in the URL, I do not want the event to be triggered.

The event is then listened by VFPage2 as shown below and the actions to be performed after triggering the event are described in VFPage2. I have added an eventListener to VFPage2 as well.

VFPage2:

<apex:page>
<style>
    .hasMotif {
        margin : 0px;
    }
</style>
<apex:iframe src="https://3d-ipsemi-dev-ed--c.ap5.visual.force.com/apex/kkvfpage" height="500" width="300" frameborder="false"/>
<script src="/support/api/40.0/lightning/opencti_min.js"></script>
<script>
   function receiveMessage(event) {
    if(event.data == 'sample') {
        var fromNumber = '3125616295';                       
        sforce.opencti.runApex({ apexClass: 'RCPhoneHelper', methodName: 'searchContact', methodParams: 'phone=' +fromNumber,
                                callback: function(response) {
                                    if(response.success == true) {
                                        var contact = response.returnValue.runApex;
                                        if(contact !== null) {
                                            sforce.opencti.screenPop({type: sforce.opencti.SCREENPOP_TYPE.SOBJECT,params: { recordId: contact.Id }});
                                            window.open('https://www.google.com/search?q=' + contact.Name);
                                        }
                                    }
                                } 
                               });
        }
    }
window.addEventListener("message", receiveMessage, false);

</script>
</apex:page>

But the event is not getting triggered and no action is being performed in VFPage2. Don't know why. Can someone tell me what is wrong with this?

I have been desperately trying this since 2 days but got no results.
I have also referred all documentations related to event handling in Salesforce. But I'm not able to find an answer.

Best Answer

The pages need to have a "handle" to each other, for example, by virtue of window.open or being an iframe (e.g. window.top). If you just open these two pages in separate tabs, they can't communicate this way. However, since they're on the same domain, one typical method is to use a Storage event, or the brand new BroadcastChannel (note: may not work in Edge yet).

To get your example code working with minimal modification, you could open the first window from the second:

   function receiveMessage(event) {
    if(event.data == 'sample') {

      **Perform some actions***

        }
    }
window.addEventListener("message", receiveMessage, false);
window.open("popup", "/apex/VFPage1");

And modify the VFPage1:

window.opener.postMessage("sample" , "*"); 

For Storage, you might look at this question on SO:

// use local storage for messaging. Set message in local storage and clear it right away
// This is a safe way how to communicate with other tabs while not leaving any traces
//
function message_broadcast(message)
{
    localStorage.setItem('message',JSON.stringify(message));
    localStorage.removeItem('message');
}


// receive message
//
function message_receive(ev)
{
    if (ev.originalEvent.key!='message') return; // ignore other keys
    var message=JSON.parse(ev.originalEvent.newValue);
    if (!message) return; // ignore empty msg or msg reset

    // here you act on messages.
    // you can send objects like { 'command': 'doit', 'data': 'abcd' }
    if (message.command == 'doit') alert(message.data);

    // etc.
}

This is a basic broadcast mechanism using Storage as the medium; all pages that subscribe to Storage events can communicate with each other.

BroadcastChannel works like Window.postMessage, but works for all pages on the same domain that are subscribed to that channel. The MDN documentation explains this in better detail.

Related Topic