Prompting a User to Save When Leaving a PageBy Scott Mitchell
|After Reading This Article...|
After reading this article, check out Using ASP.NET to Prompt a User to Save When Leaving a Page,
which shows how to extend the |
As a user, is there anything more frustrating than spending several minutes entering or changing data into a form, only to have it not be saved for one reason or another? It's annoying when it's the software's fault - such as the database server being down - and embarrassing when it's your own fault - such as closing the window before clicking the "Save" button, or clicking on a link on the page and being whisked away to some other page prior to saving the changes. Recently I was working on a project for a client that essentially moved a company's data collection from a paper-based office to an electronic-based office. Namely, the standard pages of information employees were once required to fill out, were replaced with Web pages accessible through the company's intranet.
One common theme that kept resurfacing during the testing of the application was that many of the employees, especially those with limited experience with computers, found themselves going to a page to edit some pre-entered data, making the changes, and then either closing their browser or moving to another page before hitting the "Update" button. As you can guess, doing this didn't save their changes, which led to confusion first, then embarrassment, and finally frustration. (It also didn't help that many of these pages had several dozen input fields, with "Update" buttons only at the top and bottom of the page. So if a user visited a page, scrolled down a bit and made some changes, they'd have to know/remember to scroll back to the top or bottom of the page and click the "Update" button to save the changes.)
To help surmount this problem of leaving a page after making changes, I utilized the
event. This client-side event, which works in Internet Explorer and FireFox version 0.9 and up,
is fired prior to the
onunload event, which fires when the body is being unloaded (either through the
browser being closed or the user navigating to a different URL). Using the
event, you can create an event handler that, if it returns a string, will display a prompt to the user when leaving the page,
asking them if they are sure they want to leave the page. Using this technique I was able to present the users with a
warning if they attempted to leave the page without saving their data.
In this article we'll look at the
onbeforeunload event and how you can use it to provide a similar warning
to your users when leaving a page from which they need to save their changes. We'll see two working examples: a naive one,
that always displays a confirmation dialog, and a more intelligent one that only displays a confirmation dialog box if
the user has, in fact, changed one or more of the form fields on the page. Read on to learn more!
A Simple Approach: Warn the User Whenever They Are Leaving the Page
One downside of this approach is that any action that causes the page to be unloaded - including the submission of
a form - will display the dialog box shown above. In the live demo, you might have noticed that when the user clicked the
Save button they were given the same dialog box as when they clicked on a hyperlink, or closed their browser. To prevent
this, we need to make our
onbeforeunload event handler a bit more intelligent. There are a couple of techniques
that can be used, the simplest (to me) being the following:
needToConfirm, with a default value of
- In the
onbeforeunloadevent handler, if this variable has a value of
true, then the event handler returns the message to display in the dialog box. If it has a value of
false, then the event handler returns nothing, which causes the browser to not display a dialog box, but rather just send the user onto the requested page like normal.
- Finally, in the submit button's
onclickevent, we want to set the
Prompting the User Only When Changes Have Been Made
The approach just examined is a bit naive in that it prompts the user if they are certain if they want to leave the page regardless of whether or not any data has been changed on the page. That means that even if the user hits the page to quickly check a few values, does so, and then attempts to close her browser, she'll be shown a dialog box asking her if she's certain she wants to leave the page. This can, no doubt, be annoying for a user. Ideally, a user would only see this dialog box if they went to a page, changes some data entry fields, and then attempted to leave the page without having clicked the Save button.
the page has loaded that saves the values of the data entry controls in an array. In the
onbeforeunload event handler,
this array is scanned to determine if there are any changes between the current data entry fields and their saved values in the
array. If there are any discrepancies, then the event handler returns a string, displaying the confirmation dialog box; otherwise,
the event handler returns nothing, allowing the user to leave the page as they'd expect.
In practice, I accomplish this using two arrays. One array that holds the
IDs of the data entry
form fields, and one array that holds their values. Let's look at the needed client-side script in two pieces. First,
let's look at saving the form fields' initial values when the page is loaded.
Notice that I created two arrays,
ids array has six string
entries, which correspond to the six data entry form fields in the live demo.
values array will hold a value for each form field, so it is created with six blank string values.
Next, in the
populateArrays() function, the
ids array is looped through and the HTML elements
are programmatically referenced via the
document.getElementById() function. For radiobuttons and checkboxes,
checked property is saved in the
values array; for other form fields (textboxes, drop-down lists,
value property is saved.
One important thing to note is that the
populateArrays() function is called after the form fields have been
spelled out. It's important that you call this function so that the form fields' values are saved in the array. It's vital
that this call occur after the form fields have been defined, otherwise the function will not succeed in saving the
initial values, as it will try to access the form fields before they have been received by the browser.
The second task we are faced with is modifying the
onbeforeunload event handler so that it only returns
a string if there is a discrepancy between the actual form field values and the initial form field values (which were
saved for us in the
values array). To accomplish this, I simply loop through the elements in the
values array and see if there is a mismatch between it and the actual value. If so, I return the message
to display in the dialog box. Otherwise, I continue looping. If no mismatches are found, the event handler simply exits
without returning anything, thereby allowing the user to leave the page without an unnecessary dialog box.
That's all there is to it! As you can see in the live demo, the dialog box is only displayed if one (or more) of the form fields have changed from the first page visit.
Conclusion... and Moving Forward...
At this point we have examined the
onbeforeunload event can be used to display a confirmation dialog box
when the user is attempting to leave the page after having made changes to the form fields but before saving the data.
There are still a couple of improvements we can make here. First off, if you attempt to use this code in an ASP.NET Web
page that has LinkButtons you'll find that when a user clicks a LinkButton they are, as you might expect, asked if they
are sure they want to leave the page. If they click OK, however, they are asked again. This has to do with
the fact that the LinkButton's
Another shortcoming is that to apply the more intelligent means of prompting when exiting only if there have been changes,
we have to write client-side code that includes a list of all of the
IDs of all of the data entry form fields.
This can be difficult since the client-side
ID of an ASP.NET Web control is dependent on whether or not its inside
other controls. (For example, a checkbox with a server-side
ID property value of
placed within a DataGrid might have the final client-side
in an upcoming article, all of this can be handled for us behind the scenes, boiled down to one line of code per Web control
in the data entry section.