如何重组代码以使Bootstrap的模态方法使用回调异步? [英] How to restructure the code in order to make Bootstrap's modal methods asynchronous using callbacks?

查看:57
本文介绍了如何重组代码以使Bootstrap的模态方法使用回调异步?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将 Bootstrap v3.3.0 用于我的网站.我正在使用 Bootstrap框架的Modal 对话框功能.

我为表单提交编写了一个jQuery-AJAX函数,如下所示:

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

以上功能正常运行,但有时在收到error_message作为响应时,ID为"rebateModal" 的模态不会出现.尽管有时候在某些浏览器中我没有遇到这个问题,但是一切都可以顺利进行.

因此,我想重新构造有关使用Bootstrap的函数回调调用模态方法的代码,如下所示:

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

但是由于我是Bootstrap框架和JS的新手,所以我无法以上述方式编写代码.

那么有人可以帮助我重组使用Bootstrap函数回调编写的代码吗?

如果您需要有关Bootstrap中函数回调的其他信息,请参见以下链接: 链接到Bootstrap Modal功能

谢谢.

我猜想是因为您想使用回调函数,所以您怀疑在submit函数中的调用之间可能存在竞争条件(大概是由于在动画上花费的时间):

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

以及AJAX成功函数中的调用(当响应包含error_message时):

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

在这种情况下,一种可能的实现方式是:

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

仅通过在进行了隐藏回调(在隐藏动画完成后应发生)之后继续进行AJAX调用,您才可以消除可能的竞争条件,在这种情况下,AJAX调用返回的错误比模式隐藏动画更快. /p>

这只是一个粗略的实现.您可能还希望将内部代码提取到一个可以按名称调用的单独函数中.这样一来,您可以包装一些初始逻辑来处理各种情况(例如,如果在调用表单提交功能时#rebateModal不可见)

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.

解决方案

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)

这篇关于如何重组代码以使Bootstrap的模态方法使用回调异步?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆