This question already has answers here:
How to disable beforeunload action when user is submitting a form?
(7 answers)
Closed 7 years ago.
I am using window.onbeforeunload to prevent the user from navigating away after changing values on a form. This is working fine, except it also shows the warning when the user submits the form (not desired).
How can I do this without showing the warning when the form submits?
Current code:
var formHasChanged = false;
$(document).on('change', 'form.confirm-navigation-form input, form.confirm-navigation-form select, form.confirm-navigation-form textarea', function (e) {
formHasChanged = true;
});
$(document).ready(function () {
window.onbeforeunload = function (e) {
if (formHasChanged) {
var message = "You have not saved your changes.", e = e || window.event;
if (e) {
e.returnValue = message;
}
return message;
}
}
});
Using the form's submit event to set a flag might work for you.
var formHasChanged = false;
var submitted = false;
$(document).on('change', 'form.confirm-navigation-form input, form.confirm-navigation-form select, form.confirm-navigation-form textarea', function (e) {
formHasChanged = true;
});
$(document).ready(function () {
window.onbeforeunload = function (e) {
if (formHasChanged && !submitted) {
var message = "You have not saved your changes.", e = e || window.event;
if (e) {
e.returnValue = message;
}
return message;
}
}
$("form").submit(function() {
submitted = true;
});
});
you could use .on() to bind onbeforeunload and then use .off() to unbind it in form submission
$(document).ready(function () {
// Warning
$(window).on('beforeunload', function(){
return "Any changes will be lost";
});
// Form Submit
$(document).on("submit", "form", function(event){
// disable warning
$(window).off('beforeunload');
});
}
You can handle the submit() event, which will occur only for your form submission.
Within that event, set your flag variable formHasChanged to false to allow the unload to proceed. Also, just a suggestion, but since the purpose of that flag variable will have changed, so you may want to rename it something like 'warnBeforeUnload'
$(document).submit(function(){
warnBeforeUnload = false;
});
I was looking for a better solution to this. What we want is simply exclude one or more triggers from creating our "Are you sure?" dialog box. So we shouldn't create more and more workarounds for more and more side effects. What if the form is submitted without a click event of the submit button? What if our click-handler removes the isDirty status but then the form-submit is otherwise blocked afterwards? Sure we can change the behaviour of our triggers, but the right place would be the logic handling the dialog. Binding to the form's submit event instead of binding to the submit button's click event is an advantage of the answers in this thread above some others i saw before, but this IMHO just fixes the wrong approach.
After some digging in the event object of the onbeforeunload event I found the .target.activeElement property, which holds the element, which triggered the event originally. So, yay, it is the button or link or whatever we clicked (or nothing at all, if the browser itself navigated away). Our "Are you sure?" dialog logic then reduces itself to the following two components:
The isDirty handling of the form:
$('form.pleaseSave').on('change', function() {
$(this).addClass('isDirty');
});
The "Are you sure?" dialog logic:
$(window).on('beforeunload', function(event) {
// if form is dirty and trigger doesn't have a ignorePleaseSave class
if ($('form.pleaseSave').hasClass('isDirty')
&& !$(event.target.activeElement).hasClass('ignorePleaseSave')) {
return "Are you sure?"
}
// special hint: returning nothing doesn't summon a dialog box
});
It's simply as that. No workarounds needed. Just give the triggers (submit and other action buttons) an ignorePleaseSave class and the form we want to get the dialog applied to a pleaseSave class. All other reasons for unloading the page then summons our "Are you sure?" dialog.
P.S. I am using jQuery here, but I think the .target.activeElement property is also available in plain JavaScript.
Related
I want warn users if they leave the page by closing the browser or using the history buttons of the browser using the following javascript:
window.onbeforeunload = function(e) {
return 'Ask user a page leaving question here';
};
But my links and buttons on my website should work regardless of this. How can I achieve that?
The first way that comes to mind is to set a variable that tells you whether a link was clicked:
var linked = false;
window.onbeforeunload = function(e) {
if (!linked)
return 'Ask user a page leaving question here';
};
document.addEventListener('click', function(e) {
if (e.target.tagName === "A")
linked = true;
}, false);
That is, set a click event handler at the document level, that tests whether the clicked element was an anchor (or whatever else you want to allow) and if so sets the variable. (Obviously this assumes that you don't have other anchor element click handlers at a lower level that stop event propagation.)
var linkClicked = false;
window.onbeforeunload = function(e) {
if (!linkClicked){
linkClicked = false;
return 'Ask user a page leaving question here';
}
};
$(document).ready(function(){
$('a').click(function(e){
linkClicked = true;
});
});
Obviously this relies on JQuery to add the event handler to all links, but you could attach the handler with any other method, including adding onclick="linkClicked=true;" to every link on the page if you really have to.
Edit:
Just want to point out that if the user clicks a link that doesn't redirect them (e.g. a hashtag link to somewhere else on the page, or something that returns false / prevents the default action being executed) then this will set linkClicked to true and subsequently any browser based navigation won't be caught.
If you want to catch this, I would advise setting a timeout on the link click like so:
$(document).ready(function(){
$('a').click(function(e){
linkClicked = true;
setTimeout(function(){
linkClicked = false;
}, 500);
});
});
This will allow half a second for the window unload event to trigger before resetting the flag so that future navigation events are caught correctly. This still isn't perfect, but it probably doesn't need to be.
You can use the window.onbeforeunload event.
var check= false;
window.onbeforeunload = function () {
if (!check) {
return "Are you sure you want to leave this page?"
}
}
function CheckBackButton() {
check= true;
}
referenceElement.addEventListener('onClick', CheckBackButton(), false);
Us a confirmation prompt no?
like this? Intercept page exit event
window.onbeforeunload = function (e) {
var message = "Your confirmation message goes here.",
e = e || window.event;
// For IE and Firefox
if (e) {
e.returnValue = message;
}
// For Safari
return message;
};
How to show the “Are you sure you want to navigate away from this page?” when changes committed? this may solve your problem How
I'm using Telerik controls for my project. On my page, there are some links to another page, several radtextboxes and a radbutton (it causes a postback). When the textbox values are changed, the button becomes enabled. Then, in my window.onbeforeunload, I check if the button is enabled or disabled. If it is enabled, then the confirm dialog appears. The code looks like this :
window.onbeforeunload = function (evt) {
var ClientGeneral_btnSave = $find('<%=btnSave.ClientID %>');
if (ClientGeneral_btnSave.get_enabled() == true) {
var message = 'You will lose unsaved data?';
if (typeof evt == 'undefined') {
evt = window.event;
}
if (evt) {
evt.returnValue = message;
}
return message;
}
This code works well. When I close the tab, the confirm dialog appears. When I click on the links, it does. But, when I click on the btnSave itself, the dialog appears too, which is unsual. I want the btnSave NOT to cause onbeforeunload event
Please tell me how to do this.
Thank you in advance
It will fire onbeforeunload this if the btnSave posts back which it looks as if it is. Therefore you have a couple of choices
Prevent the btnSave from posting back if you don't need it to. Easiest way to do it is put this attribute in the asp:Button markup
OnClientClick="return false"
Wire up a javaScript/jQuery method to disable the onbeforeunload event. I did this before by stashing an value in a hidden field and using this to signal that the onbeforeunload event should fire.
for instance
$('#<%= btnSave.ClientID %>').bind('click', function(e){
$('#myHiddenFieldId').val('1');
});
and change your on beforeunload handler to check that the hidden field is not equal to 1 (make 0 the default i.e.
window.onbeforeunload = function (evt) {
if( $('#myHiddenFieldId').val() != '1')
{
//your logic here
}
}
You could probably do something better by unbinding the onbeforeunload handler in the btnSave click event using JQuery rather than using a hidden field to override.
Option 2 can get fiddly though - so best of luck
I have a button in my form. I need my form to be processed after the first click (or pressing Enter) on the button, and after that, if some conditions would be true, I do something like submitting the form by the second click or pressing Enter key on the button.
What do you think I have to do?
Create a (boolean) variable that saves your state, which is set to true when the first click (or action) has happened and your condition is true. Then submit on the second action when the variable is true.
If the condition has to be matched on both clicks (I guess so) consider the following:
$(function() {
var first = false;
$("form").submit(function() {
if(first && checkCondition())
submit();
if(!first && checkCondition())
first = true;
e.preventDefault();
});
});
so in basic code:
var answered = false;
$(function() {
$("form").submit(function() {
if(answered == false) {
answered = true;
return false;
}
});
});
If I've understood what you're trying to do correctly, you could bind an event handler to the submit event. That event handler will handle your validation, but if you use the jQuery one method, it will only be executed once. The next time the submit event is triggered, the form will submit as usual:
$("yourForm").one("submit", function(e) {
e.preventDefault(); //Stop the form from being submitted
//Do stuff
});
The result is effectively the same as #Manuel van Rijn's answer, but using jQuery's one just makes it a bit shorter and cleaner in my opinion. However, this could also add a slight performance benefit, as the event handler is unbound after it's execution and won't be called again.
I have this little piece of code:
<script>
$(window).bind('beforeunload', function() {
$.ajax({
async: false,
type: 'POST',
url: '/something'
});
});
</script>
I wonder, how could I disable this request when user hits the submit button.
Basically something like here, on SO. When your asking a question and decide to close the page, you get a warning window, but that doesn't happen when you're submitting the form.
Call unbind using the beforeunload event handler:
$('form#someForm').submit(function() {
$(window).unbind('beforeunload');
});
To prevent the form from being submitted, add the following line:
return false;
Use
$('form').submit(function () {
window.onbeforeunload = null;
});
Make sure you have this before you main submit function! (if any)
This is what we use:
On the document ready we call the beforeunload function.
$(document).ready(function(){
$(window).bind("beforeunload", function(){ return(false); });
});
Before any submit or location.reload we unbind the variable.
$(window).unbind('beforeunload');
formXXX.submit();
$(window).unbind("beforeunload");
location.reload(true);
Looking for Detect onbeforeunload for ASP.NET web application well I was,
I've to show warning message if some input control changes on the page using ASP.NET with Master Page and Content Pages. I'm using 3 content placeholders on the master page and the last one is after the form
<form runat="server" id="myForm">
so after the form closing tag and before the body closing tag used this script
<script>
var warnMessage = "Save your unsaved changes before leaving this page!";
$("input").change(function () {
window.onbeforeunload = function () {
return 'You have unsaved changes on this page!';
}
});
$("select").change(function () {
window.onbeforeunload = function () {
return 'You have unsaved changes on this page!';
}
});
$(function () {
$('button[type=submit]').click(function (e) {
window.onbeforeunload = null;
});
});
</script>
beforeunload doesn't work reliably this way, as far as binding goes. You should assign it natively
so I got it working like this bind and unbind didn't work out for me also With jQuery 1.7 onward the event API has been updated, .bind()/.unbind() are still available for backwards compatibility, but the preferred method is using the on()/off() functions.
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript" src="http://cdn.jsdelivr.net/jquery.dirtyforms/2.0.0-beta00006/jquery.dirtyforms.min.js"></script>
<script type="text/javascript">
$(function() {
$('#form_verify').dirtyForms();
})
</script>
<title></title>
<body>
<form id="form_verify" action="a.php" method="POST">
Firt Name <input type="text">
Last Name <input type="file">
<input type="submit">
</form>
if you're using bind then use this:
$('form').submit(function () {
$(window).unbind('beforeunload');
});
This will be good for all form submit.
Super old question but might be useful to others.
Simply detaching the "beforeunload" from the "submit" event would not work for me - because the submit handler was being called even when there were errors in the form that the user had to fix. So if a user attempted to submit the form, then received the errors, then clicked to another page, they would be able to leave without the warning.
Here's my workaround that seems to work pretty well.
(function($) {
var attached = false,
allowed = false;
// catch any input field change events bubbling up from the form
$("form").on("change", function () {
// attach the listener once
if (!attached) {
$("body").on("click", function (e) {
// check that the click came from inside the form
// if it did - set flag to allow leaving the page
// otherwise - hit them with the warning
allowed = $(e.target).parents("form").length != 0;
});
window.addEventListener('beforeunload', function (event) {
// only allow if submit was called
if (!allowed) {
event.preventDefault();
event.returnValue = 'You have unsaved changes.';
}
});
}
attached = true;
});
}(jQuery));
This way, if the click to leave the page originated from inside the form (like the submit button) - it will not display the warning. If the click to leave the page originated from outside of the form, then it will warn the user.
having issues with onbeforeunload. I have a long form broken into segments via a jquery wizard plug in. I need to pop a confirm dialog if you hit back, refresh, close etc on any step but need it to NOT POP the confirm dialog on click of the submit button. had it working, or at least I thought, it doesn't now.
<script type="text/javascript">
var okToSubmit = false;
window.onbeforeunload = function() {
document.getElementById('Register').onclick = function() { okToSubmit = true; };
if(!okToSubmit) return "Using the browsers back button will cause you to lose all form data. Please use the Next and Back buttons on the form";
};
</script>
'Register' is the submit button ID. Please help!
The problem is that the onclick event handler will not be called prior to if(!okToSubmit). All you are doing when you say:
document.getElementById('Register').onclick = function() { okToSubmit = true; };
Is just setting up the event handler. You are not actually retrieving the value of okToSubmit.
One way to fix this might be to setup the onclick event handler before registering onbeforeunload.
Plain old JS syntax a little rusty, so here it is in jQuery if anyone ever needs it, this works, at least for a form submit button. Change method to get if it suits your needs
<script type="text/javascript">
$(document).ready(function(){
var action_is_post = false;
$("form").submit(function () {
action_is_post = true;
});
window.onbeforeunload = confirmExit;
function confirmExit()
{
if (!action_is_post)
return 'Using the browsers back, refresh or close button will cause you to lose all form data. Please use the Next and Back buttons on the form.';
}
});
</script>