Resuming default behaviour after preventDefault() - javascript

I've written a small jQuery plugin which is designed to ask the question, "Are you sure?" when clicking on a link or submitting a form.
It's used like this:
Link
Or like this:
<form action="link.php" method="post">
<button class="confirm">Submit</button>
</form>
What I am doing is using preventDefault() to prevent the default behavior when the anchor or button is clicked. I then display a confirm dialogue where the user has to click either OK or Cancel.
If the user clicks Cancel then nothing happens (as expected).
However, if the user clicks OK I am firing the click event again, and using a flag that was set first time around to not prevent the default behaviour second time around (I'm instead returning true). Except that it's not working. Clicking either OK or Cancel in the confirm dialogue doesn't do anything.
The plugin is below:
(function($) {
$.fn.fw_confirm = function(options) {
// Flag to check for the first click event
var paused = false;
return this.on("click", function(e) {
// The anchor or the button that was clicked
var button = $(this);
// If this is the second click event, the user must have confirmed so return true
if (paused == true) {
// Reset the flag
paused = false;
// This isn't working, or at least it's not submitting the form or proceeding to the URL of the hyperlink when I would expect it to
return true;
}
// First time around prevent the default behavior
e.preventDefault();
e.stopImmediatePropagation();
// Set the flag to true, ready for the second click event
paused = true;
if (confirm("Are you sure?")) {
// The user is certain, so trigger the click event again
return button.trigger("click");
} else {
// The user cancelled, reset the flag
paused = false;
return;
}
});
}
})(jQuery);

Related

Prevent page leaving and capture Leave button Jquery

I wish to prevent a user from leaving a page before clicking on submit button.And when he confirm leave i want to execute something (delayed leave).
i use this function
window.addEventListener('beforeunload', function(e) {
var myPageIsDirty = "d";
if (myPageIsDirty) {
e.preventDefault();
e.returnValue = '';
}
});
This surely warns the user. But my requirement to handle the leave button click event and do something
leave button confirmation can be done by:
Submit

JavaScript confirm dialog box keeps on regenerating on cancel event

SCENARIO: I just want to warn user on window change; so I've used jQuery's window blur & JavaScript's confirm dialogue box. When user will click OK button the application will redirect to another page & when user will click CANCEL button nothing will happen. He can continue his work on the same page.
ISSUE: OK button is working perfectly but when I click on the CANCEL button, the browser keeps on regenerating the dialogue box. How do I stop that?
CODE:
$(window).blur( function (e) {
var closeWindow = window.confirm("Your test will be cancelled if you switch the tabs.");
if (closeWindow) {
// redirect to another page
}
else {
// do nothing.
}
});
As #ROAL explained, the first blur event is because of actual blur, and rest are because of the browser trying to move away from the tab. A simple solution for this would be to use a flag to distinguish between the user generated event and the browser generated event. Give this a try:
var manualCancellation = false;
$(window).blur( function (e) {
if(!manualCancellation ){
var closeWindow = window.confirm("Your test will be cancelled if you switch the tabs.");
console.log(e);
if (closeWindow) {
// redirect to another page
}
else {
manualCancellation = true;
// do nothing.
}
} else {
// Reset the value of manualCancellation so that the event is fired the next time.
manualCancellation = false;
}
});

Prevent double submission with prevent window event issue

I'm using the following function to prevent double submissions:
$("#form").submit(function () {
var form = $(this);
form.find("input[type=submit]").attr("disabled", "disabled")
form.find("input[type=submit]").attr("value", "Processing");
});
It works fine, but then I have the following code which triggers an alert to avoid accidentally leaving the page:
function goodbye(e) {
if(!e) e = window.event;
//e.cancelBubble is supported by IE - this will kill the bubbling process.
e.cancelBubble = true;
e.returnValue = '¿DO YOU REALLY WANT TO LEAVE THIS PAGE?'; //This is displayed on the dialog
//e.stopPropagation works in Firefox.
if (e.stopPropagation) {
e.stopPropagation();
e.preventDefault();
}
}
window.onbeforeunload=goodbye;
The problem is if the user clicks submit and the realizes he didnt want to leave the page and clicks on stay on this page instead, the submit button is still disabled.
How could I re-enable it upon clicking stay on this page?
Thanks!
The button problem
You want to disable and enable the submit button so you know you going to touch the same kind of function and object twice, it is better to make advantage out of this in a function
function disableSubmit(form, enabled){
var submit = form.find("input[type=submit]"),
dataVar = enabled !== true ? "processing-message" : "send-message",
message = submit.data(dataVar);
submit.prop('disabled', (enabled !== true) );
submit.val(message);
}
I could make it even more generic for using it on each form. But the message in the button will display whatever you put in the data-attribute.
Cancel Submit
There is a problem with cancellation of an onbeforeunload event; there is no callback for it. The solution I came with is using a timeout. Since you don't know if the person canceled or not, I think 2 seconds is enough for the page to submit.
You have to have 2 seconds patient to get the submit button enabled again. But you can adjust it all you want of course
if (e.stopPropagation) {
setTimeout(function () {
disableSubmit(formObject, true);
}, 2000);
e.stopPropagation();
e.preventDefault();
}
The JSFiddle example

Preventing users from accidentally navigating away from unsaved pages

I got the snippet below from this SO post, and it works when a user tries to reload the page or close the browser etc. but if the user clicks on a link then it lets them naivagate away, and then incorrectly starts displaying the message on the wrong page. I am using pjax for the links.
$(document).ready(function () {
$('textarea').change(function () {
window.onbeforeunload = function () { return "Your changes to the survey have not been saved?" };
});
});
You should use onbeforeunload like this, inconditionally:
<script type="text/javascript">
saved=true; // initially, it is saved (no action has been done)
window.onbeforeunload = confirmExit;
function confirmExit() {
if (!saved) {
return "You did not save, do you want to do it now?";
}
}
</script>
It is not safe to handle this event only when another event is fired. The onchange event of your textarea here probably don't fire before you click on a link so the window won't handle the onbeforeunload at all. The link will work as expected: you will get redirected.
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:
$('#btnSave').click(function(){
// ajax save
saved=true;
});
Otherwise, it will load the next page with the saved flag on.
what about something like the following?
Listening on all <a> links and then, depending on whether the variable needToSave is set to true, showing the message or letting it go.
var needToSave = false; // Set this to true on some change
// listen on all <a ...> clicks
$(document).click("a", function(event){
if (needToSave == true) {
alert("You need to save first");
event.preventDefault();
return;
}
});
UPDATE (as per Roasted's suggestion) this should trigger the unload event every time the link is clicked and perform your existing logic:
// listen on all <a ...> clicks
$(document).click("a", function(event){
$(window).trigger("unload");
});
jsFiddle here - http://jsfiddle.net/k2fYM/

return true or false based on button clicked in pop up window

Okay so with jQuery I've intercepted the .submit() of a form and I want to create a custom pop up window that shows them the data that the entered and asks them to confirm it. If they click the confirm button true is returned to .submit() and they continue but if false is pressed then they should not move on and have a chance to change their entry.
I already have the pop up window being made fine with the contents of the form being displayed and the buttons being shown. What I'm not sure how to do is bind the click functions of the buttons so that if one is clicked it returns false to .submit() and if the other is clicked true is returned to .submit()
If you need me to post some of my code just let me know.
I don't want to use a confirm dialogue since i would like it to be a custom pop up window.
You need to use a confirm() dialogue:
var submit = confirm('Are you sure?');
if (submit) {
$(this).submit();
}
else {
return false;
}
This works by the dialogue presenting the message "Are you sure?" to the user, if the user clicks on the confirmation ok button, the dialogue returns true to the variable submit, otherwise it returns false.
If false is returned (the user clicked cancel), then the if evaluates to false, and the else is executed.
You would need to pass the .submit() as a callback function to the dialogue. This isn't a one line solution but rather a pattern that you should get familiar with. This http://www.youtube.com/watch?v=hQVTIJBZook will probably be helpful for some of this topic along with other common issues that you may come across
Example:
function openPopup(form) {
//
// Put whatever code you use to open you
// popup here
//
// Bind click handler to submit form if they click confim
$("#id_of_confim_button").on("click", function() {
// Get the form that was
form.submit();
});
// Bind click handler for cancel button
$("#id_of_cancel_button").on("click", function() {
//
// Code to close your popup
//
});
};
$("#id_of_form_submit_button").on("click", function(event) {
// Stops the form from submitting
event.preventDefault();
// Get the form you want to submit
var form = $("#form_being_submit");
// Call your 'open custom popup' function and pass
// the form that should be submitted as an argument
openPopup(form);
});
Catching only this form's submits' click event won't handle all cases (f.ex. if someone hits enter on a non-textarea input, the form submits too).
If i want to handle submit in an asynchronous way, i used to fire manually submit after the original was prevented & bring in an isDirty state:
(function () {
var isDirty = true;
$("form#id").on("submit", function ( evt ) {
if (isDirty) {
evt.preventDefault();
popup( "... params ...", function () {
// this will called, when the popup ensures the form can be submitted
// ... & it will be called by the popup
isDirty = false;
$("form#id").submit();
} );
}
});
})();

Categories

Resources