如何在Twitter Bootstrap中同时打开两个模态对话框

时间:2014-03-28 12:36:50

标签: javascript jquery twitter-bootstrap twitter-bootstrap-3 bootstrap-dialog

我已在项目中实现了引导程序对话框。我在该对话框中有一些删除功能,删除确认消息打开另一个引导对话框。但是当第二个确认对话框打开时,第一个对话框不会被禁用,所有事件都会起作用。

是否有其他对话框打开时禁用原始对话框的解决方案?

这是我的代码:

function OpenDialogForSelectionAdmItem(title, content, callback) {
    var dlg = new BootstrapDialog({
        title: title,
        content: content,
        buttons: [{
            label: 'Save',
            cssClass: 'btn-primary',
            id: 'btnSave',
            onclick: function (dialog) {

            }
        },
        {
            label: 'Close',
            cssClass: 'btn',
            id: 'btnClose',
            onclick: function (dialog) {
                if (callback != "") {
                    callback(true);
                }
                dialog.close();
            }
        }]
    });

    dlg.open();`
}

截图:

Screenshot

当删除确认对话框打开时,我想禁用第一个对话框。

4 个答案:

答案 0 :(得分:55)

问题:

为了理解Web开发中模态对话框的复杂性,您需要更多地了解z-index property and stacking contexts

简而言之,该对话框的工作原理是向DOM添加两个主要组件:占据整个屏幕的背景,以及包含对话框的div。每个都从页面的其余部分中脱颖而出,因为它们被置于DOM的根级别,并为其z-index属性赋予了高价值。 有多高?好吧,尝试在空白页面添加空白模态,然后您将看到以下DOM元素:

<div class="modal-backdrop fade in"></div>  <!-- z-index: 1030; -->
<div class="modal bootstrap-dialog">        <!-- z-index: 1040; -->
    <div class="modal-dialog">              <!-- z-index: 1050; -->

modal-backdrop给出了真实模态过程的错觉,因为它首先呈现了阻止点击在下方任何地方点击的所有其他内容。允许modal-dialog获得点击次数的唯一原因是,它通过提供更高的z-index,将堆叠在背景的顶层上。

那就是它!那是一大堆技巧。因此,当引导程序cautions against use multiple dialogs时,它们会这样做,因为堆叠变得棘手。如果添加另一个元素,它将使用相同的精确z-index进行渲染,这意味着它将位于常规页面内容之上,但与原始对话框位于同一平面上。如果它没有完全覆盖原件,那么原件仍然可以点击,因为它上面没有背景。

解决方案:

要解决此问题,您需要提出自己的方法来禁用对背景模式的点击。此问题似乎已解决(部分)。请参阅以下示例:

Demo in jsFiddle

Bootstrap Dialog使得单击关闭对话框只会关闭DOM中的最后一个对话框并将事件标记为已处理,因此它不会触发任何其他内容。如果第二个模态已经启动并且您单击它,那么唯一会发生的是第二个模态将关闭。


更高级处理:

如果您希望第二个模式看起来,就像第一个模式一样,您必须手动执行此操作。

创建新模态时,它会附带自己的modal-backdrop。当显示第二个模态时,您可以通过相对于第一个模态递增其z-index使其显示在原始模式上方。在onshown事件中,我们只需抓取当前模态及其覆盖并使用.CSS方法修改z-index。我们希望它出现在任何现有模态之上,因此首先我们计算DOM中的模态数($('.bootstrap-dialog').length),然后递增z-index,使其高于下一个最高值对话框。

这样打电话:

function OpenDialogForSelectionAdmItem(title, content, callback) {
    var dlg = new BootstrapDialog({
        title: title,
        message: content,
        onshown: function(dialog) {
            var tier = $('.bootstrap-dialog').length - 1;
            dialog.$modal.prev(".modal-backdrop")
                .css("z-index", 1030 + tier * 30);
            dialog.$modal
                .css("z-index", 1040 + tier * 30);
        } 
        // More Settings
    }).open();
}

Working Demo in jsFiddle

截图:

screenshot


作为概念验证,这里有一个Demo,允许您在其他对话框之上不断添加对话框

Infinite Dialogs Fiddle


UX警告:

虽然技术上可以实现modals within modals can create a confusing UX,但如果您遇到问题,正确的答案可能是尝试通过采用原始工作流并将其推广到带有网址的整页设计来完全避免它和州。

答案 1 :(得分:1)

首先将类添加到主模式中:<div class="modal-content kk"> 我只是使用:

$('#myModal1').on('shown.bs.modal', function () {
  $('.kk').addClass('magla');
  $('#myModal').modal('hide');
 });
$('#myModal1').on('hidden.bs.modal', function () {
  $('.kk').removeClass('magla');
  $('#myModal').modal('show');


});

其中.magla css是:

.magla {
     -webkit-filter: blur(5px);
  -moz-filter: blur(5px);
  -o-filter: blur(5px);
  -ms-filter: blur(5px);
  filter: blur(5px);

}

尝试看起来对我很好。

答案 2 :(得分:0)

使用onclick方法隐藏实际模态

<button data-toggle="modal" data-target="#modal-to-show-id" onclick="$('#actual-modal-id').modal('hide');">
    Text Button
</button>

答案 3 :(得分:0)

我的简单解决方案:为每个新模态生成一个新ID。然后通过一个变量管理所有内容。 它适用于我的目的,顺便说一句。

var _MODAL_LAST;
$( document ).on( 'show.bs.modal' , '.modal' , function(){
    _MODAL_LAST = $(this);
});
$( document ).on( 'hide.bs.modal' , '.modal' , function(){
    if( _MODAL_LAST.attr('id') !== $(this).attr('id') ){
        return false;
    }else{
        _MODAL_LAST = $(this).prevAll('.modal:first');
    }
});