【问题标题】:Bootstrap 4 - Open modal A; Close Modal A; Open Modal B - A not closingBootstrap 4 - 打开模态 A;关闭模态A;打开模态 B - A 未关闭
【发布时间】:2019-01-09 06:08:43
【问题描述】:

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

当用户点击发送按钮时,我打开一个模式#apply_working_modal,它只显示一个微调器图标。在 ajax.done 上,我关闭#apply_working_modal,如果有错误,将它们放在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>

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

为了在发布问题时清楚起见,我简化了 ajax 请求,因为我认为这不是原因 - 在我的代码中,我使用 'etc:etc' 作为 ajax 参数,这是为了表明我简化了代码.我确实在使用缓存:假。完整调用如下(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"
    });

【问题讨论】:

  • 只是一个想法,但我遇到了类似的问题。就我而言,禁用 ajax 缓存有效。你试过在你的ajax请求中设置cache: false;吗?
  • ajaxSubmit 怎么叫?
  • 添加了显示我正在使用缓存的代码:false;。并且,通过单击提交按钮调用 ajaxSubmit

标签: jquery modal-dialog bootstrap-4


【解决方案1】:

您是对的,如果背景动画尚未完成,模态将隐藏。见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。很可能是因为在触发.done() 之前已经触发了shown.bs.modal。所以尝试这样做:

(另一个更新) 抱歉,我自己忘了使用.one().. 其次,我将它与setTimeout() 方法结合起来,这样模态隐藏不会太快。 .

(2018 年 8 月 15 日th 我添加了缺失的部分 - $("#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;
            });
        }

        ...
    });

}

这里是 a 更新后的 demo 用于shown.bs.modal 事件,another demo 用于setTimeout() 方法。

补充说明

在这里你应该使用.one() 而不是.on()

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

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

【讨论】:

  • Re cache: false ,请参阅我在问题中的更新,我正在使用它。很快就会尝试你的答案,即将开会。
  • 当然,慢慢来。不过,我已经更新了答案。
  • Sally CJ 对此表示感谢,它似乎在 Chrome 上完美运行(没有超时的版本),但在 Edge 和 iOS 上,对于成功的应用程序来说,等待模式似乎关闭得太早了。今天玩的时间很紧,可能要到周一才能回来,所以如果赏金到期,请接受你的回答!感谢您的所有工作和演示!
  • 在 iOS 平板电脑、OSX Mac 和 Android 平板电脑以及 Edge、IE11、Chrome、Opra 和 FireFox Win 10 上测试 - 一切正常,非常感谢!我认为这“此外,对过渡组件的方法调用将被忽略。”是我的问题的关键。我一定在文档中错过了这一点。从来不知道 .one ,是的,我确实看到了您所描述的多次通话的问题。很好的答案!
  • 在你的回答中你应该显示 $("#apply_working_modal").modal("show");就在设置 modal_shown 之后(在你的...之前)。您已经在演示中,但只是为了让任何只看答案的人都清楚。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-20
  • 2023-03-30
  • 1970-01-01
  • 2021-05-22
  • 1970-01-01
  • 1970-01-01
  • 2022-11-29
相关资源
最近更新 更多