I have a multi-page app (with custom pages, pre-2.5). There are some dcc.Link elements there, and a dcc.Location which triggers a callback which in turn changes the layout. Pretty standard stuff I believe.
What I’m trying to implement now is something similar to the browsers “beforeunload” event - so that sometimes (depending on a condition) the app shows a prompt the user to confirm before navigating to another page (or to cancel and stay on the current page).
The way the app works is navigating to a different url, this is leaving the current page and should trigger as normal. I actually use this event to clear out some localStorage elements that I interact with via Javascript.
Just add your check for if you need to prompt the user before the return statement.
Well, not if you use refresh=False in your Location component, which is what the official pre-2.5 example does. And I’m sure the new pages feature does the same.
The beforeunload is triggered only before actually unloading the page.
To clarify, I am looking for a good way of prompting the user when they switch to another page, but without setting refresh=True in dcc.Location component.
This is the official pre-2.5 example linked above, plus a window.onbeforeunload handler. I wish to see the prompt every time the URL changes:
This needs to be used in conjunction with the window.onbeforeunload in order to catch both ways that you could navigate away:
function changeDefaults() {
console.log('changing defaults')
$(".ignore-click").click(function() {
if (confirm('Do you wish to continue?') != true) {
event.preventDefault();
event.stopPropagation();
return false
}
})
}
$(document).ready(function() {setTimeout(function(){changeDefaults()},300)})
window.fetch = new Proxy(window.fetch, {
apply(fetch, that, args) {
// Forward function call to the original fetch
const result = fetch.apply(that, args);
// Do whatever you want with the resulting Promise
result.then((response) => {
if (args[0] == '/_dash-update-component') {
setTimeout(function(){changeDefaults()},300);
}
})
return result;
}
})
You will also need to add the className=‘ignore-click’ to the links that you want to be effected.
You will also need to load jquery for these functions to work. Straight javascript is a lot more lengthy.