引导程序4-开放模式A;封闭模态A;打开方式B-A未关闭

时间:2018-08-01 15:31:14

标签: jquery modal-dialog bootstrap-4

我有求职网站。用户填写表格并从PC中选择CV(简历)文件,然后点击“发送”按钮。这将调用ajaxSubmit()函数,该函数执行本地验证(从下面的代码中删除),如果可以,则执行AJAX文件上传。服务器端进行进一步的验证,并以JSON返回SUCCESS或ERROR(加上错误文本)。

当用户点击“发送”按钮时,我打开一个模态#apply_working_modal,它仅显示一个微调图标。在ajax.done上,我关闭#apply_working_modal,如果有错误,请将其放在模式#apply_errors_modal的主体上并打开它。

我第一次尝试,故意出现错误,它按所述方式工作。如果我再次尝试,但错误仍然存​​在,则会显示#apply_working_modal,并且直到我手动单击X或将其移开时,它才会关闭。

这似乎是一个时间问题,因为在发生错误后重新提交时,CV文件已在服务器上,因此JSON很快返回。实际上,如果我稍微限制一下网络,我就能使其正常工作。

我尝试了等待模态事件的各种方法,还尝试setTimeout()来延迟#apply_errors_modal的打开

function ajaxSubmit(whichForm){

    $("#apply_working_modal").modal("show"); 
    console.log('showing apply_working_modal');

    var applyRequest =$.ajax({
        url: postUrl,
        etc: etc
    });


    applyRequest.done(function( data, textStatus, jqXHR ) {

        console.log(data);

        $("#apply_working_modal").modal("hide");

        console.log("hiding #apply_working_modal ");

        if (data.STATUS =='SUCCESS') {
            // validation OK at server
        }
        else {// validation error at server

            $('#apply_working_modal').on('hidden.bs.modal', function () {
                $("#apply_errors_modal_body").html(data.ErrorText); 
                $("#apply_errors_modal").modal("show");
                console.log("on hidden of #apply_working_modal");
            })
        }               
    });

}

这是好/坏测试的控制台输出:

//Expected behaviour


15:58:45.981 myscript.js:179 showing apply_working_modal

// 10 seconds pass while server uploads file and returns errors in JSON
15:58:56.696 myscript.js:206 {STATUS: "ERROR", ErrorText: "* The Comments are too short."}
15:58:56.700 myscript.js:217 hiding #apply_working_modal 
15:58:56.998 myscript.js:236 on hidden of #apply_working_modal


// Problem behaviour

15:59:26.704 myscript.js:179 showing apply_working_modal
15:59:26.723 myscript.js:206 {STATUS: "ERROR", ErrorText: "* The Comments are too short."}
15:59:26.724 myscript.js:217 hiding #apply_working_modal 


// #apply_working_modal never gets hidden, have to manually close it
// manual dismiss of modal after waitinf 13 secs ....


15:59:38.525 myscript.js:236 on hidden of #apply_working_modal
15:59:38.526 myscript.js:236 on hidden of #apply_working_modal


// error modal shown but logged many times? 

HTML:

 <!-- apply working (spinner while sending cv) -->
  <div id="apply_working_modal" class="modal fade" role="dialog">
    <div class="modal-dialog">
      <div class="modal-content">
       <div class="modal-header"> 
          <h4  class="modal-title"><i class="fa fa-hourglass-end"></i><span class="sr-only">Loading...</span> Sending your CV</h4>
          <button type="button" class="close" data-dismiss="modal"><i class="fa fa-times-circle-o" aria-hidden="true"></i></button>
        </div>
        <div class="modal-body text-center">
          <i class="fa fa-spinner fa-spin fa-5x fa-fw"></i><span class="sr-only">Loading...</span>
        </div>
        <div class="modal-footer">
            &nbsp;
        </div>
      </div>
    </div>
  </div>



 <!-- apply errors modal-->
  <div id="apply_errors_modal" class="modal fade" role="dialog">
    <div class="modal-dialog">

      <!-- Modal content-->
      <div class="modal-content">

       <div class="modal-header">
          <h4 style='color:#cc0000;' class="modal-title"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> There were errors!</h4>
          <button type="button" class="close" data-dismiss="modal"><i class="fa fa-times-circle-o" aria-hidden="true"></i></button>
        </div>

        <div id="apply_errors_modal_body" class="modal-body">
        </div>

        <div class="modal-footer">
            <button data-dismiss="modal" type="button" style="float:left;" class="btn btn-outline-info">Cancel</button>
        </div>

      </div>
    </div>
  </div>

根据下面的答案/评论进行更新。

为了清楚起见,在发布问题时我简化了ajax请求,因为我不认为这是原因-在我的代码中,我将“ etc:etc”用作ajax参数,这表明我简化了代码。我确实在使用cache:false。下面的完整调用(在代码中较早地设置了postUrl):

var applyRequest =$.ajax({
    url: postUrl,
    data: postData,
    type: "POST",
    xhr: function() {  // Custom XMLHttpRequest
        var myXhr = $.ajaxSettings.xhr();
        if(myXhr.upload){ // Check if upload property exists
            myXhr.upload.addEventListener('progress',progressHandler, false); // For handling the progress of the upload
        }
        return myXhr;
    },

    enctype: 'multipart/form-data',
    cache: false,
    processData: false,  // tell jQuery not to process the data (reqd for use with FormData)
    contentType: false,   // tell jQuery not to set contentType
    dataType: "json"
    });

1 个答案:

答案 0 :(得分:4)

您是对的时间安排是正确的,如果背景动画尚未完成,模态将不会被隐藏。参见https://getbootstrap.com/docs/4.1/getting-started/javascript/#asynchronous-functions-and-transitions

  

异步方法和转换

     

所有API方法都是异步并开始过渡。他们   过渡开始后立即返回到呼叫者,但之前   结束。另外,在转换组件上的方法调用   将被忽略

—以上引用来自https://getbootstrap.com/docs/4.1/components/modal/#events

(更新后的答案-我删除了cache: false的内容。)

所以尝试隐藏模态,如下所示:

// Wait for the modal to be made fully visible, where CSS transitions have completed.
$('#apply_working_modal').one('shown.bs.modal', function(){
    $(this).modal("hide");
});

See the description of the shown.bs.modal for more information.

或像这样使用setTimeout()

setTimeout(function(){
    $('#apply_working_modal').modal("hide");
}, 1000);

(再次更新)以上(shown.bs.modal)有效,但在我的测试中,仅当cachetrue时。很可能是因为shown.bs.modal在触发.done()之前已经被触发。因此,尝试以这种方式进行操作:

(另一个更新)抱歉,我本人忘了使用.one() ..其次,我将其与setTimeout()方法结合使用,以使模式隐藏是“太早了..

(2018年8月15日,supsth) 我添加了丢失的部分-$("#apply_working_modal").modal("show");(正好在此答案中;感谢@ KevinSol指出了它出来!)。

function ajaxSubmit(whichForm){

    var modal_shown = false;
    $('#apply_working_modal').one('shown.bs.modal', function(){
        modal_shown = true;
    });

    $("#apply_working_modal").modal("show");

    ...

    applyRequest.done(function( data, textStatus, jqXHR ) {

        ...

        // If the modal has been *fully* visible, simply hides it.
        if (modal_shown) {
            $('#apply_working_modal').modal("hide");
        // Else, wait until it's fully visible, and then hides it.
        } else {
            $('#apply_working_modal').one('shown.bs.modal', function(){
                // Wait a few ms before we hide the modal.
                setTimeout(function(){
                    $('#apply_working_modal').modal("hide");
                }, 100);

                modal_shown = true;
            });
        }

        ...
    });

}

这是针对shown.bs.modal事件的 a 更新后的demo 和针对setTimeout()方法的another demo

附加说明

此处应使用.one()而不是.on()

//$('#apply_working_modal').on('hidden.bs.modal' // before
$('#apply_working_modal').one('hidden.bs.modal'  // correct

以防止事件处理程序被多次触发:

enter image description here