I am trying to implement some code to prevent the back button from doing anything on a page in my site. Page posts a form to process a payment, so don't want the user to press back otherwise it ends up in a weird user experience. There is serverside code to handle it, but would like to prevent it clientside as much as possible.
My issue is that even if I use methods like the ones mentioned here: how to stop browser back button using javascript
The problem is that although the page never goes back now, as soon as the back button is pushed the form POST gets canceled.(Using Chrome browser.)
Code I have currently is:
function() {
if(window.history && window.history.pushState) {
window.history.pushState({ page: 1 }, $(document).find("title").text(), null);
window.addEventListener('popstate', function (e) {
e.preventDefault();
e.stopPropagation();
window.history.pushState({ page: 1 }, $(document).find("title").text(), null);
});
}
else {
window.location.hash = "pp";
window.onhashchange = function (e) {
e.preventDefault();
e.stopPropagation();
window.location.hash = "pp";
};
}
}
Is there actually anything I can do here?
Unfortunately there's not a lot you can do. You can stop the end result of pressing the back button (changing the page), but you can't stop the side effects of clicking it (causing currently pending requests to halt).
The best you can do is capture when the back button is pressed, determine if the form was sent but no response was received, and then alert the user that the form was likely sent. Then you could attempt to direct the user to next page, which you could design to kick back to the payment page if none was received.
It's problems like this that are hard to analyze for edge cases. :)
Related
I've added ajax calls that fire when a user leaves a text box to automatically save their text. There is also a save button at the bottom of the page (the save button is still necessary because it permanently archives the document state at that point in time).
The problem is when a user edits a text box and then directly clicks the submit button. The ajax request is made but then the submit request kills it and I get an error. If I don't get a successful response back from the server then I display a message letting the user know there is a problem (long story short, we've had issues with users spending a long time entering data and then for whatever reason it doesn't get submitted and they lose it all).
In the case that they hit the Save button, I don't care that the request is cancelled because the hitting Save is, obviously, going to Save the data anyway. How can I differentiate between an ajax error where connectivity was lost versus one where it was cancelled because the form was submitted?
I tried this:
var formIsSubmitting = false;
$(document).ready(function () {
$('form').on('submit', function (e) {
debugger;
formIsSubmitting = true;
});
});
function handleError(xmlRequest) {
debugger;
if (!formIsSubmitting)
alert(xmlRequest.status + ' \n\r ' + xmlRequest.statusText + '\n\r' + xmlRequest.responseText);
}
This didn't work though. Also it doesn't break on either of the debugger lines so not sure what's up with that either.
EDIT:
Here's what the button looks like:
<asp:LinkButton ID="lbnSaveP1" runat="server" OnCommand="GoToPage"
OnClientClick="return validateP1();" CommandName="1" CommandArgument="1" />
validateP1 doesn't do anything fancy... just what you'd expect.
I am developing a project where user gets a conformation page. I want user not to click back or close tab or reload.
Now either I need to disable the browser features or get back button,tab close event, or reload event to java script so that I could take the needed steps to prevent my data to get lost.
I have used this:
window.onbeforeunload = function()
{
return "Try This";
};
But this get called even when I click a button that redirects the page.
If you just want to have the alert, understanding that the user is ultimately in control and can bypass your alert, then do what you're doing but use a flag that disables it when you're navigating and don't want the alert. E.g.:
var warnWhenLeaving = true;
window.onbeforeunload = function() {
if (warnWhenLeaving) {
return "your message here";
}
};
then in a click handler on the link/button/whatever that moves the user on that you don't want this to pop up on:
warnWhenLeaving = false;
In a comment you asked:
can i know that what user has clicked when alert is generated with this function. That is can i know what user has clicked (leave this page/stay on page)
The answer is: Sort of, but not really; you're almost certainly better off not trying to.
But: If you see your onbeforeunload function run, then you know the user is leaving the page and the browser is likely to show them your message. The browsers I'm familiar with handle the popup like an alert: All JavaScript code on the page is blocked while the popup is there. So if you schedule a callback via setTimeout, you won't get the callback if they leave and you will if they stay:
window.onbeforeunload = function() {
if (warnWhenLeaving) {
setTimeout(function() {
display("You stayed, yay!");
}, 0);
return "No, don't go!";
}
};
Live Example
So in theory, if you get the callback, they stayed; if you see an unload event, they left. (Note that there are very few things you can do in an unload event.)
I've tried that on current Chrome, current Firefox, IE8, and IE11: It works on all of those. Whether it will work in the next release of any of them is anybody's guess. Whether it works reliably on mobile browsers is something you'd have to test, and again could change.
I have a page where user needs to enter some data and click save to validate the changes, but my problem is if the user is trying to close the browser window or click on a different link to navigate to a different page..I need to delete all the entries the user has saved so far..
I am doing it the following way
window.onbeforeunload = function()
{
if(confirm('Are you sure you want to navigate'))
{
//Invoke `enter code here`server side method
}
else
{
// return false;
}
}
Everything works fine if he click on Yes, the problem comes when he click on "No"..Even if he click on No..the page unload method is getting called and it is redirected to a different page..but I want it to stay in the same page in same state...can you please help me in achieving this.
Thanks and appreciate your response....
You cannot stop the user from leaving the page. What you can do is alert a message to them, asking if they want to leave or not.
The window.onbeforeunload event should return a string (and only a string). This string will be printed on the alert box made by the browser.
You cannot use your own alert box, or block the user from leaving (or redirect them).
window.onbeforeunload = function(){
return 'Are you sure you want to leave?';
};
Or with jQuery
$(window).on('beforeunload', function(){
return 'Are you sure you want to leave?';
});
When a user leaves the page, you can use the onunload event to make an AJAX call (you may need to use async: false here).
Example:
$(window).unload(function(){
$.ajax({
url: '/path/to/page/',
async: false, // this may be needed to make sure the browser doesn't
// unload before this is done
success: function(){
// Do something
}
});
});
NOTE: Instead of doing this, why don't you just save everything when the user is completed? Instead of saving it and then removing it if the user doesn't finish?
First of all: you can't! It's impossible. onbeforeunload only accepts a string as return value and will then close if the user wants that.
But then think about what happens if the computer is being without energy and shuts down? Or the browser will closed by the Task Manager? Or even more "realistic": The internet connection get lost! => Then you got invalid data states too!
You are trying to solve a false problem! Your problem isn't this function, your problem is the state of your formular!
Why do you need some kind of function? Do you saving the data before he clicks on save? Then don't! Or make sure to have another query which detects unfinished data in your database and delete it after a timeout!
onbeforeunload only accepts a string as return value. That string will be displayed by the browser with the option to stay on the page or leave it. But that's ll you can do.
You can use something like this, just call the following function on your page
function noBack() {
window.onbeforeunload = function(){window.history.forward()}
}
this disables Back button if window.history is clean, otherwise it works only first time.
Is there a way detect/catch the browser back button being pressed and in doing so ask them if they are sure about going back?
Building an application and it will soon be converted to an ajax based application and per requirements it's supposed to reset the application if a user goes 'back'...
I mainly want this to catch the accidental back button presses as I personally feel that if someone can't follow the directions that are given to them at the beginning of the application.... I'm not worried about their extra work.
If there isn't a way to do this is would the best solution be to launch the application in a new window/tab so that there is no history for it to go back to?
you can use onbeforeunload to detect back button or accidental page navigations:
window.addEventListener("beforeunload", function() {
var ans = confirm("Are you sure?");
if (ans) {
//TODO: add your code here
}
}, false);
to replace the current page in browser history you can use window.location.replace():
window.location.replace("yourNewURL");
You can also set the onbeforeunload function like this:
window.onbeforeunload = function() {
return "Are you sure you wish to leave?";
};
Is it possible to cancel a browser back or forward event that causes a hash change or an HTML 5 history change in the same way that one can cancel a page-loading back or forward event through window.onbeforeunload?
I don't know if it helps in your situation but Sammy.js, a popular hash-routing library, has a before handler. I've used it in my application to record the previously accessed hash, and if it's the hash I want to stop them from leaving, return false will keep them on that page. You still need to rewrite the URL to display the previous page, but it seems to be working. Here's a little sample of what I did:
app.before(function (context) {
if (context.path === lastRoute) return false; // Was fired from our app.setLocation below.
if (lastRoute === "/#MyHashWhereIFirstWantToConfirm") {
if (!confirm("Are you sure you wish to leave this page?")) {
app.setLocation(lastRoute); // Send them back to /#MyHashWhereIFirstWantToConfirm
return false; // Keep the handler for the destination page from firing.
}
}
lastRoute = context.path;
return true;
});
Used in conjunction with window.onbeforeunload you could pretty well keep the user from leaving the page without a confirmation.