Confirm leaving the page in an ArcGIS web app builder

107 views Asked by At

I created an app with ESRI ArcGIS Web App Builder. Now I want to ask the user if he wants to leave the page any time he clicks the forward or back button of the browser or if he refreshes the page.

I tested a couple of solutions but none works properly.

Solution One

add the following in the index.html found in the root folder of the app, right after all the other js scripts imports - I add it right above the </body> tag

<script type="text/javascript" src="init.js"></script> 
<script type="text/javascript" src="setLeavingConfirm.js"></script>   
</body>

then, inside the setLeavingConfirm.js I have the following:

 (function setCOnfirm() {
    window.addEventListener('beforeunload', function(e) {
        e.preventDefault()
        return 'Are you sure you want to leave? Changes will not be saved';
    }, {capture:true});//

  window.addEventListener('popstate', function(event) { 
      event.preventDefault()
      let r = confirm("Leave site? Changes you made may not be saved"); 
      if (r == true) { 
          history.back(); 
      } else { 
          history.pushState(null, null, window.location.pathname);
      }
      history.pushState(null, null, window.location.pathname);
  }, false );
})();

Solution Two

In the root folder of the app and then in jimu.js folder, there is the main.js file.

Inside that file, at the top of the initApp() function I add

  on(window, 'beforeunload', function(e){        
    e.preventDefault()
    return 'Are you sure you want to leave? Changes will not be saved';
  }, {capture:true});

  window.addEventListener('popstate', function(event) { 
      event.preventDefault()
      let r = confirm("Leave site? Changes you made may not be saved"); 
      if (r == true) { 
          history.back(); 
      } else { 
          history.pushState(null, null, window.location.pathname);
      }
      history.pushState(null, null, window.location.pathname);
  }, false );

This is based on the on event of dojo.

As I said, both kind of work. For them to work I have to first hit Control + Shift + R on my keyboard to delete the cache. Otherwise I can leave the page without being asked first.

How can I fix either, so I get asked before leaving the page?

1

There are 1 answers

0
VonC On

Using the beforeunload and popstate events to prompt the user to confirm leaving the page should work.
But: not all browsers handle these events in the same way, and some (possibly Safari) may ignore the beforeunload event entirely if they deem it to be used for displaying a "blocking" message.

Regarding your issue with the cache, you could try adding the following code to your setLeavingConfirm.js file to disable caching:

// Disable caching
$(document).ready(function() {
  $.ajaxSetup({
    cache: false
  });
});

That would use jQuery's $.ajaxSetup() method to disable caching for all AJAX requests made by the app.

And for the issue with the beforeunload event not being triggered consistently, you could try using a different approach to handle the back button navigation. For instance, try and use the hashchange event instead of the popstate event.

(function setConfirm() {
  // Disable caching
  $(document).ready(function() {
    $.ajaxSetup({
      cache: false
    });
  });

  // Add event listener for beforeunload event
  window.addEventListener('beforeunload', function(e) {
    e.preventDefault();
    return 'Are you sure you want to leave? Changes will not be saved';
  }, {capture:true});

  // Add event listener for hashchange event
  window.addEventListener('hashchange', function(event) {
    let r = confirm("Leave site? Changes you made may not be saved");
    if (r == true) {
      history.back();
    } else {
      history.pushState(null, null, window.location.pathname);
    }
    history.pushState(null, null, window.location.pathname);
  }, false);

  // Prevent hashchange event from firing on initial load
  setTimeout(function() {
    window.onhashchange = null;
    window.onhashchange = function() { /* do nothing */ };
  }, 0);
})();

That would add an event listener for the hashchange event, which is fired whenever the hash fragment of the URL changes (e.g. when the user clicks the back button). The code then displays a confirmation dialog to the user, and if the user clicks "Cancel", it prevents the page from navigating away by pushing the current URL onto the history stack.

Warning: if it works, it might work "too well", and some users may find it annoying to be prompted every time they try to leave the page. You might want to consider adding a flag to disable the confirmation dialog if the user has already saved their changes.