An Update on Prompting a User to Save When Leaving an ASP.NET PageBy Scott Mitchell
Several months ago I wrote an article here on 4Guys titled Using ASP.NET to Prompt a User to Save When Leaving a Page, which, as its name implies, provides a technique for alerting a user when they're about to leave a Web page that has "unsaved" data. Specifically, the article looked at using the
onbeforeunloadclient-side event, which fires whenever a Web page is being exited, be it through the user closing the browser window, clicking on a bookmark, clicking on a link in the Web page, or any other task that would cause the Web page to unload.
With some clever client-side programming you can use
onbeforeunload to display a modal dialog box whenever
the user is about to leave a page whose content they have changed but have yet to save the changes. This is an especially
handy technique for applications that will be used by people who are not Web-savvy users, and might not realize that they
need to click some sort of Save button in order to save the changes they made.
Over the months since the original article's publication I have received a number of questions from interested readers.
In this article I plan on addressing the two most popular questions: dealing with auto-postback Web controls (such as
DropDownLists or CheckBoxes with their
AutoPostBack property set to True); and how to prevent "Unspecified error"
script errors that can creep up depending on how, exactly, the page was unloaded. Read on to learn more!
A Quick Summary of the Prompting Technique
If you've not yet read the article Using ASP.NET to Prompt a User to Save When Leaving a Page I'd encourage you to do so now, along with the article Prompting a User to Save When Leaving a Page. The Prompting a User to Save When Leaving a Page article introduces the
onbeforeunloadevent and examines how to utilize it to prompt the user when exiting a page. The article Using ASP.NET to Prompt a User to Save When Leaving a Page illustrates how to apply this technique to an ASP.NET page and covers issues and workarounds that certain ASP.NET controls, such as LinkButtons, raise.
The basic premise for the two previous articles was that we had a Web page with various data-entry fields that contained existing data the user had entered. In addition to the data-entry fields, there was some sort of "Save" button at the bottom of the page. The workflow for this page would be as follows: if the user wanted to change some data, they'd visit this page, update the appropriate data-entry fields, and click the Save button. The aim of the previous articles was to examine a means to prevent the user from visiting the page, making some changes to the data-entry fields, then accidentally leaving the page prior to saving those changes. In order to help prevent mistakenly leaving a page before saving, the previous articles illustrate how to have the user prompted with a modal dialog box upon leaving a page with changed data-entry values.
To quickly summarize, the prompting technique works via the client-side
onbeforeunload event, which, in modern browsers,
fires immediately prior to the document unloading. To actually prompt upon exit you need to wire up this event to an event
handler. If the event handler returns a string, that string is displayed in a modal dialog box, like the one shown to the right.
This dialog box informs the user that they are about to leave the page and presents two buttons, OK and Cancel. The user can
click Cancel to stay on the current page (thereby giving them an opportunity to save the unsaved data, if needed), or can click
OK to continue exiting the page.
Of course we don't want this dialog box to popup every time the user leaves a page. Rather, we only want the user to
be prompted if they are leaving the page after they had changed the values of one or more input fields on the page without
clicking the Save button to commit their changes. To accommodate this, client-side script is used to record the initial values of
those input fields that need to be monitored. In the
onbeforeunload event handler these initial values are compared
against the current values. If there are any discrepancies, a string is returned, thereby displaying the prompt to the end user.
The article Using
ASP.NET to Prompt a User to Save When Leaving a Page introduced a base class for ASP.NET code-behind classes that contained
methods to mark particular input Web controls for being monitored, as well as indicating that particular Web controls should
not cause a prompt when they induce a postback (such as the Save button itself).
Suppressing the Prompt for Button Web Controls
onbeforeunloadevent fires every time a page is unloaded, including when it is posted back. For example, imagine that a user comes to the page, makes some changes to the data-entry fields, and then clicks the Save button. Clicking Save will cause a postback, thereby causing
onbeforeunloadevent to fire, which causes the associated client-side event handler to execute. This client-side event handler will notice that the data-entry values have changed since the page was initially loaded and will therefore return a string, causing the user to see the prompt. However, if the user is clicking Save we need to suppress this prompt, since even though the page is being unloaded, it's being unloaded to save the changes.
In Prompting a User to Save When Leaving a Page we saw
event handler: if the flag had a value of
true then the comparison of the input values proceeded and the prompt
was displayed if there was a discrepancy; if the flag had a value of
false, this check was circumvented, and no
prompt was displayed, regardless of whether or not there were any changes in the data-entry input values since the page's
the button's client-side
onclick event that set this flag to
This concept was taken one step further in Using ASP.NET to Prompt a User to Save When Leaving a Page
through the introduction of two server-side methods:
prompt (by setting the flag to
BypassModifiedMethod(WebControl) accepts a Web control
instance as input and sets its client-side
Typically this method will be called passing in a Button Web control instance for those buttons that, when clicked, should
not cause a prompt to be displayed, even if the data-entry form fields' data had been modified. (As mentioned earlier,
typically you'll want to suppress the prompt for the Save and Cancel buttons on the page.)
Suppressing the Prompt for AutoPostback Web Controls
Since publication of Using ASP.NET to Prompt a User to Save When Leaving a Page one of the most common questions I've received has been, "I have a DropDownList Web control on my page that has its
AutoPostbackproperty set to True. Whenever a user makes a change in this DropDownList the user sees the 'Data on this page has changed' prompt. How can I prevent this?" This question applies not only to DropDownLists but to any Web control whose
For the CheckBox and RadioButton the client-side
onclick event can be used to set this flag to
false, meaning that you can simply call the
BypassModifiedMethod(WebControl) method, passing in the CheckBox or RadioButton instance. For the
DropDownList you want to set the flag to
false on the client-side
onchange event. To accomplish
this you could create an additional server-side method similar to the
method, but that sets the
onchange event instead, or you could just use the following single line of code:
That's all there is to it!
Suppressing "Unspecified error" Client-Side Script Errors When Using
eval()statement and clicking the Cancel button in the prompt. If a page is exited through client-side script - like
onbeforeunloadevent will fire, as expected. The associated event handler will run, checking to see if the data-entry values have changed. If they have, a string will be returned, causing the prompt to be display. Now here's where the script error creeps up: if the user clicks OK, indicating that they want to page to continue unloading, everything works fine. But if the user clicks Cancel, indicating that they want to stop unloading the page, Internet Explorer throws up an "Unspecified error" script error.
This script error only occurs when attempting to unload a page through an
eval() statement, and only in Internet
Explorer (things work smoothly in FireFox). The workaround I've found is to place the
eval() statement in a
try...catch block, like so:
By using a
try...catch block the "Unspecified error" script error will be suppressed. Not the most graceful
workaround, but it's one that works and the only one that I could find.