Implementar un indicador de carga para una llamada jQuery AJAX

88

Tengo un modal Bootstrap que se inicia desde un enlace. Durante unos 3 segundos, permanece en blanco, mientras que la consulta AJAX recupera los datos de la base de datos. ¿Cómo puedo implementar algún tipo de indicador de carga? ¿Twitter bootstrap proporciona esta funcionalidad de forma predeterminada?

EDITAR: código JS para 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>
devcoder
fuente

Respuestas:

40

Supongo que estás usando jQuery.get o alguna otra función jQuery ajax para cargar el modal. Puede mostrar el indicador antes de la llamada ajax y ocultarlo cuando se complete el ajax. Algo como

$('#indicator').show();
$('#someModal').get(anUrl, someData, function() { $('#indicator').hide(); });
Jacob Mouka
fuente
164

Resolví el mismo problema siguiendo este ejemplo:

Este ejemplo usa la biblioteca jQuery JavaScript.

Primero, cree un icono de Ajax usando el sitio AjaxLoad .
Luego agregue lo siguiente a su HTML:

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

Y lo siguiente a su archivo CSS:

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

Por último, debe conectarse a los eventos Ajax que proporciona jQuery; un controlador de eventos para cuando comienza la solicitud Ajax y uno para cuando termina:

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

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

Esta solución es del siguiente enlace. Cómo mostrar un icono animado durante el procesamiento de solicitudes Ajax

delgado
fuente
+1 para el mecanismo de enganche "hacer una sola vez". Pero un indicador de carga fijo no es tan bueno para los modales que generalmente tienen una superposición que ocultará parcialmente el indicador de carga ... mejor poner el indicador de carga dentro del modal en ese caso, por ejemplo, en la barra de título. ¿O tal vez agregar un índice Z alto al indicador para que se muestre sobre la superposición?
Pierre Henry
3
Hey, todos ... Vea una demostración basada en esta respuesta.
Paul Vargas
Solo recuerde poner esos scripts DESPUÉS de la referencia al script JQuery. Solo paso una hora debido al orden inverso de colocación dentro de la página.
Greg Z.30 de
Parece ajaxStart()y ajaxStop()sería una mejor solución según la respuesta de @ajaristi, ya que estos disparan solo una vez por lote de AJAX: stackoverflow.com/questions/3735877/…
SharpC
30

Hay una configuración global usando jQuery. Este código se ejecuta en cada solicitud global de Ajax.

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

Aquí hay una demostración: http://jsfiddle.net/sd01fdcm/

ajaristi
fuente
1
Esto funciona muy bien, pero no olvide agregar un css de índice z para los sitios que usan modal.
Deise Vicentin
1
Esto debería tener más votos que la respuesta de @leansy, ya que se usa correctamente .ajaxStart()y se activa ajaxStop()una vez por lote de AJAX: stackoverflow.com/questions/3735877/… .
SharpC
14

Un indicador de carga es simplemente una imagen animada (.gif) que se muestra hasta que se llama al evento completado en la solicitud AJAX. http://ajaxload.info/ ofrece muchas opciones para generar imágenes de carga que puede superponer en sus modales. Que yo sepa, Bootstrap no proporciona la funcionalidad incorporada.

HenryZhang
fuente
6

Así es como lo hice funcionar con la carga de contenido remoto que debe actualizarse:

$(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');
    });
});

Básicamente, simplemente reemplace el contenido modal mientras se carga con un mensaje de carga. El contenido será reemplazado una vez que haya terminado de cargarse.

Rhys Stephens
fuente
3

Así es como me di cuenta del indicador de carga por un 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
fuente