How to restructure the code in order to make Boots

2019-05-19 23:22发布

问题:

I'm using Bootstrap v3.3.0 for my website. I'm using Bootstrap framework's Modal dialog functionality.

I've written one jQuery-AJAX function for form submission as follows:

$('#rebate_request_form').submit(function(e) {  
  $('#rebateModal').modal('hide');
  $('#progressModal').modal('show');   

  var fileInput = $("#receipt_image")[0];  
  var input =  $("#receipt_image").val(); 

  var form = $(this);

  var formdata = false;

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

  if(input != '') {
    var ImgSizeInBytes = fileInput.files[0].size;  
    var filename = $('input[type=file]').val().split('\\').pop();
    var customer_id = $('#customer_id').val();
  }  
  if(input!='' && ImgSizeInBytes > 10485760) {
    var trans_id = $('#trans_id').val();  
    var trans_date_dateLists_year_list = $("#trans_date_dateLists_year_list").val();
    var trans_date_dateLists_month_list = $("#trans_date_dateLists_month_list").val();
    var trans_date_dateLists_day_list = $("#trans_date_dateLists_day_list").val();  

    var params = "trans_id="+trans_id+"&trans_date_dateLists_day_list="+trans_date_dateLists_day_list+"&trans_date_dateLists_month_list="+trans_date_dateLists_month_list+"&trans_date_dateLists_year_list="+trans_date_dateLists_year_list+"&file_size="+ImgSizeInBytes+"&file_name="+filename+"&customer_id="+customer_id;
    var method = 'GET';
  } else {
    var params = formdata ? formdata : form.serialize();
    var method = 'POST';
  }  

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

  $.ajax({
    url         : 'rebate_request.php',
    type        : method,    
    cache       : false,
    data        : params,
    contentType : false,
    processData : false,

    success: function(response) {
      $('#progressModal').modal('hide');
      var responseObject = $.parseJSON(response);    
      if(responseObject.error_message) {
        $('#rebateModal').modal('show');  
        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 #rebate_request_form');        
        } else { 
          $('#successModal').modal('show');       
        }
      }
    });
    e.preventDefault();
  });

The above function is working properly but sometimes the modal with id "rebateModal" doesn't show up when error_message is received in response. Though sometimes in some browsers I don't encounter this issue, everything just works smoothly.

So I want to restructure my code regarding calling the modal methods using Bootstrap's function callbacks as follows:

$('#rebateModal').one('hidden.bs.modal', function () {
  $('#progressModal').one('shown.bs.modal', function () {
  //...more code...
  }).modal('show');
}).modal('hide');

But I'm not able to write my code in above fashion since I'm a newbie to Bootstrap framework and JS.

So can someone please help me in restructuring the code I've written using Bootstrap's function callbacks?

If you need additional information regarding function callbacks in Bootstrap please refer below link: Link for Bootstrap Modal functionality

Thanks in advance.

回答1:

I presume since you are wanting to use the callback functions, that your suspicion is there may be a race condition between the call in the submit function (presumably due to time spent in animations):

$('#rebateModal').modal('hide');

And the call in the AJAX success function (when response contains an error_message):

$('#rebateModal').modal('show');

In that case, one possible implementation would be:

$( '#rebate_request_form' ).submit( function(e) {
    $( '#rebateModal' ).one( 'hidden.bs.modal', function () {
        $('#progressModal').one( 'shown.bs.modal', function () {
            var fileInput = $("#receipt_image")[0];  
            var input =  $("#receipt_image").val(); 

            var form = $( '#rebate_request_form' );

            var formdata = false;

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

            if(input != '') {
                var ImgSizeInBytes = fileInput.files[0].size;  
                var filename = $('input[type=file]').val().split('\\').pop();
                var customer_id = $('#customer_id').val();
            }  
            if(input!='' && ImgSizeInBytes > 10485760) {
                var trans_id = $('#trans_id').val();  
                var trans_date_dateLists_year_list = $("#trans_date_dateLists_year_list").val();
                var trans_date_dateLists_month_list = $("#trans_date_dateLists_month_list").val();
                var trans_date_dateLists_day_list = $("#trans_date_dateLists_day_list").val();  

                var params = "trans_id="+trans_id+"&trans_date_dateLists_day_list="+trans_date_dateLists_day_list+"&trans_date_dateLists_month_list="+trans_date_dateLists_month_list+"&trans_date_dateLists_year_list="+trans_date_dateLists_year_list+"&file_size="+ImgSizeInBytes+"&file_name="+filename+"&customer_id="+customer_id;
                var method = 'GET';
            } else {
                var params = formdata ? formdata : form.serialize();
                var method = 'POST';
            }  

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

            $.ajax( {
                url         : 'rebate_request.php',
                type        : method,    
                cache       : false,
                data        : params,
                contentType : false,
                processData : false,

                success: function(response) {
                    $('#progressModal').one( 'hidden.bs.modal', function () {
                        var responseObject = $.parseJSON(response);    
                        if(responseObject.error_message) {
                            $('#rebateModal').modal('show');  
                            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 #rebate_request_form');        
                        } else { 
                            $('#successModal').modal('show');       
                        }
                    } ).modal('hide');
                }
            });
        } ).modal( 'show' );
    } ).modal( 'hide' );
    e.preventDefault();
} );

By only proceeding with the AJAX call after the hidden callback has been made (which should occur once the hiding animation is complete) you eliminate the possible race condition where the AJAX call returned with an error faster than the modal hiding animation.

This is just a rough implementation. You would probably also want to pull out that inner code into a separate function that you can call by name. That would allow you to wrap some initial logic to handle various scenarios (for example if #rebateModal is not visible when the form submit function is called)