3

I'm trying to implement a "Unsaved changes" warning in my web application but I'm struggling to get this working properly. I know about the existence of onbeforeunload event in javascript, but I was requested to use a custom div with some fancy formatting as a modal popup to prompt the user about those unsaved changes.

What I've got so far is this:

Basically what it does is bind a function that would check if the page is dirty and prompt the user with the popup before clicking any link or button, etc that could cause a postback. One of the problems I'm having right now is that all the cancelled events seem to be running when I press continue, instead of just the last one.

I know it is not the best solution, but it is the only thing that came to my mind. Better ideas are welcome :)

jQuery function to bind an event before all the others:

$.fn.bindFirst = function(name, fn) {
    this.bind(name, fn);
    var handlers = this.data('events')[name.split('.')[0]];
    if (handlers.length) {
        var handler = handlers.pop();
        handlers.splice(0, 0, handler);
    }
};

function hideSaveWarning() {
    $("#divSaveWarning").hide();
}

This will set the continue button to do the cancelled action

function showSaveWarning(e) {
    $("#divSaveWarning").show();
    $("[id$='_btnContinue']").click(function() {
        e.currentTarget.click();
    });
}

function onClickContinueWithoutSaving() {
    hideSaveWarning();
    setDirtyContent(false);
}

function SetSavePrompt() {
    setDirtyContent(false);
    $(":input, :radio, :button, a").not("[id$='_btnSave']").bindFirst('click', function(e) {
        if (isPageDirty) {
            showSaveWarning(e);
            return false;
        }
    });
}

Thanks. Regards.

Tute
  • 6,943
  • 12
  • 51
  • 61

2 Answers2

3

Would this do the trick?

http://mal.co.nz/code/jquery-dirty-forms/

Pierre
  • 1,252
  • 1
  • 14
  • 24
1

I haven't tested this, and it will probably require some tweaking, but you should be able to do something like this:

JavaScript:

<script language="javascript" type="text/javascript">              
    var formChanged = false;
    window.onbeforeunload = function() {
        if(!formChanged){
            return;                                   
        }
        return confirm("You have made changes to this form. Do you want to continue without saving these changes?");           
    }        
    function  setDirty() { 
        formChanged = true; 
    }                                
</script> 

Code-behind:

protected void RegisterClientSaveChangeHandler()
{
    foreach (Control ctrl in Page.Controls)
    {
        if (ctrl != null)
        {
            //make sure it doesn't prompt for save if it's a button click
            if (ctrl is Button | ctrl is LinkButton | ctrl is ImageButton | ctrl is HyperLink)
                ((WebControl)ctrl).Attributes.Add("onclick", "javascript:formChanged=false;");

            //make sure that all user input fields register for prompting when the value changes
            if (ValidateAsInput(ctrl))
                ((WebControl)ctrl).Attributes.Add("onchange", "setDirty()");                
        } 
    }                     
}

private bool ValidateAsInput(Control ctrl)
{
    return ctrl is TextBox | ctrl is CheckBox | ctrl is RadioButton | ctrl is DropDownList | ctrl is RadioButtonList;                
}
James Johnson
  • 45,496
  • 8
  • 73
  • 110
  • Thanks for your answer, but it is not quite what I asked because you are using the onbeforeunload and as far as I know you cannot show a custom div instead of the default popup from the browser. Am I right? – Tute Oct 05 '11 at 19:18
  • You can use a custom div if you'd prefer; you just need to have some type of yes/no/true/false input from the user to tell the browser not to post back. – James Johnson Oct 05 '11 at 19:20
  • This will not work. The confirm call is not allowed in the event handler of `onbeforeunload`. See http://stackoverflow.com/questions/276660/how-can-i-override-the-onbeforeunload-dialog-and-replace-it-with-my-own, http://stackoverflow.com/questions/12132060/confirm-on-window-onbeforeunload or http://stackoverflow.com/questions/1335727/onbeforeunload-confirmation-screen-customization – qff Apr 11 '14 at 11:59