locked
[JS] Ask confirm to exit page with pending changes (onbeforeunload) RRS feed

  • Question

  • User-389939489 posted

    How to ask users to confirm when they try to exit a page other than by submitting the form, and they have pending changes in some form fields?

    The trick is handling the (on)beforeunload page event, which traps any exiting event including a jump command, a back-forward or other navigation command, a reload, a window close...

    The dark side is the onbeforeunload handler is not part of the w3c standard, and up to now it seems to be implemented on IE, FX and NS browsers only. (Actually, it was born as a Microsoft extension.)

    Below is a sample i've tested on IE6 and FX1.0.7.

    Hope this helps, and feel free to ask, comment, extend, or correct...

    Regards. -LV

     

    <html>
       <head>
          <title>onbeforeunload sample (IE, FX)</title>
    
          <script type="text/javascript">
    var UNLOAD_MSG = "You will lose any unsaved changes!";
    
    var IGNORE_UNLOAD = true;
    
    function doBeforeUnload() {
       if(IGNORE_UNLOAD) return; // Let the page unload
    
       if(window.event)
          window.event.returnValue = UNLOAD_MSG; // IE
       else
          return UNLOAD_MSG; // FX
    }
    
    if(window.body)
       window.body.onbeforeunload = doBeforeUnload; // IE
    else
       window.onbeforeunload = doBeforeUnload; // FX
          </script>
    
          <script type="text/javascript">
    function SetTxtFocus(txtId) {
       var oTxt = document.getElementById(txtId);
       oTxt.focus();
       oTxt.select();
    }
          </script>
    
       </head>
       <body onload="SetTxtFocus('MyText')">
          <form action="">
    
    <p><input type="text" id="MyText" value="Change this to trigger"
       onchange="IGNORE_UNLOAD = false"
       onkeypress="IGNORE_UNLOAD = false" /></p>
    
    <p><input type="submit" value="Test submit"
       onclick="IGNORE_UNLOAD = true" /></p>
    
    <p><a href="http://www.google.com">Test jump</a></p>
    
          </form>
       </body>
    </html>
    Sunday, August 6, 2006 3:15 PM

All replies

  • User-503940700 posted

    Nice..and very helpful..!

    But is it submitted to W3C for adoption as a standard?

    -Vivek

    Sunday, August 6, 2006 4:07 PM
  • User457684763 posted

    Thank you for this,its much appreciated. [:D]

    Sunday, August 6, 2006 11:28 PM
  • User-389939489 posted

    vivek_iit> is it [onbeforeunload] submitted to W3C for adoption as a standard?

    Well, i don't know specifically about that. What i can tell is the W3C is trying to develop a standard as much independent from specific technology as they can, and there's also side-issues with accessibility. In fact, XHTML strict doesn't allow anything related to something like a "browser", so not only events like onbeforeunload, but also simple things like the TARGET attribute, because that implies the notion of a browser window. Above XHTML strict there may be more powerful profiles, but i guess W3C experts are still in the process of working out a "standard" framework from the various vendor specific implementations.

    The overall problem with this standardization is rooted into the very history of client-side web development, with early days browsers very different and very forgiving upon the "developer". Anything would be much simpler if they could just start from scratch, but this is not possible and reasonable after all. That recent past has anyway been a rich source of experience and ideas about what a web standard finally should be. So i guess let's just be patient and trust they are doing a great job, as i indeed believe.

    Btw, i guess the widespread attitude amongst programmers in considering client-side programming very simple or even not true programming is the worst side-effect of that past, making it still present...

    -LV

    Saturday, August 12, 2006 1:38 PM
  • User-709018348 posted

    I have the same problem. 

    Actually problem the user has still not exit browser, they link to other pages
    in the website but they always receive the message "You will lose any unsaved changes!". So I only want to display a message when user is closing the Browser (Click "X" button).

    Thank in advance.

    Tuesday, July 3, 2007 10:05 PM
  • User-861818263 posted

     Its Really Good.

     

    Tuesday, February 26, 2008 5:57 AM
  • User795527130 posted

    Hi Ludovico

     I used the following code for the desired effect:

     

    http://www.codeproject.com/KB/ajax/ajaxdirtypanelextender.aspx?fid=447258&df=90&mpp=25&noise=3&sort=Position&view=Quick

    cheers

    tongnom

    Tuesday, February 26, 2008 9:35 AM
  • User-1450431286 posted

    Hey,

    first of all, sorry for my bad English. I hope you can understand, what I need ;)

     I have a ASP.NET Application with one page, where users can setup filter settings. I want to have such a message as described here, but it doesn't work correctly.

     If I add "IGNORE_UNLOAD = true" to the 'textChanged'- or 'checkedchanged'-Event I get the error, that thats not found. So I tried a work-around and did it in the vb-part. I have a invisible checkbox in my contentplaceHolder which is checked, when a setting has changed and unchecked at startup or after saving changes with the buttons. But the problem is, that the javascript-code is executed before the vb-events are...started(?).

    I really need your help.

    I am using Visual Studio 2005 and IE 7. My application has a masterpage which contains a Form. In my page "filter.aspx" is a ContentPlaceHolder, which contains my controls.

    Here is my code:

    <%@ Page Language="vb" Debug="true" MasterPageFile="MasterPage.master" AutoEventWireup="false" validateRequest="false" Inherits="Projecttasks.filter" Codebehind="filter.aspx.vb" %>

    <asp:Content ID="contentOR" runat="server" ContentPlaceHolderID="cphInhaltOR">

        <script type="text/javascript">
            var UNLOAD_MSG = "Ungespeicherte Daten gehen verloren!";
            var IGNORE_UNLOAD = true;

            function doBeforeUnload() {
                var vChange = document.getElementById("ctl00_cphInhaltOR_cbChange").checked;
                var strIsPostBack = theForm.__EVENTTARGET.value;
                var Ergebnis = strIsPostBack.search(/.+bSenden.+/);

                if (strIsPostBack.length == 0 || Ergebnis == -1) {
                    if (vChange) {
                   
                    if(window.event)
                        window.event.returnValue = UNLOAD_MSG;
                    else
                        return UNLOAD_MSG;
                    };
                };
            };

            if(window.body1)
                window.body1.onbeforeunload = doBeforeUnload;
            else
                window.onbeforeunload = doBeforeUnload;

        </script>

        &nbsp;<h1 class="anmeldung">
        <asp:Label ID="lFilterH" runat="server" Text="Konfiguration des persönlichen Filters"></asp:Label>
        <asp:Label ID="lVerantw" runat="server" Text="Name"></asp:Label></h1>
       

     ...a lot of tables, asp:Labels, asp:Checkboxes, asp:Textboxes... if you want I can post it

    </asp:Content>

     

    And the importants part of my VB-Code


        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

            cbChange.Checked = False
     ...

        End Sub


        Protected Sub bSpeichern_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles bSpeichern.Click

            cbChange.Checked = False
     ....
        End Sub


        Protected Sub cbAll_CheckedChanged(ByVal sender As Object, ByVal e As EventArgs) Handles cbAS400Nr.CheckedChanged, _
                                            cbAusfKostSt.CheckedChanged, cbBearbArt.CheckedChanged, cbBelKostSt.CheckedChanged, _
                                            cbDauer.CheckedChanged, cbEigNotiz.CheckedChanged, cbIdentNo.CheckedChanged, cbInfo.CheckedChanged, _
                                            cbKostMKb.CheckedChanged, cbKostOKb.CheckedChanged, cbKunde.CheckedChanged, cbNotiz.CheckedChanged, _
                                            cbProjBeschr.CheckedChanged, cbProjLeiter.CheckedChanged, cbProjPlaner.CheckedChanged, cbProjQW.CheckedChanged, _
                                            cbRessourcen.CheckedChanged, cbSpaltBreit.CheckedChanged, cbVertrAuftrNo.CheckedChanged, _
                                            cbZeitraumBis.CheckedChanged, cbZeitraumVon.CheckedChanged
            cbChange.Checked = True
        End Sub

    If it doesn't work this way, please try to give me another option, but I don't really want to use AJAX, because I have no idea how it works.

    My error-description I get, when I try it like in the first post:

    Compileerror: IGNORE_UNLOAD&quot; is not a member of &quot;ASP.Filter.aspx

    Thank you for your help!!!

    Monday, June 2, 2008 3:40 AM
  • User-1450431286 posted

    Yeah,

    I got it on my own!!! I don't know, whether it's the best way, but it works good:

    Here is my scriptcode:

        <script type="text/javascript">
            var UNLOAD_MSG = "Ungespeicherte Daten gehen verloren!";
            var IGNORE_UNLOAD = false;

            function doBeforeUnload() {
                var vChange = document.getElementById("ctl00_cphInhaltOR_hdCheckedChange").value;
                var strIsPostBack = theForm.__EVENTTARGET.value;

                if (IGNORE_UNLOAD == false)
                {
                    if (strIsPostBack.length == 0) {
                        if (vChange == "true") {
                       
                        if(window.event)
                            window.event.returnValue = UNLOAD_MSG;
                        else
                            return UNLOAD_MSG;
                        };
                    };
                }
                else
                {
                    document.getElementById("ctl00_cphInhaltOR_hdCheckedChange").checked = false;
                };
            };
           

            if(window.body1)
                window.body1.onbeforeunload = doBeforeUnload;
            else
                window.onbeforeunload = doBeforeUnload;

        </script>

     Very important is that the save-button has the onclientclick-event: OnClientClick="IGNORE_UNLOAD = true"

     For all other textboxes and so on I used a HiddenField, which is filled with "true" or "false", depending on the changes:

        Protected Sub rbAll_CheckedChanged(ByVal sender As Object, ByVal e As EventArgs) Handles rb100Ja.CheckedChanged, rb100Nein.CheckedChanged, _
                                            rbDirektJa.CheckedChanged, rbDirektNein.CheckedChanged
            hdCheckedChange.Value = "true"
        End Sub

        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

            hdCheckedChange.Value = "false"
        End Sub

        Protected Sub bSpeichern_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles bSpeichern.Click

            hdCheckedChange.Value = "false"
        End Sub

     

    Note: I used "theForm.__EVENTTARGET.value;" in the script, because, when I got a Postback this returns the ID of the control except for the button. So I know whether I have a PostBack or not.

    I hope it will help someone else!!!

    Greetz from Germany ;-)

    Monday, June 2, 2008 8:20 AM
  • User404561368 posted

     Sorry my english, i hope you undestand.

     E need to execute this code only when the user will try close the window (browser) and not in other's situations. How can i can change the code to do only what i need?

    Thanks,

     

    Thursday, March 5, 2009 8:09 AM
  • User-2093044557 posted

    Very nice work – Thank you. Follow up messages are good. Toraj

    Monday, June 22, 2009 12:22 PM
  • User-68639941 posted
    hi LudovicoVan, good post, actually on close of IE this code asking confirmation, how can i execute some code if user click's ok button Thanks
    Friday, August 7, 2009 7:10 AM