Dirty workarouds: dirty page checking + AJAX

Dirty page checking is scenario when you have a form, user does some modifications and before hitting the save button, tries to leave the page. Enterprise web applications have a requirement to intimate the user that "there are unsaved details" and "do you really want to move away from this page".

The idea of solution behind this is 1. use of window.beforeunload and 2. use of onchange to register the window.beforeunload.

As setting window.beforeunload manually for each control can be timeconsuming, we need a generic solution which will work with minimal code changes. If you search for this on internet, you will find the following generic code:

<script type="text/javascript">
function setDirty() {
window.onbeforeunload = showNavigateAwayMessage;
}
function clearDirty()
{
window.onbeforeunload = "";
}

function showNavigateAwayMessage() {
return "There is some unsaved Data in this form."
}

function setControlChangeEvent() {
if (typeof (event.srcElement) != 'undefined') {
event.srcElement.onchange = setDirty;
}
}
document.body.onclick = setControlChangeEvent;
document.body.onkeyup = setControlChangeEvent;
</script>

As usual there are a lof of problems with this generic approach.
Problem 1. An irritating problem is that this gets triggered for each and everycontrol irrespoective of whether you want that control to make the page dirty or not. For example, you might have a dropdown - view - with values barchart and line chart. You might want to change the graph depending on which control is selected. You do not want the change in dropdown to make the page dirty, only make the page dirty when some genuine input changes.
Problem 2: This is more serious than Problem 1 but it is difficult to guess that this problem is caused by this dirty logic. When you use AJAX (similar to MS AJAX) and have a dropdown which causes postback, the AJAX provider typically automatically sets the onchangeproperty to a strange looking dynamically generated javascript. When we use this generic solution, we actually replace this with our onchange function and so the ajax postback is not caused and you are left guessing what went wrong.

There might be other better solutions to these two problems but we used a solution which is a bit quite different worth mentioning. I will explain the basic idea behind the solution here:
We exploited the use of class for this. We used a css class ExcludeDirty. There are quite limited controls in the form for which dirty should not work. So, we modified the setControlChangeEvent to something like below.

function setControlChangeEvent() {
if (typeof (event.srcElement) != 'undefined')
{
if (event.srcElement.className != 'ExcludeDirty') {
event.srcElement.onchange = setDirty;
}
}
}

And then use this class for your contorl

<asp:TextBox ID="UserAlias" runat="server" Text="" MaxLength="21" OnTextChanged="UserAlias_TextChanged" CssClass="ExcludeDirty"/>

Comments

  1. One more dirty workaround for checkboxes:

    event.srcElement.onchange = setDirty;
    This does nto work correctly for a checkbox. As per html standards, the onchange event gets fired for a checkbox when you lose focus of the checkbox either by clicking outside or by tabbing out.

    We had to explicitly call the setDirty function on clientclick event of the CheckBox.

    ReplyDelete

Post a Comment

Popular posts from this blog

ASP Upload and localization