on window close, not beforeunload

I have a parent window which has a button which launches a popup window. The first thing the popup window does is to mask-out the parent window so that no data can be entered while the popup is open. The popup window is like a wizard which presents a series of forms with PREVIOUS and NEXT buttons. When the last form is presented, there is a FINISH button. When the user clicks on the FINISH button, the mask-out is removed from the parent window and then the popup window closes. This works perfectly. The only problem is, what happens if the user closes the window prior to reaching the FINISH button? Well, the parent window remains masked-out. I tried adding the following bit of code to the popup window.
  window.addEventListener('beforeunload', function () { 
     window.opener.document.getElementById("modalDivBackDrop").classList.remove("slds-backdrop--open");
   });

Open in new window

It works nicely when the user closes the popup window. Unfortunately it also triggered when the user hits the NEXT button. The NEXT button looks like:
<input id="j_id0:j_id1:i:f:pb:pbb:next" type="submit" name="j_id0:j_id1:i:f:pb:pbb:next" value="Next" style="visibility: visible;" class="btn FlowNextBtn">

Open in new window

I don't understand why the 'beforeunload' event is being triggered by the NEXT button.
I've tried various ways of unbinding the 'beforeunload' event from the <FORM> but no luck.
What do I need to do in order to unmask the window.opener.document when the user closes the popup but not when they click on the NEXT button.
Thanks
LVL 3
mmooreAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

mmooreAuthor Commented:
I have solved my problem by using MutationObserver. I trap it when somebody changes the class on the DIV which causes the shield to drop. I then test if the popup still exists. If Yes, then I put the shield back down. Shield down means:

 window.opener.document.getElementById("modalDivBackDrop").classList.remove("slds-backdrop--open");

So rather that find the source of the problem and prevent it, I have chosen to monitor the symptom and fix it.
0
Julian HansenCommented:
You need to post a message the parent window.

Parent
CSS
<style type="text/css">
.overlay {
  background: rgba(0,0,0,.85);
  position: fixed;
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 10000;
}
</style>

Open in new window

HTML
	<button>Click Me</button>

Open in new window

JavaScript
<script>
$(function() {
  $('button').click(function() {
    $('body').append($('<div/>', {class: 'overlay'}));
    window.open('t2196child.html');
  });
});
window.addEventListener('message', function(e) {
  console.log(e.data);
  $('.overlay').remove();
}, false);
</script>

Open in new window

Child
<!doctype html>
<html>
<body>
<h1> Close this form</h1>
<script>
window.addEventListener('beforeunload', function() {
	window.opener.postMessage("done", window.location.href);
});
</script>
</body>
</html>

Open in new window

Working sample here
0
mmooreAuthor Commented:
I should have made it more clear that the NEXT button is also triggering a 'beforeunload' event, and I can't change this because it's part of a visual flow (salesforce) embedded in a visualforce page. I don't need need anybody to look at this, but I am posting in just in case anybody is interested.
<apex:page showheader="false" sidebar="false">
<flow:interview name="New_Account_Wizard"></flow:interview>
<!-- New_Account_Wizard is a multi page flow with a form on each page -->
<!-- so at different stages of the flow the DOM will look different -->   
<script>

   window.onload = function () {
     var frm = document.getElementById('j_id0:j_id1:i:f');
     // do this only if the target FORM is on the curent page
     if (typeof(frm) != 'undefined' && frm != null)
     {
     
        var accountNameField = document.getElementById('j_id0:j_id1:i:f:pb:d:Company.input');
        // do this only if the target accountNameField is on the curent page
        if (typeof(accountNameField) != 'undefined' && accountNameField != null)
        {
           // Load the local Storage when the user hits the NEXT button. NEXT button does SUBMIT and goes to next page
           frm.addEventListener('submit',function(evt) {
               localStorage.setItem('AccountName', document.getElementById('j_id0:j_id1:i:f:pb:d:Company.input').value);
           });
        }
     }
     
     var finishBtn = document.getElementById('j_id0:j_id1:i:f:pb:pbb:finish');
     if (typeof(finishBtn) != 'undefined' && finishBtn != null)
     {
        // override the FINISH button on the last screen of the wizard. If you dont,
        // the natural behaviour is to restart the wizard at page one.
        finishBtn.addEventListener('click',function(evt2) {
            evt2.preventDefault();
            //console.log (document.body);
            //var list = (opener.document.body)
            
            // Remove backdrop which is covering the parent window
           // window.opener.document.getElementById("modalDivBackDrop").classList.remove("slds-backdrop--open");
            //console.log (list);

            window.close();
        });
     }
   }

    
 window.addEventListener('beforeunload', function () { 
 
    window.opener.document.getElementById("modalDivBackDrop").classList.remove("slds-backdrop--open");
    console.log('opened backdrop from popup window');
  });

</script> 
</apex:page>

Open in new window


The "<flow:interview name="New_Account_Wizard"></flow:interview>" basically injects a Visual Flow ( a multi form multi page web based app) at this point. This app has a NEXT button on it with takes the user to the next page but it ALSO also triggering a 'beforeunload'. I don't want to unmask the parent window each time the user hits the NEXT button. I only want to unmask  the parent window when the user actually closes the popup. Anyway, I've actually solved my problem albeit a bit hacky.  I'll leave this open for now just in case there is some solution that allows me differentiate between the user clicking on the close-window X button and hitting the NEXT button.
Capture.PNG
0
Big Business Goals? Which KPIs Will Help You

The most successful MSPs rely on metrics – known as key performance indicators (KPIs) – for making informed decisions that help their businesses thrive, rather than just survive. This eBook provides an overview of the most important KPIs used by top MSPs.

Julian HansenCommented:
I suspect what is happening is the Next button is calling another page which is what is triggering the beforeunload.

Not sure if this will work
What you would need to do is to attach an event handler to the Next and set a flag to say whether it has been clicked and in the beforeunload check to see if the flag has been set and only remove the background if the flag has not been set (button has not been clicked)
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
mmooreAuthor Commented:
Awesome idea. I'll try that. It's a good technique. I doubt, however,  if it is the best solution in this case because the wizard (visual flow) might be changed independent of this usage. I think that each NEXT button might have a different id and if more next buttons get created (more pages to the wizard)  then I would need to update my wrapper to address these new buttons. In fact, that is a weakness that my wrapper (visualforce page shown above) already has. It looks for specific element ids and I have no guarantee  that the next time I generate the visual flow that it will be generated with those same ids.  Thanks for your help!
0
Julian HansenCommented:
I would look for something that identifies the button other than its id - look for a class that you can use - even if it is a sibling you can do a next to get to the Next button.

Otherwise you are welcome.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
JavaScript

From novice to tech pro — start learning today.