Joel James
Joel James

Reputation: 3938

Show a loading bar using jQuery while making multiple AJAX request

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?

Upvotes: 1

Views: 2430

Answers (4)

nate_weldon
nate_weldon

Reputation: 2349

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);
    }
});

Upvotes: 0

Mike
Mike

Reputation: 1738

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.
  }
});

Upvotes: 1

AmericanUmlaut
AmericanUmlaut

Reputation: 2837

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.

Upvotes: 0

gulty
gulty

Reputation: 1076

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..

Upvotes: 2

Related Questions