I have function making multiple AJAX request with jQuery like:
function() {
$.ajax({
url: "/url",
data: {
params: json_params,
output: 'json'
},
async: false,
success: function(res) {
data1 = res
}
});
$.ajax({
url: "/url",
data: {
params: json_params,
output: 'json'
},
async: false,
success: function(res) {
data2 = res;
}
return data1 + data2;
});
}
While this function is running and data is loading I want to display a loading image without blocking it.
I have tried showing the loading icon using ajaxSend ajaxComplete, but does not work, since I have multiple ajax calls.
I also tried showing the loading at the beginning of the function and hiding at the end of the function, but failed.
How to do this?
How exactly did you try loading? Using the ajaxStart/ajaxStop events on the elements is one way to accomplish what you want. It could look like this:
$('#loadingContainer')
.hide() // at first, just hide it
.ajaxStart(function() {
$(this).show();
})
.ajaxStop(function() {
$(this).hide();
})
;
Maybe this helps you, I often used this before and it works like a charm..
I think the answer is really a combination of several of these. I would begin with ajax start to show the loading image at 0 (or whereever you want the start to be). Then I would use a callback function to increment the loading bar and repaint it.
For example
//when ajax starts, show loading div
$('#loading').hide().on('ajaxStart', function(){
$(this).show();
});
//when ajax ends, hide div
$('#loading').on('ajaxEnd', function(){
$(this).hide();
});
function ajax_increment(value) {
//this is a function for incrementing the loading bar
$('#loading bar').css('width', value);
}
//do ajax request
$.ajax({
url:"", //url here
data: {params:json_params,output:'json'},
async: false,
success: function (res) {
data1=res
ajax_increment(20); //increment the loading bar width by 20
}
});
$.ajax({
url:"", //url here
data: {params:json_params,output:'json'},
async: false,
success: function (res) {
data1=res
ajax_increment($('loading bar').css('width') + 10); // a little more dynamic than above, just adds 10 to the current width of the bar.
}
});
You could try something like this: Define a callback with a counter, and the callback hides the image after it's been called the required number of times.
showLoadingImage();
var callbackCount = 0;
function ajaxCallback() {
++callbackCount;
if(callbackCount >= 2) {
hideImage();
}
}
$.ajax({
url:"/url",
data: {params:json_params,output:'json'},
async: false,
success: function (res) {
data1=res
ajaxCallback();
}
});
$.ajax({
url:"/url",
data: {params:json_params,output:'json'},
async: false,
success: function (res) {
data2=res;
ajaxCallback();
}
});
That's only necessary for asynchronous calls, though. The way you're doing it (all your AJAX calls are synchronous), you should be able to just call hideImage() before returning at the end of your outer function.
You should be able to bind to the start and then end with the following:
$('#loading-image').bind('ajaxStart', function() {
$(this).show();
}).bind('ajaxStop', function() {
$(this).hide();
});
Or you could use beforeSend and on Complete
$.ajax({
url: uri,
cache: false,
beforeSend: function() {
$('#image').show();
},
complete: function() {
$('#image').hide();
},
success: function(html) {
$('.info').append(html);
}
});
Related
I have a function that fires two ajax calls when toggling a radio button. Both calls return a price and put it inside an element. The problem is when I spamclick the radiobutton, sometimes the prices differ from eachother while they should be the same, this means the ajax calls are out of synch with eachother.
I tried removing the part that appends the price from the success function to the complete function, so it only adds the result of the PHP scripts when the entire call is finished. But for some reason it won't append the price when I put it inside the complete function, why is that?
My function:
$('.checkoutwrap input[name=ontwerpcontrole]').on("change", function(e) {
e.preventDefault();
var productid = $(this).closest('.prodinfoleft').siblings('.prodinforight').find('.productid').val();
var $pricediv = $(this).closest('.prodinfoleft').siblings('.prodinforight').find('.prodinfoprice');
$.ajax({
type:'post',
url:"checkout/ontwerpcontrole.php",
data:({ontwerp: ontwerp, productid: productid}),
success:function(data){
},
complete: function(data) {
refreshcoupon(true);
}
});
$.ajax({
type:'post',
url:"checkout/prices.php",
data:({productid: productid}),
success:function(data){
},
complete: function(data) {
$($pricediv).empty().append( data );
}
});
});
Above puts no price in $pricediv, but when I put that part in the success function like this:
$('.checkoutwrap input[name=ontwerpcontrole]').on("change", function(e) {
e.preventDefault();
var productid = $(this).closest('.prodinfoleft').siblings('.prodinforight').find('.productid').val();
var $pricediv = $(this).closest('.prodinfoleft').siblings('.prodinforight').find('.prodinfoprice');
$.ajax({
type:'post',
url:"checkout/ontwerpcontrole.php",
data:({ontwerp: ontwerp, productid: productid}),
success:function(data){
},
complete: function(data) {
refreshcoupon(true);
}
});
$.ajax({
type:'post',
url:"checkout/prices.php",
data:({productid: productid}),
success:function(data){
$($pricediv).empty().append( data );
},
complete: function(data) {
}
});
});
The function used inside the first ajax call:
function refreshcoupon(force){
$.ajax({
type:'post',
url:"checkout/refreshcoupon.php",
data:({}),
success:function(data){
$( "body #coupon" ).empty().append( data );
}
});
}
It works fine (except like mentioned if you click to fast the prices are not the same).
Why is this?
You have couple of synced and couple of sequential ajax calls. Therefor it may happen that first request is done after last one. You probably have more solutions, but simply one would be to check if your variable productid is still same in ajax success function:
$('.checkoutwrap input[name=ontwerpcontrole]').on("change", function(e) {
e.preventDefault();
var $ontwerp = $(this).closest('.prodinfoleft').siblings('.prodinforight').find('.productid');
var productid = $ontwerp.val();
var $pricediv = $(this).closest('.prodinfoleft').siblings('.prodinforight').find('.prodinfoprice');
$.ajax({
type: 'post',
url: "checkout/ontwerpcontrole.php",
data: ({
ontwerp: ontwerp,
productid: productid
}),
success: function(data) {
if ($ontwerp.val() == productid) {
refreshcoupon($ontwerp, productid);
};
}
});
$.ajax({
type: 'post',
url: "checkout/prices.php",
data: ({
productid: productid
}),
success: function(data) {
if ($ontwerp.val() == productid) {
$($pricediv).empty().append(data);
};
}
});
});
function refreshcoupon($ontwerp, productid) {
$.ajax({
type: 'post',
url: "checkout/refreshcoupon.php",
data: ({}),
success: function(data) {
if ($ontwerp.val() == productid) {
$("body #coupon").empty().append(data);
};
}
});
}
Anyhow... looking at this code it does not look fine. Maybe try to do it with only one ajax call, save resources, reduce errors and debugging etc.
In below code after ajax is completed or successed $(".cdmodels").append(result); does not executed but two next lines are executed. i have checked different way but it's not solved. please help me.
$('.load-more').on('click', function (e) {
e.preventDefault();
var count = $(this).attr('data-value');
var btn = $(this).button('loading');
$.ajax({
url: "#Url.Action(MVC.Library.Index())",
data: { count: count },
dataType: 'json',
async: true,
method: 'POST',
complete: function (result) {
$(".cdmodels").append(result);
btn.button('reset');
btn.attr("data-value", parseInt(count) + 1);
}
});
});
UPDATE:
browser debug:
Usually when you are working with AJAX calls and if you are struck you should debug as shown below
Log the response. console.log(response)
Check for the type of response. console.log(Object.prototype.toString.call(response)
$('.load-more').on('click', function (e) {
e.preventDefault();
var count = $(this).attr('data-value');
var btn = $(this).button('loading');
$.ajax({
url: "#Url.Action(MVC.Library.Index())",
data: { count: count },
dataType: 'json',
async: true,
method: 'POST',
complete: function (result) {
// In your case it should be result.responseText
$(".cdmodels").append(result.responseText);
btn.button('reset');
btn.attr("data-value", parseInt(count) + 1);
}
});
});
Have you checked it using a try/catch block?
...
complete: function (result) {
try{
$(".cdmodels").append(result);
btn.button('reset');
btn.attr("data-value", parseInt(count) + 1);
}catch(e) {
console.log("Something went wrong! Watch for 'e' and 'result'");
debugger;
}
}
...
start with devtools open.
The complete callback receives a object with several properties. You cannot directly use that to update your DOM. If you want you can use the responseText property.
This should work.
$(".cdmodels").append(result.responseText);
Or even better, use the done() callback
$.ajax({
url: "#Url.Action("Index")",
data: { count: 2 },
method: 'POST'
}).done(function (res) {
console.log('done');
$(".cdmodels").append(res);
});
The jqXHR.success(), error(), and complete() callbacks are removed as of jQuery 3.0. You should use jqXHR.done(), fail(), and always() instead.
I know that in some browsers (IE, Chrome) that changes to the DOM won't take place until after a function is completed. I have read through various suggestions on how to deal with this, but I'm not having any luck. I'm trying to loop through a series of AJAX calls and show progress for each line that is being processed. The code is like this:
for(i=0; i < rowIds.length; i++){
$(rowImage).attr('src', '/images/spinner.gif');
$.ajax({
type: 'GET',
url: ajaxUrl,
async: false,
processData: true,
data: {},
dataType: "json",
success: function(data) {
$(rowImage).attr('src', '/images/success.gif');
}
});
}
I've read several suggestions about trying to insure that the image transformation takes place before proceeding, such as doing this before the AJAX call starts:
var changeImage = function() {
$(rowImage).attr('src', '/images/spinner.gif');
};
$.when(changeImage() ).done( function() {
//run AJAX call
But that doesn't make a difference. The images don't change until after the function is finished executing.
You will note that I have async set to false, and I'm doing that for various reasons. But even without that in place, the issue persists. I've also tried using setTimeOut() as has been suggested, and that doesn't seem to work (And I know that setTimeOut() is meant for async mode, but even in async it doesn't seem to help.)
Jquery:
$.ajax({
type: 'GET',
url: ajaxUrl,
async: false,
processData: true,
data: {},
dataType: "json",
success: function(data) {
$(rowImage).attr('src', '/images/success.gif');
}
});
$(document).ajaxStart(function () {
$(rowImage).attr('src', '/images/spinner.gif');
}).ajaxStop(function () {
});
I am using ASP.NET MVC and jQuery and I am loading a PartialView via Ajax. A seperate JavaSriptFile belongs to this PartialView. On success, the return html is inserted in the DOM. In the JavaScript, some stuff is done and that together might take a little moment. The loaded content is then displayed in a dialog.
Simplified Code:
1 $.ajax({
2 url: /user/edit,
3 dataType: 'html',
4 data: { id: 1 },
5 success: function (htmlCode) {
6 $('#dialogEditUser').html(htmlCode);
7 $('#dialogEditUser').dialog('open');
8 });
9 };
This code works and sometimes not, depending on how fast the PartialView's JavaScript is executed. So sometimes, the dialog does not open. So i changed line number 7 to;:
7 setTimeout(function() { $j('#dialogEditUser').dialog('open') }, 250);
Now everything works fine. But this "hack" is not very suitable. How can I check if the PartialView's JavaScript has been executed on the loaded content? Is there maybe any way to return a fully rendered PartialView (so the JavaScript has already been executed where I get the return of the AjaxCall?
By default ajax will not wait for the request to finish.
Try setting async option to false:
$.ajax({
url: /user/edit,
dataType: 'html',
async: false,
data: { id: 1 },
success: function (htmlCode) {
$('#dialogEditUser').html(htmlCode);
$('#dialogEditUser').dialog('open');
});
};
More details in docs
Why not make the $('#dialogEditUser').dialog('open'); in the js you are loading? That way when the call is made you know the corresponding js is loaded already
Try wrapping that code in a ready block:
$(document).ready(function(){
$.ajax({
url: /user/edit,
dataType: 'html',
data: { id: 1 },
success: function (htmlCode) {
$('#dialogEditUser').html(htmlCode);
$('#dialogEditUser').dialog('open');
});
};
});
'#dialogEditUser' might to be loaded yet when the success callback gets called.
If, at the end of your partial view, you have got an element with an specific id like #finishLoad. Why not try this?
var waitToOpenDialog = function(){
var jFinish = $('#finishLoad');
if(jFinish.length<=0){
setTimeout(waitToOpenDialog, 10);
}else{
$('#dialogEditUser').dialog('open');
}
}
$.ajax({
url: /user/edit,
dataType: 'html',
data: { id: 1 },
success: function (htmlCode) {
$('#dialogEditUser').html(htmlCode);
waitToOpenDialog();
});
};
Well if you cant modify your DOM or don't have any id like #finishLoad you cant try (keeping async=true) with (more or less) this:
var waitToOpenDialog = function(){
var jDialogUser= $('#dialogEditUser');
if(jDialogUser.html().length<=0){
setTimeout(waitToOpenDialog, 10);
}else{
jDialogUser.dialog('open');
}
}
$.ajax({
url: /user/edit,
dataType: 'html',
data: { id: 1 },
success: function (htmlCode) {
$('#dialogEditUser').html(htmlCode);
waitToOpenDialog();
});
};
Or you can try with complete:
$.ajax({
url: /user/edit,
dataType: 'html',
data: { id: 1 },
success: function (htmlCode) {
$('#dialogEditUser').html(htmlCode);
},
complete: function(){
$('#dialogEditUser').dialog('open');
}
)};
I am trying to write a jQuery Ajax function, to reduce the amount of code in the page because the script is called a few times in the page. I can't seem to get it to work. Here is the code i have:
var loadURL = $(this).attr('href');
function load(){
$.ajax({
url: loadURL,
type: 'GET',
cache: true,
data: {
delay: 4
},
success: function(data) {
$('#load').html(data)
}
});
return false;}
$('#one').click(function(){ load(); });
$('#two').click(function(){ load(); });
$('#three').click(function(){ load(); });
Two
Two
Two
can anyone guide me here please?
i think the way you are getting href is wrong
function load(item){
var loadURL = $(item).attr('href');
$.ajax({
url: loadURL,
type: 'GET',
cache: true,
data: {
delay: 4
},
success: function(data) {
$('#load').html(data)
}
});
return false;}
$('#one').click(function()
{
load($(this));
return false; //you should mention return false here
});
It is worth noting that you can define your own jQuery functions if you wish..