Introduction
This code enables a Web page to notify users that they are leaving a page that they have made modifications to. Why is this useful? Well, the previous sentence says it all. We want to notify the user that they have made modifications to a page and ask them if they really want to leave the page. It is assumed that you are familiar with JavaScript, DOM Events, and ASP.NET 1.x or higher. The included project is in Visual Studio 2005.
Background
The idea of notifying users that they are leaving a page that has been modified is not new. There are plenty of sites that explain this process via client-scripting of the onbeforeunload
body event. This article takes that client-side scripting and ties it into the ASP.NET client-side framework.
Using the Code
The core of this article is quite simple. JavaScript does all the magic. All we need to do is tie this JavaScript magic into the ASP.NET client-side submission model. So, as you can see, in the JavaScript object, MySuperDuper
, there is a method called checkForChanges()
. This method gets attached when the script loads the onbeforeunload
event of the body
tag. Why did I call it MySuperDuper
? No reason at all. I thought it sounded geeky cool if such a thing exists.
window.onbeforeunload = function() {
return MySuperDuper.checkForChanges();
}
Here's the full client-side code:
var MySuperDuper = new function() {
var var _this = this;
this.saving;
this.navigateAwayMessage = "You have made some changes which" +
" will be lost if you leave this page. " +
"Do you want to leave this page?";
this.checkForChanges = function() {
if (!_this.saving && typeof(_this.globalChange) !=
"undefined" && _this.globalChange)
{
if(document.all && event)
event.returnValue = _this.navigateAwayMessage;
else
return _this.navigateAwayMessage;
}
}
}
window.onbeforeunload = function() {
return MySuperDuper.checkForChanges();
}
Here's the server-side code to incorporate the JavaScript magic. In my project, I put this in a BasePage
class so that it can be reused in all pages in which you might want to have this functionality. We could have a boolean property on the base page to turn all this functionality on and off as well. For simplicity's sake, I have left something like that out.
ClientScript.RegisterOnSubmitStatement(typeof(BasePage),
"saving", "MySuperDuper.saving = true;");
Now for your control, simply update the MySuperDuper.globalChange
variable to true
. I've used it on a regular HTML text input for simplicity, but you could do this with a server-side control like an <asp:TextBox id="myTextBox" runat="server" />
by adding an attribute in the code file like this:
myTextBox.attributes.Add("onchange", "MySuperDuper.globalChange = true;");
You could also get the ClientID
property and render some JavaScript that attaches a DOM event to do this update as well. There's many ways to slice it.
<!---->
<input onchange="MySuperDuper.globalChange = true;" type="text" />
Also, after getting some feedback from crashedapp (see below), he offered his suggestion to check if there have been changes. Thanks for the feedback. So say crashedapp had his own way of checking for changes, he could just override my method MySuperDuper.checkForChanges
like this:
function yourCustomFunction()
{
}
MySuperDuper.checkForChanges = yourCustomFunction
Points of Interest
It has been tested on Internet Explorer 6+, FireFox, and Safari for Windows. Internet Explorer and FireFox handle navigating away from a page as does Safari, but when you close the browser window and changes have been made, only FireFox and Internet Explorer fire the onbeforeunload
event. Safari just closes the page without notifying you. This appears to be how Safari is designed. Also, this doesn't work in Opera (client-side part). I can't remember if it supports onbeforeunload
or not. Maybe check out this Web site if you really need to get it working in Opera.
This will also work with AJAX. All that you need to manage is when a partial render has come back to the client, you just need to reset MySuperDuper.globalChange
to false
. You can do so using the PageRequestManager
, Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(pageLoadedHandler)
or if you are using a PageMethod
or custom AJAX, just add the code to reset MySuperDuper.globalChange
. to false
. For more information on PageRequestManager
, check out this Web site.
History
- 6th May, 2008: Initial post
- 7th May, 2008: Article content updated