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>
Related
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
}
});
})();
I need to add a Button to every select2 item and prevent the default event so only the button gets triggered.
I have the following code but the normal onSelect event still gets triggered:
select.on('select2:select', test2);
function test2(e) {
if (e.params.originalEvent.target.classList.contains('TreeButton')) {
//stop event execution
e.stopPropagation();
e.preventDefault();
return false;
} else {
//execute normal
}
}
Try to catch select2:selecting event:
select.on("select2:selecting", function (e) {
if (e.params.args.originalEvent.target.className === 'btn') {
e.preventDefault();
}
}
Here is a jsfiddle: http://jsfiddle.net/beaver71/dtjhpnm7/
How to get out from event function (onclick event)?
document.onclick = function (event) {
if ( event.target.getAttribute("id") == 'chess') {alert('You miss cell!'); };
if (prevCell != undefined) {
prevCell.classList.remove('red');
}
//....
}
//.....
With the term 'get out', I mean to stop this function and wait for new onclick event.
Just write return statement where you want to stop function.
Example:
document.body.addEventListener("click", function (){
If(flag) return
// Do some other work
Return
})
Return statement immediately stops function execution
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.
I have Jquery click event and i want to prevent multiple click before executing my function UpdateItemStatus(this.id);, so i have tried below code using on/off event,
$('#tableItems').on('click', 'tr', function (e) {
if ($(e.target).closest("td").hasClass("cssClick")) {
$(this).off(e);
UpdateItemStatus(this.id);
$(this).on(e);
}
});
but how do i turn .on? as it's not working, not able to click again.
How about having a global variable which decides the button click action?
Something like this?
var clickevent = true;
$('#tableItems').on('click', 'tr', function (e) {
if(clickevent){
if ($(e.target).closest("td").hasClass("cssClick")) {
clickevent = false;
UpdateItemStatus(this.id);
clickevent = true;
}
}
});
if UpdateItemStatus function has ajax then i recommend you to put clickevent = true inside success of that ajax
You don't need to use off() for your code. Use return false:
$('#tableItems').on('click', 'tr', function (e) {
if ($(e.target).closest("td").hasClass("cssClick")) {
return false;
} else{
//do stuff here
}
});
I would probably use something like this :
var inputstate = false;
$('#tableItems').on('click', 'tr', function (e) {
if ($(e.target).closest("td").hasClass("cssClick")) {
if(!inputstate){
inputstate = true;
setTimeout((function(element){
return function(){
UpdateItemStatus(element);
inputstate = false;
};
})(this),50);
}
}
});
the setTimeout used to "defer the call" of your UpdateItemStatus function.
Because if this listener is fired, (an other listener cannot be fired at the same time) the value of the boolean will change to the end state before that the next click will be handled
Seems like your UpdateItemStatus() uses some asynchronous call (ajax?), so here's how i would do it:
$('#tableItems').on('click', 'tr', function (e) {
var $td = $(e.target).closest("td");
if ($td.hasClass("cssClick")) {
$td.toggleClass("cssClick");
UpdateItemStatus(this.id).done(function(){
$td.toggleClass("cssClick");
});
}
});
and in UpdateItemStatus:
function UpdateItemStatus(id){
//do stuff
return $.ajax(...);
}