Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent navigating to another view if contents are unsaved

We have a backbone.js app that displays a number of forms to the user. What we want is very simple: if the user goes to another page without saving the filled-in form, we want to display a confirmation dialog.

In classic forms this is easy enough, just implement window.onbeforeunload (or $(window).on('beforeunload') in jQuerysh). But backbone apps only have one view, typically. I tried a bit using onHashChange, but returning false in that callback does not prevent Backbone from still going to the other view.

Pointers are appreciated. Searching the interwebs didn't find me any valid response.

like image 660
cthulhu Avatar asked Mar 26 '12 13:03

cthulhu


2 Answers

Since version 1.2.0 you can override method Router.execute and return false to cancel routing, like this:

execute: function(callback, args, name) {
    if (!changesAreSaved) {
        // tip: .confirm returns false if "cancel" pressed
        return window.confirm("You sure have some unsaved "
          + "work here, you want to abandon it?");
    }

    // this is the default part of "execute" - running the router action
    if (callback)
        callback.apply(this, args);
}
like image 94
mrówa Avatar answered Oct 20 '22 16:10

mrówa


I would avoid hacking around with Backbone. You could do this globally for all links by replacing the part where you would normally start Backbone.history with something like

initRouter: function () {
    Backbone.history.start({ pushState: true });
    $(document).on('click', 'a', function (ev) {
        var href = $(this).attr('href');
        ev.preventDefault();
        if (changesAreSaved) {
            router.navigate(href, true);
        }
    });
}

You need of course to replace the changesAreSaved with something that makes sense and add whatever other login you have about handling links.

like image 22
ggozad Avatar answered Oct 20 '22 15:10

ggozad