简体   繁体   中英

How to show loader image with message at center & prevent bootstrap modal dialog box from closing while AJAX response is coming from PHP file?

I'm using Bootstrap v 3.0.0 . I've following HTML code of Bootstrap Modal:

<div class="modal fade" id="newModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
      <div class="modal-dialog">
        <div class="modal-content">
          <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
            <h4 class="modal-title">Submit Form</h4>
          </div>
          <div class="modal-body" style="max-height: 300px; overflow-y: auto;">
            <br/>
            <!-- The form is placed inside the body of modal -->
            <form id="request_form" method="post" class="form-horizontal" enctype="multipart/form-data" action="">
              <div class="form-group">
                <label class="col-sm-4 col-sm-offset-1 control-label">Reg ID <span style="color:#FF0000">*</span> :</label>
                <div class="col-sm-5">
                  <input type="text" class="form-control" name="reg_id" id="reg_id"/>
                </div>
              </div>
              <div class="form-group">
                <label class="col-sm-4 col-sm-offset-1 control-label">Reg Date<span style="color:#FF0000">*</span> :</label>
                <div class="col-sm-5">
                  <input type="text" class="form-control date_control" id="reg_date" name="reg_date" value="" placeholder="yyyy-mm-dd">
                </div>
              </div>
              <div class="form-group">
                <label class="col-sm-4 col-sm-offset-1 control-label">Upload Image<span style="color:#FF0000">*</span> :</label>
                <div class="col-sm-5">                   
                  <input type="file" name="reg_image" id="reg_image" accept="image/*" capture="camera" />                  
                </div>
              </div>  
              <div class="form-group">
                <div class="col-sm-5 col-sm-offset-5">
                  <button type="submit" class="btn btn-success" id="btn_receipt_submit">Submit</button>
                  <button type="button" class="btn btn-danger" data-dismiss="modal">Cancel</button>
                </div>
              </div>
            </form>
          </div>
        </div>
      </div>
    </div>

For above bootstrap modal I've written following AJAX-jQuery code :

$('#request_form').submit(function(e) {
  var form = $(this);
  var formdata = false;
  var reg_id = $('#reg_id').val();
  var reg_date = $('#reg_date').val();

  if(window.FormData) {
    formdata = new FormData(form[0]);
  }

  var formAction = form.attr('action');

  $.ajax({
    url         : 'xyz.php',
    type        : 'POST',    
    cache       : false,
    data        : formdata ? formdata : form.serialize(),
    contentType : false,
    processData : false,
    beforeSend: function() { 
      $(".btn").prop('disabled', true); // disable both the buttons on modal      
    },

    success: function(response) {
      $(".btn").prop('disabled', false); // enable both the buttons on modal
      var responseObject = $.parseJSON(response);    
      if(responseObject.error_message) {
        if ($(".alert-dismissible")[0]) {
          $('.alert-dismissible').remove();   
        }  
        var htmlString = "<div class='alert alert-danger alert-dismissible' role='alert'><button type='button' class='close' data-dismiss='alert' aria-hidden='true'>&times;</button>"+responseObject.error_message+"</div>";    
        $(htmlString).insertBefore('div.modal-body #request_form');        
      } else {
        $('#newModal').modal('hide');
        $('#Modal2').modal('show');       
      }
    }
  });
  e.preventDefault();
});

I want to show some appropriate loader image exactly at the the center of the screen along with the message "Your request is processing...please wait" when the AJAX request goes to PHP file and it should be displayed exactly at the center of the screen until the response from PHP file comes.

Also during this time user should not be able to close the modal, nor it should get hidden if user clicks anywhere apart from the modal. In other words, until the response from PHP file comes user should not be able to do anything.

I tried many tricks but I'm only able to disable the two buttons appearing on form until the response comes. But actually I want to do much more than this.

http://jsfiddle.net/cnvusn04/2/

CSS:

.modal { text-align: center; }

.modal:before { display: inline-block; vertical-align: middle; content: " "; height: 100%; }

.modal-dialog { display: inline-block; text-align: left; vertical-align: middle; }

JQ:

$('#myModal').modal({
    show:false,
})

// prevents closure while the ajax call is in progress
$('#myModal').on('hide.bs.modal', function (e) {   
    if(inProgess == true)
           return false;
})

var inProgess = false;
ajaxCall();

function ajaxCall()
{
    inProgess = true;
    $('#myModal').modal('show');

    //simulates the ajax call
    setTimeout(function(){  
        inProgess = false;
        $('#myModal').modal('hide');
    }, 5000);    

}

Here is what you could do:

  • Use css to create a spinning icon
  • As for the positioning of the icon and message do the following:
    • create div that covers the whole page
    • set the z-index to a high value, higher than that of modal
    • use css to center content in the div
    • the div should initially be hidden
    • when the submit event fires the div is made visible which then disables any user action
  • Use the following JavaScript:

The JavaScript:

$(function() {
    var mod1 = $('#newModal'),
        mod2 = $('#modal2'),
        btn = $('.open-form'),
        ldg = $('#loading');

    mod1.add(mod2).modal({show: false});

    btn.on('click', function() {
        mod1.modal( 'show' );
    });

    $('#request_form').submit(function(e) {
        e.preventDefault();
        ldg.find('> div > span').text('Please wait as your file is uploaded')
        .end().show();
        var form = $(this);
        var formdata = false;
        var reg_id = $('#reg_id').val();
        var reg_date = $('#reg_date').val();

        if(window.FormData) {
            formdata = new FormData(form[0]);
        }

        var formAction = form.attr('action');

        $.ajax({
            url         : formAction,
            type        : 'POST',    
            cache       : false,
            data        : formdata ? formdata : form.serialize(),
            contentType : false,
            processData : false,
            success: function(response) {
              ldg.hide();
              var responseObject = $.parseJSON(response);    
              if(responseObject.error_message) {
                if ($(".alert-dismissible")[0]) {
                  $('.alert-dismissible').remove();   
                }  
                var htmlString = "<div class='alert alert-danger alert-dismissible' role='alert'><button type='button' class='close' data-dismiss='alert' aria-hidden='true'>&times;</button>"+responseObject.error_message+"</div>";    
                $(htmlString).insertBefore('div.modal-body #request_form');        
              } else {
                $('#newModal').modal('hide');
                $('#Modal2').modal('show');       
              }
            }
          });
    });
});

The Demo:

DEMO

Notice that i expect that your question should be close cause it is "too broad".

You can try to disable the mouse event on the modal:

$(".modal").css('pointer-events','none');

See also: https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events

The above does not disable the button (used to open the modal), but you can keep your first solution. Also notice that you will have to set the modal's keyboard option false to pevent closing with the escape key.

Alternatively you code set a overlay with a higher z-index than the modal

CSS:

html, body{
  height:100%;
}

#disableall{
position: absolute;
width: 100%;
height:100%;
z-index:1050;
background-color: rgba(255,0,0,0.5);
display:none;
}

html directly after the <body> tag:

<div id="disableall"></div> 

javascript :

 beforeSend: function() { 
      $("disableall").show(); 
    },

it worked for me try like this

css

#pageloaddiv {
position: fixed;
margin: 0px;
width: 100%;
height: 100%;
z-index: 100000;
background: url('../img/ajax-loader.gif') no-repeat center center rgba(0, 0, 0, 0.38);
}

html

<div id="pageloaddiv" style="display: none;"></div>

javascript

$.ajax({
    url: 'your url',  
    beforeSend:function(){
        $('#pageloaddiv').show();     
    },
    success: function() {
        $('#pageloaddiv').hide();
        $('#newModal').hide();
    },
});

is there anything wrong with using something like font awesome icons that are animated

<i class="fa fa-spin fa-3x"></i>

the above then might do the trick for you

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM