views:

162

answers:

2

I want to show a confirm dialog when the user selects an item in a DropDownList. If the user presses "Cancel", I want to stop the postback. Here is the function I add to the onchange event:

function imitateConfirmUnload(event) {
    if (window.onbeforeunload = null)
        return true;

    return confirm("Are you sure you want to navigate away from this page?\n\nYou have unsaved changes\n\nPress OK to continue or Cancel to stay on the current page.");
}

And this is the relevant bit of code in my startup script to add the handler to the event:

function addConfirmToWarnClasses() {

    $('.warn').change(function() {
        imitateConfirmUnload()
    });
}

The problem is that the postback occurs even if the user selects "Cancel". If I move the handler on to the click event, it works. But it feels clunky to me.

Edit

Correction: it doesn't work onclick, because the dialog prevents selection, so when the user selects OK, no change has taken place, and no postback when you want it!

Edit 2

The DropDownList is inside an UpdatePanel so that may affect behaviour.

+2  A: 

You need to return from that function as well, like this:

$('.warn').change(imitateConfirmUnload);

Currently the return value isn't being used. This would also work:

$('.warn').change(function() {
  return imitateConfirmUnload();
});

Also, I'm pretty sure you want an equals check here:

if (window.onbeforeunload == null)
    return true;

Currently it's nulling out the onbeforeunload handler if it was present.

Nick Craver
Thank-you for that answer. It spotted two problems very quickly. And I thought that would fix it. Surprisingly it didn't. The postback still occurs. The DropDownList is inside an UpdatePanel, so I wonder if that is affecting the behaviour....?
Colin
@Colin - Yes, absolutely. UpdatePanel changes the game completely, it's captured and handled by Microsoft scripts when it attempts to post.
Nick Craver
A: 

Sure enough, cancelling asynchronous postbacks from an Update Panel requires a different technique:

http://msdn.microsoft.com/en-us/magazine/cc163413.aspx

http://stackoverflow.com/questions/2424327/prevent-asp-net-dopostback-from-jquery-submit-within-updatepanel

//Adds an event handler to confirm unsaved changes when an asynchronous postback is initialised by an UpdatePanel
function setConfirmAsyncPostBack() {

    if (typeof (Sys.WebForms) === "undefined" || typeof (Sys.WebForms.PageRequestManager) === "undefined")
        return;

    var prm = Sys.WebForms.PageRequestManager.getInstance();
    prm.add_initializeRequest(confirmAsyncPostBack);
}

//An event handler for asynchronous postbacks that confirms unsaved changes, cancelling the postback if they are not confirmed
//Adds the confirmation to elements that have a css class of "warn"
function confirmAsyncPostBack(sender, args) {
    if (window.onbeforeunload != null && args.get_postBackElement().className == "warn" && !unloadConfirmed())
        args.set_cancel(true);
}

//Displays a confirmation dialog that imitates the dialog displayed by onbeforeunload
function unloadConfirmed() {

    var confirmed = confirm("Are you sure you want to navigate away from this page?\n\n" + unloadMessage() + "\n\nPress OK to continue or Cancel to stay on the current page.");
    if (confirmed)
        window.onbeforeunload = null;
    return confirmed;
}

function unloadMessage() {

    return 'You have unsaved changes.';
}

This code goes with the problem described in my other question: http://stackoverflow.com/questions/3290758/dropdownlist-not-firing-onbeforeunload-when-autopostbacktrue

Colin