Jquery - Ajax : Unhandled multiple clicks event with ajax button "on Click method" - javascript

I have a button where i'm injecting an ajax request to a distant web service.
the traitment takes effects after checking a condition given from the success of another ajax request (thats why i am usung "ajaxSuccess")
My fonction looks like this :
$('body').on('click', '#btn', function (e) {
$(document).ajaxSuccess(function (event, xhr, settings) {
if (settings.url === window.annonce.route.testService) {
xhr = xhr.responseJSON;
var msg = {},
if (xhr == 1) { //case of traitement to be done
msg["attr1"] = attr1;
msg["attr2"] = attr2;
msg = JSON.stringify(msg);
console.log(msg);
$.ajax({
method: 'POST',
url: servicePostulation,
data: {msg: msg},
dataType: 'json',
success: function (data) {
console.log(data);
$("#btn").addClass("active");
},
error: function (data) {
console.log(data);
}
});
}
}
})
}
I my case , the "console.log(msg)" shows me a multiple sending of data msg , which means a multiple clicking events , and that's exactly the problem i wanna evitate,
i have tried many solutions with the " $('body').on('click') like :
e.stopImmediatePropagation();
e.preventDefault();
stopPropagation()
one()
off()
unbind()
but nothing works , so is there any further solution or explication ??

My suggest is to disable the button when user click and then enable the button when ajax complete.
**onClick:**
$('#btn').prop("disabled", true);
Ajax complete/success:
$('#btn').prop("disabled", false);

Related

Call ajax on before page unload

I'm trying to call an ajax before user leaving a page, this what i have done so far. But it doesn't even hit the ajax page.
This is what i have done so far.
window.onbeforeunload = closeIt();
function closeIt()
{
var key="save-draft";
$.ajax({
url: "app/ajax_handler.php",
type:"GET",
data:{key:key},
success: function(data) {
return data;
}
});
}
I Have tried this one also both failed in my case.
$( window ).unload(function() {});
The only way I think is to let the user know that it's a process on background with a confirm message, that will block the exit until user click on Accept or you've got the response.
Something like that:
window.onbeforeunload = closeIt();
function closeIt()
{
/*var key="save-draft";
$.ajax({
url: "app/ajax_handler.php",
type:"GET",
data:{key:key},
success: function(data) {
return data;
}
});*/
setTimeout(function() {
return confirm("There is a process that isn't finished yet, you will lose some data. Are you sure you want to exit?");
}, 1000);
}

preventDefault of a link depending on the Ajax response

I've created a controller in Magento which check whether or not there are products in a list. If there are products in list it will return true otherwise false.
Here is the front-end which triggers the ajax call, bare in mind I can not change this to be a form. It has to be a link.
Compare Products
Here is the ajax call.
jQuery(".compare-product-link").on("click", function(e) {
jQuery.ajax({
async : false,
dataType : "json",
url : "/compareextra/compare/allowed",
success : function(data) {
//console.log(data);
if(data.isAllowed != true) {
e.preventDefault();
}
}
});
});
The problem I have is that the async is deprecated and is not good for user experience, saying that there are many answer out there which add a delay of 3 seconds, I also don't want that because thats not good for user experience.
I've also tried using a promise call but it only works with async : false.
jQuery(".compare-product-link").on("click", function(e) {
var response = false;
jQuery.ajax({
dataType : "json",
url : "/compareextra/compare/allowed",
success : function(data) {
console.log(data);
if(data.isAllowed) {
response = true;
}
}
}).done(function (){
console.log(response);
if(response != true) {
e.preventDefault();
}
});
});
EDIT
Another problem I also have is if I store the link into a variable and then open a new window as so window.location = href; most browser will block it and users will have to manually accept pop ups from the target site, which again is not good for user experience.
you cannot really achieve this using preventDefault like you said - because of async.
what I would try is:
preventDefault
store href as a variable
call ajax
redirect to href variable if true and not if false
jQuery(".compare-product-link").on("click", function(e) {
var href = $(this).attr('href');
e.preventDefault();
jQuery.ajax({
async : false,
dataType : "json",
url : "/compareextra/compare/allowed",
success : function(data) {
//console.log(data);
if(data.isAllowed == true) {
window.location = href;
}
}
});
});
if you need to create a link action you can use this code:
function triggerClick(url){
$('body').append('<span id="click_me_js"></span>');
$('span#click_me_js a')[0].click();
$('span#click_me_js').remove();
}
which will mimic a regular click on <a>

Ajax- beforeSend

In order to prevent getting an error twice I use beforeSend.
hasSent = false
function submit() {
if (!hasSent)
$.ajax({
url: "${createLink(controller:'userInvitation', action:'ajaxUpdate')}",
type: "POST",
data: $("#invitationForm").serialize(),
success: function(data, textStatus, jqXHR) {
$('#invitationForm')[0].reset();
$('.thank-you-modal').modal('show');
hasSent = true;
console.log(hasSent)
},
complete: function() {
hasSent = false;
console.log(hasSent)
}
});
}
As you can see the ajax should happen only if hasSent=false.
For some reason the ajax happens also if the user clicks multiple time (very quick) on the submit button
To prevent this kind of issue disable the button before sending the ajax and then anable inside the success function
$(mybutton).prop("disabled",true);
// ajax call here
then
success: function(data, textStatus, jqXHR) {
$(mybutton).prop("disabled",false);
// code here
}
You can create another flag such as isSending
function submit() {
if(isSending)
return;
isSending = true
$.ajax({
// ...
complete: function() {
isSending = false;
}
});
}
there are two ways you can do this.
1) create a flag and check if the button is pressed. If pressed then do not execute the ajax code
change the flag back once the request is successful, like this
success:function(...)
{
flag=false;
}
Or you can disable the button at the button click so the request will be carried out and double click situation won't arise. Enable the button on complete like this
complete:function(..){ $("yourbutton").attr("disabled",false)}

jQuery Anchor Clicked triggered by multiple times

Here is the scenario:
I am sending ajax request when user click on anchor tag to fecht & update instagram media status.
But it take sometime to retrieve the response, in that time user clicked N number of time on that anchor tag.
So each time it sends the request, I am don't want such behaviour ..
Is there any easy way to handle such situation?
Currently I am adding the class when user clicked on it, and using that I am deciding user has click on anchor tag or not??
Please let me know, if it is correct way or not..
Here is fiddle URL (Not clicked on link at least 2+ times, it send 2+ request which is i don't want )
http://jsfiddle.net/bkvaiude/mxb8x/
thanks
You should use should remove the click event and then set it up again when the ajax call is complete:
Instead of setting it in the success call as the others do; you should use the complete callback to set it. To make sure if the server returns an error it is still binding the click event again.
http://jsfiddle.net/eWwZt/
(function (){
console.log("bhushan");
var ajaxCall = function(e){
$("#test").off("click");
console.log("click");
e.preventDefault();
var is_liked_url = "https://api.instagram.com/v1/media/popular?client_id= b52e0c281e584212be37a59ec77b28d6";
$.ajax({
method: "GET",
url: is_liked_url,
dataType: "jsonp",
success: function(data) {
console.log("data...");
},
complete: function(){
$("#test").on("click", ajaxCall);
}
});
}
$("#test").on("click", ajaxCall);
})();
Put a flag to check if ajax call completed or not this way:
(function (){
var RequestInProgress = false;
console.log("bhushan");
$("#test").on("click", function(e){
e.preventDefault();
if(!RequestInProgress) // if request not in progress send
{
RequestInProgress = true;
var is_liked_url = "https://api.instagram.com/v1/media/popular?client_id= b52e0c281e584212be37a59ec77b28d6";
$.ajax({
method: "GET",
url: is_liked_url,
dataType: "jsonp",
success: function(data) {
console.log("data...");
RequestInProgress = false;
}
});
}
});
})();
UPDATED FIDDLE
You can use .off() to unbind click to element.
(function () {
console.log("bhushan");
var Myfunction = function (e) {
$("#test").off("click"); //Unbind click
e.preventDefault();
var is_liked_url = "https://api.instagram.com/v1/media/popular?client_id= b52e0c281e584212be37a59ec77b28d6";
$.ajax({
method: "GET",
url: is_liked_url,
dataType: "jsonp",
success: function (data) {
console.log("data...");
$("#test").on("click", Myfunction);
}
});
};
$("#test").on("click", Myfunction);
})();
DEMO
try this
var gettingData =false;
$('selector').click(function() {
gettingData = false;
if (!gettingData) {
gettingData =true;
$.ajax(//do ajax logic)
.success(
gettingData = false;
//parse data)
.error(
gettingData = false;
//display some error
);
} else {
return false;
}
});

form.submit fires multiple times, one extra time after each response

I have a form.submit that fires multiple times. The first time, it's fine. After I get the response back, if I click the submit button again, it fires twice. Then thrice. Seems like each time the response comes back, the submit fires an extra time the next time the button is clicked.
RetrievePassword = function () {
var $popup = $("#fancybox-outer");
var form = $popup.find("form");
form.submit(function (e) {
var data = form.serialize();
var url = form.attr('action');
$.ajax({
type: "POST",
url: url,
data: data,
dataType: "json",
success: function (response) {
if (response.Success) {
$.fancybox.close();
}
alert(response.Message);
},
error: function (xhr, status, error) {
alert(xhr.statusText);
}
});
e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();
return false;
});
};
I'm not even sure how to debug this. Any advice is appreciated...
I assume you are calling RetrievePassword() multiple times. Everytime you call it another onsubmit handler will be registered.
The solution is to register the handler only once.

Categories