JQuery: Unbind click event not working as expected - javascript

I'm having a problem with the unbind event from jquery.
I load a modal after clicking a button and in this modal I have two possibilities, continue or cancel. If I continue there are some validations and if something goes wrong an alert should appear, or if I click cancel I close the modal. But if i cancel the modal and then I click the button that loads the modal with an ajax call again when clicking continue the alert appears 2 times, when it should appear only once. I've tried using the unbind event as is seen in the code but it doesn't seem to work, any ideas?
The ajax call is done by the followinenter code hereg code:
function ValidacionGeneral() {
var frmObs = $("#frmCreate");
$.ajax({
url: '#Url.Action("ValidacionGeneral", "Viajes")',
type: 'POST',
dataType: "text",
data: frmObs.serialize(),
success: function (data) {
if (data == "OK") {
$('#frmCreate').submit();
}
else {
$.unblockUI();
$.modal(data);
}
}
});
}
And the script of the modal is:
<script type="text/javascript">
$(document).ready(function () {
$("#btnAceptarValidacionGeneral").unbind("click");
$("#btnAceptarValidacionGeneral").live("click", function (e) {
e.preventDefault();
var error1 = false;
var error2 = false;
var error3 = false;
var error4 = false;
if ($('#ddlMotivosDistancia').length) {
error1 = $("#ddlMotivosDistancia").val() == '00000000-0000-0000-0000-000000000000';
}
if ($('#ddlMotivosRendimiento').length) {
error2 = $("#ddlMotivosRendimiento").val() == '00000000-0000-0000-0000-000000000000';
}
if ($('#ddlMotivosCarga').length) {
error3 = $("#ddlMotivosCarga").val() == '00000000-0000-0000-0000-000000000000';
}
if ($('#ddlMotivosDuracion').length) {
error4 = $("#ddlMotivosDuracion").val() == '00000000-0000-0000-0000-000000000000';
}
if (error1 || error2 || error3 || error4) {
alert('Debe seleccionar los motivos de tolerancia correspondientes para las alertas');
} else {
var form = $('#frmCreate');
if (form.html() == null) {
form = $('#frmEdit');
}
form.submit();
}
});
$("#btnCancelarValidacionGenral").live("click", function () {
$("#IdMotivoToleranciaDistancia").val('00000000-0000-0000-0000-000000000000');
$("#IdMotivoToleranciaRendimiento").val('00000000-0000-0000-0000-000000000000');
$("#IdMotivoToleranciaCarga").val('00000000-0000-0000-0000-000000000000');
$("#IdMotivoToleranciaDuracion").val('00000000-0000-0000-0000-000000000000');
});
});

Use off("click") to unbind all click events:
$("#frmCreate").off("click")
Further, if it's a one-time thing use $.one to bind it in the first place:
$("#frmCreate").one("click", function(){/*do this once and once only */});
HTH

Your unbind $("#btnAceptarValidacionGeneral").unbind("click"); is executed once only when DOM is ready, I think you must move it to function ValidacionGeneral()

After seaching I found that to unbind events attached with .live() the proper way is using .die()
Here is the documentation: http://api.jquery.com/die/
It solved my problem.

Related

jquery prevent submit and submit again on popup button click

I am trying to ,
Prevent the form Submit
Open a pop up
Submit the form again on click of Ok button of the above pop up.
I tried this ,
$('#continueForm').one('submit', function(e) {
var curr=$('input#hdncurrency').val();
var inrDiv = $("<div />");
if (curr=='INR') {
e.preventDefault();
inrDiv.ajaxDialog({
url: '#Url.Action("PopUpOnINRflow", "optionalextras")',
closeOnEscape: false,
success: function (content) {
$(content).find("#inrcontinue").click(function (e) {
inrDiv.ajaxDialog('close');
showLoader(); //TILL THIS IS WORKING
$('#continueForm').submit(); //THIS IS NOT HAPPENING AND NO CONSOLE ERRORS
});
}
});
}
else
{
$("input[type='submit']", this).val("Please Wait...").attr('disabled', 'disabled');
document.getElementById("cancelAmndment").style.visibility = "hidden";
return true;
}
});
you should replace
$('#continueForm').one
by
$('#continueForm').on

How could I stop a form submit in this case?

My intention is to check some conditions before submit is done or stop it and show an alert if the results of that condition are false. I need to ask a function localized in another PHP document using POST.
The next case I'm going to show, the alert is showed correctly when "result != 1", but when I test the opposite case "result == 1", the submit doesnt work:
$('body').on("submit","#idForm",function(event) {
event.preventDefault();
$.post( 'php_file_rute.php', {action:'functionName'})
.done(function(result) {
if (result == 1) {
if(functionNameInSameJSPage()){
return true;
}else{
return false;
}
} else {
alert('error');
return false;
}
});
});
I tried in another way, putting event.preventDefault behind every "Return false" but when "result != 1" it shows the alert but do the submit anyways. It happens in every condition (submit doesnt stop).
$('body').on("submit","#formProyecto",function(event) {
$.post( 'php_file_rute.php', {action:'functionName'})
.done(function(result) {
if (result == 1) {
if(functionNameInSameJSPage()){
return true;
}else{
return false;
event.preventDefault();
}
} else {
alert("error");
event.preventDefault();
return false;
}
});
});
As you can see, my goal is to stop the submit if "result != 1" and show an alert or do the submit if all conditions are ok.
Any idea?
Thanks.
The issue you have is that you cannot return anything from an asynchronous function - which your AJAX request is.
To solve this you need to use preventDefault() to stop the form submit event through jQuery, then raise another native submit event if the AJAX request returns a valid result. This second submit event will not be handled by jQuery and will submit the form as you require. Try this:
$(document).on("submit", "#idForm", function(e) {
e.preventDefault();
var form = this;
$.post('php_file_rute.php', {
action: 'functionName'
}).done(function(result) {
if (result === 1) {
if (functionNameInSameJSPage()) {
form.submit();
}
} else {
alert('error');
}
});
});
This is assuming that functionNameInSameJSPage() is not an async function. If it is then you'll need to use the callback pattern there too.
This is a bit of a tricky one but you can kind of get it to work by doing:
$('body').on("submit","#idForm",function(event) {
event.preventDefault();
$.post( 'php_file_rute.php', {action:'functionName'})
.done(function(result) {
if (result == 1) {
if(functionNameInSameJSPage()){
$('#idForm').trigger("submit.force"); //Trigger submit again but under a different name
}
} else {
alert('error');
}
});
});
$('body').on("submit.force","#idForm", function () { return true; }); //Passthrough
The idea is to retrigger the event but ensure you don't call the same handler.
There's a proof of concept at https://jsfiddle.net/2kbmcpa4/ (there's no actual ajax happening but the promise simulates that, note this example won't work in IE)
Steps to solve the issue :
On actual form submit just block the event and make the rest call.
Based on response again dynamically resubmit by setting the allowSubmit flag.
Because flag is set on second submit, it doesn't prevent the form from submission. Reset the allowSubmit flag.
(function() {
var allowSubmit = false;
$('body').on("submit", "#idForm", function(event) {
var that = this;
if (!allowSubmit) {
event.preventDefault();
$.post('php_file_rute.php', {
action: 'functionName'
}).done(function(result) {
if (result == 1) {
if (functionNameInSameJSPage()) {
allowSubmit = true; // set the flag so next submit will not go though this flow
that.submit(); // dynamically trigger submit
}
} else {
alert('error');
}
});
} else {
allowSubmit = false; // reset the flag
}
});
})();

second or nested event.PreventDefault() not working

I have this jquery code snippet, if I uncomment the first preventDefault() it will work fine, but I'm trying to invoke the second preventDefault(), but it won't work. See below:
$(document).ready(function () {
$('#btnSubmit').click(function (event) {
if ($('#tracking').val() != "") {
// FIRST preventDefault()
//event.preventDefault();
var url = "/ReceivingLog/CheckTrackingNumber?number=" + $('#tracking').val();
$.get(url, null, function (result) {
if (result == "False") {
// SECOND preventDefault()
event.preventDefault();
}
});
}
});
Why is the second/nested preventDefault not working? How do I get the second preventDefault() to work?
$.get is asynchronous - by the time its response comes back, the outer thread has already finished, and the triggered event has completed normally. You'll have to trigger the event again after the response comes back:
const button = document.querySelector('button');
button.addEventListener('click', clickListener);
let doSubmit = false;
function clickListener(e) {
// If this was triggered by the `$.get`, return immediately, run the event as normal without interruption:
if (doSubmit) {
console.log('redirecting');
return;
}
e.preventDefault();
//$.get(url, ...
setTimeout(() => {
const success = true;
if (success) {
doSubmit = true;
button.click();
}
}, 500);
}
<form>
<button type="submit">click</button>
</form>

Check which button clicked on page leave prompt?

So I have this code and I'm trying to find out how to check which button the user clicks on the prompt. I'd like to fire an event if they click stay or fire a different event if they leave. Is this possible?
var submitted = false;
$(document).ready(function () {
window.onbeforeunload = function (e) {
if (!submitted) {
var message = "Are you sure you want to leave?", e = e || window.event;
if (e) {
e.returnValue = message;
}
return message;
}
}
$("form").submit(function() {
submitted = true;
});
});
Actually there is no way to find that which button is clicked(in case of onbeforeunload confirm box) according to my knowledge.
But we can achieve the required functionality by following way:
window.onbeforeunload = function (e) {
if( $("table tbody.files tr.template-download.fade").length > 0 )
{
var message = "XYZ",
e = e || window.event;
// For IE and Firefox
if (e) {
e.returnValue = message;
}
// For Safari
return message;
}
}
And you can write the code for 'yes' button click inside following:
$( window ).unload(function() {
//--> Here
});
use Javascript "confirm" for that:
if(confirm("Are you sure you want to leave?"))
{
//True part
}
else
{
//False part
}

how to detect if a link was clicked when window.onbeforeunload is triggered?

I have window.onbeforeunload triggering properly. It's displaying a confirmation box to ensure the user knows they are navigating (closing) the window and that any unsaved work will be erased.
I have a unique situation where I don't want this to trigger if a user navigates away from the page by clicking a link, but I can't figure out how to detect if a link has been clicked inside the function to halt the function. This is what I have for code:
window.onbeforeunload = function() {
var message = 'You are leaving the page.';
/* If this is Firefox */
if(/Firefox[\/\s](\d+)/.test(navigator.userAgent) && new Number(RegExp.$1) >= 4) {
if(confirm(message)) {
history.go();
}
else {
window.setTimeout(function() {
window.stop();
}, 1);
}
}
/* Everything else */
else {
return message;
}
}
You're looking for deferred event handling. I'll explain using jQuery, as it is less code:
window._link_was_clicked = false;
window.onbeforeunload = function(event) {
if (window._link_was_clicked) {
return; // abort beforeunload
}
// your event handling
};
jQuery(document).on('click', 'a', function(event) {
window._link_was_clicked = true;
});
a (very) poor man's implementation without jQuery's convenient delegation handling could look like:
document.addEventListener("click", function(event) {
if (this.nodeName.toLowerCase() === 'a') {
window._link_was_clicked = true;
}
}, true);
this allows all links on your page to leave without invoking the beforeunload handler. I'm sure you can figure out how to customize this, should you only want to allow this for a specific set of links (your question wasn't particularly clear on that).
var link_was_clicked = false;
document.addEventListener("click", function(e) {
if (e.target.nodeName.toLowerCase() === 'a') {
link_was_clicked = true;
}
}, true);
window.onbeforeunload = function() {
if(link_was_clicked) {
link_was_clicked = false;
return;
}
//other code here
}
You can differ between a link unload or a reload/user entering a different address unload s by using a timer. This way you know the beforeunload was triggered directly after the link click.
Example using jQuery:
$('a').on('click', function(){
window.last_clicked_time = new Date().getTime();
window.last_clicked = $(this);
});
$(window).bind('beforeunload', function() {
var time_now = new Date().getTime();
var link_clicked = window.last_clicked != undefined;
var within_click_offset = (time_now - window.last_clicked_time) < 100;
if (link_clicked && within_click_offset) {
return 'You clicked a link to '+window.last_clicked[0].href+'!';
} else {
return 'You are leaving or reloading the page!';
}
});
(tested in Chrome)

Categories