How to prevent user from navigating away?

onbeforeunload
are you sure you want to leave this page javascript disable
confirm navigation leave this page javascript
javascript detect leaving page
javascript onbeforeunload custom message
onbeforeunload preventdefault
warn user before leaving web page with unsaved changes jquery
confirmation before closing of tab/browser using javascript

In my SAPUI5 application I'm using a sap.tnt.Toolpage as the main layout container. The SideNavigation shows a list of application links and the mainContents is dynamically loaded using the sap.ui.core.routing.Router.

To navigate to a detail page I'm using

var router = sap.ui.core.UIComponent.getRouterFor(this);
router.navTo("MyDetailRoute", {
    detailItemId: oItem.getBindingContext("oDataSourceName").getProperty("DETAILID")
});

This loads a detail view which then binds it's controls to the data from my data source.

The problem arises when I try to remember the user to save his changes back to the server. I basically want to interrup the navigation to aks the user if he'd like to a) Cancel his changes, b) Save his changes or c) Stay on the detail page. While a) and b) are easy to implement, I don't know how to prevent the navigation from happening.

I've tried so far by subscribing to onBeforeHide of my view:

var view = this.getView();
var that = this;
view.addEventDelegate({
    onBeforeHide: function (evt) {
        var oModel = that.getModel("oDataSourceName");
        if (oModel.hasPendingChanges()) {
            // How to prevent leaving the page?
        }
    }
});

Things I've tried that are not working:

  1. evt.preventDefault();
  2. evt.stopPropagation();
  3. throw 'something';

Option 3) actually prevents the navigation but leads to later problems because the URL will change nevertheless...

Does anyone have an idea?

Edit: Thanks to the answer from cschuff I was able to get it working. For anyone who has the same problem in the future:

// In onInit: Subscribe to onBeforeHide in order to un-register event handler for hashchange

onInit: function () {        
    this.getRouter().getRoute("MyDetailRoute").attachPatternMatched(this.onNavigated, this);

    var view = this.getView();
    var that = this;

    view.addEventDelegate({
        onBeforeHide: function (evt) {
            $(window).off('hashchange');
        }
    });
}


// Then in onNavigate stoppen the router, saving the current window location and subscribing to hashchange (only once)
// In hashchange use helper variable m_bSelfURLSetting to prevent the function from running when triggered by URL restore (above)
// In the handler checking for pending changes and either resore the old URL or starting the router again if the user wants to quit or if there are no changes

onNavigated: function (oEvent) {            

    this.getRouter().stop();
    this.m_strHref = window.location.href;
    var that = this;

    $(window).off('hashchange').on('hashchange', function (e) {
        if (that.m_bSelfURLSetting) {
            that.m_bSelfURLSetting = false;
            return;
        }

        var oModel = that.getModel("oDataSourceName");
        if (oModel.hasPendingChanges()) {
            var leave = confirm('There are unsaved changes.\r\n\r\nDo you really want to leave the page?');
            if (!leave) {
                // re-set the URL
                that.m_bSelfURLSetting = true;
                window.location.href = that.m_strHref;
            }
            else {
                that.getRouter().initialize(false); 
                oModel.resetChanges();
            }
        } else {
            that.getRouter().initialize(false);
        }
    });
}

This is definitively not the kind of code one is proud of...

Solution #1: You could temporarily deactivate routing completely by using the Router methods stop and initialize. This will stop listening to changes in the url hash and thereby ignore all routing triggers.

From your controller:

var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
oRouter.stop();

// later
// passing true will interpret and navigate to the current hash (since 1.48.0)
oRouter.initialize(true); 

Solution #2: Interrupt routing itself using sap.ui.core.routing.HashChanger events. hashChanged and hashReplaced are internally used by Router. You could also try if sap.ui.core.routing.Router routeMatched or beforeRouteMatched are cancelable (Docs are not giving any hint).

Solution #3: A less restrictive solution would be to just interrupt all actions that trigger routing from that particular view. Be aware that browser-back or changing the url-hash manually will still work here (the native JS events beforeunload and hashchange might help here).

BR Chris

Prevent leaving the page using plain JavaScript, This even will trigger whenever the user is trying to leave the page by. clicking the "Back" button (Reload the page, navigate away, etc.) This allows us write  To deal with the saved flag, you could listen to what happens in your textarea, for example, when the user is actually typing something: $('textarea').keyup(function(){ saved=false; }); Then, if you save the data in ajax, the save button could set it back to true:

JS to prevent user from navigation away from current html page , Here is a simple js script to prevent a user from navigating away from the current html page. What this script does is that the user will be shown  Prevent users from navigating away from form What is JotForm? JotForm is a free online form builder which helps you create online forms without writing a single line of code.

Try "onBeforeUnload" event on the window object.

Prevent a User Navigating Away from a Page with Unsaved Changes, On my current project we have the problem where users will often navigate away from a page without saving their changes. The users of our  In your code how many ways user can navigate away to other page means on button click or on Link Button click or what?? Ruwaldo 6-Jul-12 9:32am The user can close the page or click on link buttons or click one of the menu options at the top of the page or enter different url address.

How to prevent user from navigating away?, How do I prevent user from navigating away the page using C#? I tried using Unload but it fires right after page_load so i cant really use it. The redirection works, the user gets redirect to his address page. But the styles, javascripts are also prevented from being loaded. Any idea how i can prevent user clicking away from the page and force him to enter his address and get the styles etc. being loaded?

How to prevent browser refresh, URL changes, or route navigation , Every once in a while in Vue, you want to prevent the user from navigating away from a route or reloading the page. For example, perhaps they  NgOnDestroy won't necessarily fire when you navigate away from the angular component, since NativeScript caches the component. This means that the subscription will exist beyond the point when you navigate away from the component and you'll be executing the subscription callback on NavigationStart events of other components.

Prevent User Navigating Away from Page with Unsaved Changes, Solved: Hello, I'm trying to add a prompt warning window in Nintex warning users of losing their form data if a user accidentally presses the  Prevent router navigation. Great! So far, our component will prevent a user accidentally losing their changes if the browser changes, but it’s likely that your route changes are actually handled by JavaScript. If that’s the case, you will also need to prevent the Vue router from navigating away.

Comments
  • Solution #2 does not work (at least not on my end), preventDefault() and cancelBubble() did nothing to stop the navigation.
  • This is not working for websites just using hashes for navigation like all sapui5 apps.