views:

4558

answers:

5

I have an AJAX-based grid control.

We hook into the window.onbeforeunload event to check if they have unsaved data and if so present them with a message "Are you sure you want to navigate away...you have unsaved data...".

All this is good.

But AJAX calls also trigger window.onbeforeunload and so if the grid has unsaved data and we make an AJAX call (such as to delete a row in another grid) the user gets the "Are you sure you want to navigate away...you have unsaved data..." message which is not good.

Is it possible to suppress the onbeforeunload event for AJAX calls? Or is it possible to detect that a call is an AJAX call? Otherwise we'll have to get hacking!

Thanks

+1  A: 

This is really weird, are you sure your Ajax call isn't loading a new link?

Be sure you read this relevant specification: onbeforeunload spec

See if the Ajax call maybe triggers any of the actions listed in the To invoke table.

Luca Matteis
Thanks. Read the spec and it references "document.write" under "To invoke". That is certainly happening a bunch with the grid library we're using.
Paul
A: 

If you're talking about ASP.NET AJAX partial postbacks, then I encountered this behavior today too, doing the exact same thing. (If you're not, ignore my post completely.)

In my experience so far, it seems like if your partial postback is triggered by an input, it won't fire onbeforeunload during a partial postback, but if the partial postback is triggered by a hyperlink, it will. It seems like the browser assumes you're navigating away if you click on anything in an anchor tag (only tested in IE and FireFox but yeah).

Whether or not the page has a certain hidden field is already what I was using to determine client-side when it's appropriate to show the navigate away warning, so I was able to fix this very simply by adding a check of the hidden field's value to my onbeforeunload's if condition, and hooking into the PageRequestManager's BeginRequest and EndRequest handlers to set the value. That effectively disables the warning during partial postbacks. You could add more complicated logic here if there were more specific things you wanted to check.

Here's a really over-simplified code sample. (sorry if i pared and censored to the point where it doesn't work but it should give you an idea.)

window.onbeforeunload = checkNavigateAway;

Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(onBeginRequest);
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(onEndRequest);

function onBeginRequest(sender, args) {
    var navigateAwayFlag = $("input[id*='navigateAwayValue']");
    if (navigateAwayFlag.length > 0) {
        navigateAwayFlag[0].value = "false";
    }
}

function onEndRequest(sender, args) {
    var navigateAwayFlag = $("input[id*='navigateAwayValue']");
    if (navigateAwayFlag.length > 0) {
        navigateAwayFlag[0].value = "true";
    }
}

function checkNavigateAway() {
    var navigateAwayFlag = $("input[id*='navigateAwayValue']");
    if (navigateAwayFlag.length > 0 && navigateAwayFlag[0].value == "true")
    {
        return "Warning Text";
    }
}

Edit: Bad news. The above doesn't seem to work in IE6. It seems like it fires events in a different order than Firefox, so the onbeforeunload fires before the AJAX beginRequest... May have to find a way to change the flag's value via the hyperlink click before the onbeforeunload fires.

Grank
A: 

I did something like this:

inside body tag:

  var allowConfirm = true;

  window.onbeforeunload = confirmExit;
  function confirmExit()
  {
    if(allowConfirm)
        return "Are you sure you want to navigate away from this page?";
    else
        allowConfirm = true;
  }

When I Logout, I call this script:

allowConfirm = false; return window.location.href;

Arpit
+3  A: 

If you want to trigger your postback by a hyperlink, there is a simple workaround: Instead of

<a href="javascript:submitFunction();">Submit</a>

or

<a href="javascript:;" onclick="submitFunction();">Submit</a>

just use this code:

<a href="#" onclick="submitFunction();">Submit</a>

It seems that IE fires the onbeforeunload event if the content of the href-attribute of a hyperlink is not the current page (which the sharp character indicates).

cygro
A: 

This actually works:

 OnClientClick="eval(this.href);return false" 
Shawn Simon