89

I have a Bootstrap modal which is launched from a link. For about 3 seconds it just sits there blank, while the AJAX query fetches the data from the database. How can I implement some sort of a loading indicator? Does twitter bootstrap provide this functionality by default?

EDIT: JS code for modal

<script type="text/javascript">
  $('#myModal').modal('hide');
  $('div.divBox a').click(function(){
    var vendor = $(this).text();
    $('#myModal').off('show');
    $('#myModal').on('show', function(){             
      $.ajax({
        type: "GET",
        url: "ip.php",
        data: "id=" + vendor,
        success: function(html){
          $("#modal-body").html(html);
          $(".modal-header h3").html(vendor);
          $('.countstable1').dataTable({
            "sDom": "T<'row-fluid'<'span6'l><'span6'f>r>t<'row-fluid'<'span6'i><'span6'p>>",
            "sPaginationType": "bootstrap",
            "oLanguage": {
              "sLengthMenu": "_MENU_ records per page"
            },
            "aaSorting":[[0, "desc"]],
            "iDisplayLength": 10,
            "oTableTools": {
              "sSwfPath": "swf/copy_csv_xls_pdf.swf",
              "aButtons": ["csv", "pdf"]
            }
          });
        }
      });
    });
  });
  $('#myModal').on('hide', function () {
    $("#modal-body").empty();
  });
</script>
Alexander Abakumov
  • 13,617
  • 16
  • 88
  • 129
devcoder
  • 1,675
  • 2
  • 21
  • 28

6 Answers6

166

I solved the same problem following this example:

This example uses the jQuery JavaScript library.

First, create an Ajax icon using the AjaxLoad site.
Then add the following to your HTML :

<img src="/images/loading.gif" id="loading-indicator" style="display:none" />

And the following to your CSS file:

#loading-indicator {
  position: absolute;
  left: 10px;
  top: 10px;
}

Lastly, you need to hook into the Ajax events that jQuery provides; one event handler for when the Ajax request begins, and one for when it ends:

$(document).ajaxSend(function(event, request, settings) {
    $('#loading-indicator').show();
});

$(document).ajaxComplete(function(event, request, settings) {
    $('#loading-indicator').hide();
});

This solution is from the following link. How to display an animated icon during Ajax request processing

Community
  • 1
  • 1
leansy
  • 1,791
  • 2
  • 11
  • 5
  • +1 for the "do only once" hooking mechanism. But a fixed loading indicator isn't that great for modals that usually have an overlay that will partially hide the loading indicator... better to put the loading indicator inside the modal in that case, e.g. in the title bar. Or maybe add a high z-index to the indicator so that it shows above the overlay ? – Pierre Henry Jun 17 '14 at 15:28
  • 3
    Hey, all ... See a [**demo**](https://jsfiddle.net/q3uhLvbn/) based on this answer. – Paul Vargas Mar 20 '15 at 06:29
  • Just remember to put those scripts AFTER the reference to the JQuery script. I just spend an hour because of the reverse order of placement inside the page. – Greg Z. Oct 30 '15 at 15:10
  • It sounds like `ajaxStart()` and `ajaxStop()` would be a better solution as per the @ajaristi answer as these fire only once per AJAX batch: https://stackoverflow.com/questions/3735877/whats-the-difference-between-1-ajaxstart-and-ajaxsend-and-2-ajaxstop-and#3735901 – SharpC May 11 '19 at 11:17
41

I'm guessing you're using jQuery.get or some other jQuery ajax function to load the modal. You can show the indicator before the ajax call, and hide it when the ajax completes. Something like

$('#indicator').show();
$('#someModal').get(anUrl, someData, function() { $('#indicator').hide(); });
Jacob Mouka
  • 2,005
  • 18
  • 26
31

There is a global configuration using jQuery. This code runs on every global ajax request.

<div id='ajax_loader' style="position: fixed; left: 50%; top: 50%; display: none;">
    <img src="themes/img/ajax-loader.gif"></img>
</div>

<script type="text/javascript">
    jQuery(function ($){
        $(document).ajaxStop(function(){
            $("#ajax_loader").hide();
         });
         $(document).ajaxStart(function(){
             $("#ajax_loader").show();
         });    
    });    
</script>

Here is a demo: http://jsfiddle.net/sd01fdcm/

ajaristi
  • 979
  • 1
  • 9
  • 16
  • 1
    This works very well but don't forget to add a z-index css for sites that use modal. – Deise Vicentin Nov 16 '16 at 17:14
  • 1
    This should have more votes than the @leansy answer as it correctly uses `.ajaxStart()` and `ajaxStop()` which fire once per AJAX batch: https://stackoverflow.com/questions/3735877/whats-the-difference-between-1-ajaxstart-and-ajaxsend-and-2-ajaxstop-and#3735901. – SharpC May 11 '19 at 11:09
14

A loading indicator is simply an animated image (.gif) that is displayed until the completed event is called on the AJAX request. http://ajaxload.info/ offers many options for generating loading images that you can overlay on your modals. To my knowledge, Bootstrap does not provide the functionality built-in.

HenryZhang
  • 1,318
  • 8
  • 11
6

This is how I got it working with loading remote content that needs to be refreshed:

$(document).ready(function () {
    var loadingContent = '<div class="modal-header"><h1>Processing...</h1></div><div class="modal-body"><div class="progress progress-striped active"><div class="bar" style="width: 100%;"></div></div></div>';

    // This is need so the content gets replaced correctly.
    $("#myModal").on("show.bs.modal", function (e) {
        $(this).find(".modal-content").html(loadingContent);        
        var link = $(e.relatedTarget);
        $(this).find(".modal-content").load(link.attr("href"));
    });    

    $("#myModal2").on("hide.bs.modal", function (e) {
        $(this).removeData('bs.modal');
    });
});

Basically, just replace the modal content while it's loading with a loading message. The content will then be replaced once it's finished loading.

Rhys Stephens
  • 889
  • 3
  • 20
  • 36
4

This is how I realised the loading indicator by an Glyphicon:

<!DOCTYPE html>
<html>

<head>
    <title>Demo</title>

    <link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/css/bootstrap.min.css">
    <script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.4.min.js"></script>
    <script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/bootstrap.min.js"></script>

    <style>
        .gly-ani {
          animation: ani 2s infinite linear;
        }
        @keyframes ani {
          0% {
            transform: rotate(0deg);
          }
          100% {
            transform: rotate(359deg);
          }
        }
    </style>  
</head>

<body>
<div class="container">

    <span class="glyphicon glyphicon-refresh gly-ani" style="font-size:40px;"></span>

</div>
</body>

</html>
Mathias
  • 317
  • 1
  • 12