1

I have a web site that contains several pages where the user can add and edit information. In order to provide a consistent UI, I have the following JavaScript function...

function setWindowBeforeUnload(changed) {
  $(window).on("beforeunload", function() {
    if (confirmLeave && changed && changed()) {
      return "You haven't saved the information. If you leave this page, the information will be lost.";
    }
  });
}

confirmLeave is a global variable that specifies if we are to ask them for confirmation before navigating away (which we don't if we are navigating to another page after a successful save). changed is a function that checks if the entity has changed.

This is called from a details page (say the customer page) as follows...

$(document).ready(function() {
  setWindowBeforeUnload(customerChanged);
});

function customerChanged() {
  // Checks the data and returns true or false as appropriate
}

This all worked fine until recently, when a change in Chrome broke it.

I have searched for hours, and found loads of people suggesting code like this...

addEventListener('beforeunload', function(event) {
  event.returnValue = 'You have unsaved changes.';
});

...which works fine as it is, except that it fires the warning whenever they leave the page, irrespective of whether or not the data has changed.

As soon as I try to add any logic (such as my checking code in the first sample), it doesn't work...

function setWindowBeforeUnload(changed) {
  addEventListener('beforeunload', function(event) {
    if (confirmLeave && changed && changed()) {
      event.returnValue = 'You have unsaved changes.';
    }
  });
}

With this code, I can navigate away from the page without getting a warning.

Is there any way to reproduce my original behaviour now?

DreamingOfSleep
  • 1,208
  • 1
  • 11
  • 23
  • Put this in your `beforeunload` handler. `const shouldLeave = confirm('Are you sure you want to leave the page?');` – Olian04 Jan 25 '18 at 18:34
  • I think it has to be `window.addEventListener('beforeunload', function(event) {..`, I do not see `window` in your code – brk Jan 25 '18 at 18:36
  • Chrome (and Firefox) specifically make it impossible to add a custom message. You can't do that. – SLaks Jan 25 '18 at 18:37
  • @Olian04: There is no way to prevent the unload. – SLaks Jan 25 '18 at 18:37

1 Answers1

1

You can use logic in the handler, you just can't have a custom message any more. See the code below. Use the "Run code snippet" to simulate navigation. Run the snippet, run it again no confirm. Toggle the button to "false" run the snippet and get a confirm.

var test = true;

function otherTest() {
  return true;
}

addEventListener('beforeunload', function(event) {
if(!test || !otherTest()) {
  event.returnValue = 'You have unsaved changes.';
}
  
});

document.getElementById('theButton').addEventListener('click', function(event) {
  test = !test;
  this.innerHTML = test.toString();
});
<p>Click the button to turn the confirm on and off</p>
<button id="theButton">true</button>
gforce301
  • 2,944
  • 1
  • 19
  • 24
  • Thanks for that. It turned out that the reason my code wasn't working was because another developer had added some elements with the same IDs as existing ones, and had added another `customerChanged()` method. That second method was being called instead of the original, and was failing silently due to the duplicate IDs. Once I renamed the IDs and method, it all worked fine. Thanks again. – DreamingOfSleep Jan 25 '18 at 21:29