Search code examples
javascriptreactjspostmessage

using postMessage in a modal to communicate the parent window


I have a html page that opens a modal using window.showModalDialog with a React application as the uri:

var retValue = window.showModalDialog ("http://localhost:8080/myreactapp, "dialogWidth:500px; dialogHeight:500px; dialogLeft:300px;");

This react app displays a form and has a data object to contain the form values. When I submit the form I would the the updated data object to be sent to the parent html page of the modal .

I've been using the [postmessage api] (https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) for communicating between the parent and the child windows.

In the modal I have:

window.top.postMessage( message, 'http://localhost:3000/postMessage.html' );

I've also tried:

window.parent.postMessage( message, 'http://localhost:3000/postMessage.html' );

I can communicate from the react app to the parent when I use an iframe but not when using a modal.

The postmessage simply does nothing in modal, there is no error message and no message sent.


Solution

  • I was able to get this working.

    In the html client I use two test methods :

     function createWindow()
    {
     var win = window.open('http://localhost:8080/myreactapp', 'popup', 
    'status=
     no,toolbar=no,location=no,
     directories=no,
     resisable=no,
     srollbars=yes,
     width=1050,height=600');
    
     }
    
     function createWindowV2() {
    if (window.showModalDialog) {
        showModalDialog ("http://localhost:8080/myreactapp", window, "dialogWidth:1000px; dialogHeight:800px; dialogLeft:300px;");
    
       }
    

    }

    Then in the popup/modal window :

     const [IE, setIE] = useState(false);
     const [chrome, setChrome] = useState(false);
     const [openerWindow, setOpenerWindow] = useState(null);
    
      useEffect(() => {
       const handler = event => {
        if (typeof event.data !== 'undefined') {
        document.getElementById('received-message').innerHTML = event.data;
        }
        };
    
       window.addEventListener('message', handler);
       setIE(/*@cc_on!@*/ false || !!document.documentMode);
       setChrome(
      !!window.chrome && (!!window.chrome.webstore || !!window.chrome.runtime)
       );
    
       setOpenerWindow(window.dialogArguments);
    
       // clean up
       return () => window.removeEventListener('message', handler);
      }, []);
    
    
      const handleSubmit = evt => {
        evt.preventDefault();
    
       if (IE) {
         openerWindow.postMessage(
          message,
         'http://localhost:3000/postMessage.html'
         );
        } else {
             window.opener.postMessage(
             message,
            'http://localhost:3000/postMessage.html' );
        }
       };