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

11,187

Solution 1

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

Solution 2

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

Solution 3

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(); 
    },
Share:
11,187

Related videos on Youtube

halfer
Author by

halfer

I'm a (mainly PHP) contract software engineer, with interests in containerisation, testing, automation and culture change. At the time of writing I am on a sabbatical to learn some new things - currently on the radar are Modern JavaScript, Jest and Kubernetes. I wrote a pretty good PHP tutorial, feedback on that is always welcome. I often scribble down software ideas on my blog. My avatar features a sleepy fur bundle that looks after me. I've written about how to ask questions on StackOverflow. I don't spend as much time answering questions these days - I think my time is better spent guiding people how to ask. I try to look after beginners on the platform - if anyone reading this has had a "baptism of fire", don't worry about it - it gets easier. If you'd like to get in touch, find the 'About' page of my blog: there's an email address there.

Updated on June 04, 2022

Comments

  • halfer
    halfer almost 2 years

    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.

  • PHPLover
    PHPLover over 9 years
    :Thanks for your answer but if you look at the issue closely you will come to know that I want to show the loader image and message exactly at the center of the screen so can you please tell me where should I put <div id="pageloaddiv" style="display: none;"></div> in my code in order to display this at the centre of the screen?
  • Dexter
    Dexter over 9 years
    put after this <div class="modal fade" id="newModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
  • PHPLover
    PHPLover over 9 years
    I tried your code but neither the loader is not getting displayed nor the message. Also as the request goes to server everythin just got fade in, user can't click anywhere. Even after coming the response the effect remains. How to resolve these things?
  • PHPLover
    PHPLover over 9 years
    Thanks for your answer. The only modification I need in the fiddle you provided is the appropriate loader image should also get displayed along with the message and that's the main issue I'm facing. Can you please help me in it?
  • PHPLover
    PHPLover over 9 years
    Thanks once again for your help. This is the exact thing I want to do. But one issue is still there. I'm having one modal pop-up opened which contains the form. You are also showing the rotating image and message in a new modal. For showing this modal I've to close the modal which contains the form. Actually I want to show the modal containing form, show the loader image and message on it and prohibit the user from doing any activity until the response comes. How to achieve this?
  • Admin
    Admin over 9 years
    @dm4web:Thanks for your immense help. You did exactly what I wanted to do. But there is still one major issue. The tool-tip image is not getting hidden once it it opened on smart devices like iPhone, iPad and other android devices. Once this issue is resolved then it will be really great. Can you do please resolve this issue? Thanks once again.