5

This seems like a common question but search is not returning anything.

I have the following code that executes before the page unloads.The problem is if the unload is a postback i do not want to fire my warning to the user but i can't figure out how to differentiate between a postback and a user navigating to another page for example.

// This is executed before the page actually unloads
        $(window).bind("beforeunload", function () {

            if (prompt) {

                //prompt
                return true;
            }
            else {

                //reset our prompt variable
                prompt = true;
            }
        })

Running script in the code behind i.e. if Page.IsPostBack then set prompt is not an option.

Any ideas?

EDIT:

Here is the solution I ended up with:

 function DoNotPrompt() {
              prompt = false;
        }

I then added this to all the controls where the user could do something that result in a post back.

OnClientClick="DoNotPrompt()

Then checked this flag and only returned a string in "beforeunload" if the user was really moving away from the page i.e. not a postback.

I also had to use this code: var magicInput = document.getElementById('__EVENTTARGET');

    if (magicInput && magicInput.value) {
        // the page is being posted back by an ASP control 
        prompt = false;
    }

The reason being i had a custom user control that was a list box and I could not add the above method. So used this to catch that event and set the flag to false.

Not the most elegent solution.

Thanks, Michael

3 Answers3

2

You can capture the submit and reset the onbeforeunload as:

jQuery(function($) {
    var form = $('form'), oldSubmit = form[0].onsubmit;
    form[0].onsubmit = null;

    $('form').submit(function() {       
        // reset the onbeforeunload
        window.onbeforeunload = null;

        // run what actually was on
        if(oldSubmit)           
            oldSubmit.call(this);           
    });
});

This is a tested code from my pages :)

Aristos
  • 66,005
  • 16
  • 114
  • 150
  • how do you check if the page is redirected or postback ? – Royi Namir May 02 '12 at 13:33
  • @RoyiNamir This is capture the submit of the form. If he click on a link is not affected, is not make post back. What is try to archive here is to not show a message on post back. All the rest are count. I use the same code and trick for my pages. – Aristos May 02 '12 at 13:35
  • @MichaelHollywood the only diferent is that I use `window.onbeforeunload = function() {}` and not bind from jQuery. Hope that its work for you. – Aristos May 02 '12 at 13:42
  • No I am still blocked. I should say its not due to above not being correct answer but that the complexity of my problem is greater than my question. The page has a some basic ASP.Net controls, a Grid View where users can add/delete/edits rows, and custom controls. Now a bunch of these will force the page back to the code behind on the server (not just a simple submit) and for each of these the event is fired and caught by the beforeunload. The problem is taht where we are posting back I don't have a need to warn the user. So I need to extend the Submit case to cover all postbacks on this page. – Michael Hollywood May 02 '12 at 15:14
  • @MichaelHollywood all post back are pass from the onsubmit. I do not know what else you have do, or what other way you use to make post back, but this is the trick, just capture all the rest post back with a similar way. – Aristos May 02 '12 at 16:14
  • @Aristos I have a custom user control that I register and use on my page. This user control has a checklistbox and a OnSelectedIndexChanged attached to the list and fires accordingly. Now when the user chanegs the index on the list in the main page $(window).submit(function () {... does not trap it. It traps all the submits on the page itself but not from this control that is added as a reference. jbabey code does catch this. Do I need to do something specific? – Michael Hollywood May 02 '12 at 16:33
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/10804/discussion-between-michael-hollywood-and-aristos) – Michael Hollywood May 02 '12 at 16:39
1

JavaScript runs on the client; as far as the client is concerned, a page does not maintain state from one view to the next. Postbacks are entirely an ASP.NET concept.

You can get around this by running some code on the server-side which defines a JavaScript variable based on whether or not Page.IsPostBack is true.

Example:

<%@ Page Language="C#" AutoEventWireup="true"  %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Page.IsPostBack -> client</title>

    <script type="text/javascript">
        var isPostback = <%= Page.IsPostBack %>;
        console.log("IsPostBack: " + isPostback);
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Button runat="server" ID="btnTest" Text="Click me..." />
    </div>
    </form>
</body>
</html>
Ivan Karajas
  • 1,081
  • 8
  • 14
  • I think that he needs to know that is postback, at the first time, before the post back happens. This works after the first post back on the second one. – Aristos May 02 '12 at 13:34
  • @Aristos. Yes exactly. I want to know before the postback actually happen, so running server side code is too late as the code in the function beforeunload has already executed. – Michael Hollywood May 02 '12 at 13:39
  • My bad. In that case, Aristos's answer looks closer to the mark. – Ivan Karajas May 02 '12 at 13:45
1

This may not cover all of the postback situations, but you can tell if the page was posted back by an ASP control by interrogating the __EVENTTARGET hidden input.

This input is set by ASP when the page is posted back by an ASP control.

var magicInput = document.getElementById('__EVENTTARGET');

if (magicInput && magicInput.value) {
   // the page is being posted back by an ASP control
}
jbabey
  • 45,965
  • 12
  • 71
  • 94
  • @Aristos magicInput will be `null` (falsey) if it was not found in the DOM, and it's value will be an empty string (falsey) if it was found but has not been set. the statement checks that the hidden input exists and has a value. – jbabey May 02 '12 at 13:30
  • Ok, I think its an idea - I just not have test it, must be sure that in all cases the __EVENTTARGET is change before the post back. Here I see that is change on when the __doPostBack is called. – Aristos May 02 '12 at 13:31
  • I tried this but as you say it does not capture all the postbacks for some reason. Such as when a user edits rows in our grid. – Michael Hollywood May 02 '12 at 15:32