My
earlier posting illustrated how one can easily trap the
beforeunload event and decide whether to display a message to the user that exiting the page without first saving the data will result in all unsaved work being lost.
But then I discovered that it was not working properly on my web page. Whenever any of the command buttons - Add, Delete, Move, and Save - were pressed,
beforeunload was fired and I would be warned about leaving the page.
This was most confusing because I knew I wasn't leaving the page! But I intuitively knew that there's always a logical explanation so it was just a matter to find it. As I frequently do, I posted a few messages on the
ASP.Net Forums. A very bright developer from Portugal named
Luis Abreu responded and provided me some sample code. I ran it and
his code ran perfectly. So why on earth was mine not working?
On my page I added a simple button, like Luis had done, to force a partial page postback. Pressing it did NOT force the
beforeunload event to fire! WTF?!?
I stared at my web page for some time and suddenly realized what the problem was. Those aforementioned command buttons are not sitting directly on the page but instead reside in a
Draggable Panel. Also, the Move button causes a
Modal Panel to appear. While both of these panels are technically "on the same page", from the perspective of
beforeunload I suppose they are not.
So what to do? I thought about it for a second and realized that with each of these buttons I could use the local 'OnClientClick' event to temporarily disable the beforeunload check. With this goal in mind I added this JavaScript function:
function ToggleBeforeUnload(onOff)
{
if (onOff == true)
{
window.onbeforeunload = ConfirmExit; // Activate beforeunload event handler
}
else
{
window.onbeforeunload = null;
}
}
So now, when any of the buttons are pressed, the first thing that occurs is that the
beforeunload handler is turned off. But it had to be reactivated. To accomplish this I added a call to this function at the end of each button's server-side method:
private void ToggleBeforeUnload(bool onOff)
{
ScriptManager.RegisterClientScriptBlock(this, typeof(Page), "toggleBeforeUnload", "ToggleBeforeUnload(" + onOff.ToString().ToLower() + ");", true);
}
It calls the same JavaScript function described earlier. And sure enough, it works perfectly!
Incidentally, blessed is the Internet for helping out developers! I distinctly remember the days when there was no Internet. I'm absolutely convinced that it has dramatically improved the productivity and learning curve of developers around the world.