动态构建 Twitter Bootstrap modal

Posted

技术标签:

【中文标题】动态构建 Twitter Bootstrap modal【英文标题】:Dynamically build Twitter Bootstrap modal 【发布时间】:2014-04-14 08:56:07 【问题描述】:

我正在构建一个 Rails 应用程序,我想通过 AJAX 将 Rails 部分中的内容放入模式中。

在 Twitter Bootstrap 2.3.2 模式中,我阅读了文档,您可以使用远程键通过 ajax 加载内容。

http://getbootstrap.com/2.3.2/javascript.html#modals

但是,这只允许将内容注入.modal-body,而不是动态构建整个模式。

有没有办法用JS动态构建整个modal,包括.modal-header.modal-footer

用字符串来做这件事似乎很笨拙,如下所示:

partial = render_to_string(:partial => 'some-partial').gsub(%", %').gsub(/'/,"\\\\'").gsub("\n", "")

【问题讨论】:

我做了一次,它定义了一个 JavaScript 函数,该函数动态地将整个模态的 html 创建为字符串(取决于您想要的标头参数等),然后设置容器的 innerHTML持有模态。通过这种方式,您可以动态控制您想要的模式的各个方面。 @Amnon 你有任何代码示例可以分享吗? 【参考方案1】:

更新:

自从发布这篇文章以来,我发现了一个优雅的 bootstrap 3 模态包装函数here,它不需要在 html 代码中添加 div。


这里有一个代码示例来演示这一点。要使用,只需在

中添加一个 div(在 bootstrap 的 中,例如:
<div id="idMyModal"></div>

然后您可以通过以下方式使用它:

var header = "This is my dynamic header";
var content = "This is my dynamic content";
var strSubmitFunc = "applyButtonFunc()";
var btnText = "Just do it!";
doModal('idMyModal', header, content, strSubmitFunc, btnText);

要关闭模式,请调用 hideModal,也定义如下:

function doModal(placementId, heading, formContent, strSubmitFunc, btnText)

    var html =  '<div id="modalWindow" class="modal hide fade in" style="display:none;">';
    html += '<div class="modal-header">';
    html += '<a class="close" data-dismiss="modal">×</a>';
    html += '<h4>'+heading+'</h4>'
    html += '</div>';
    html += '<div class="modal-body">';
    html += '<p>';
    html += formContent;
    html += '</div>';
    html += '<div class="modal-footer">';
    if (btnText!='') 
        html += '<span class="btn btn-success"';
        html += ' onClick="'+strSubmitFunc+'">'+btnText;
        html += '</span>';
    
    html += '<span class="btn" data-dismiss="modal">';
    html += 'Close';
    html += '</span>'; // close button
    html += '</div>';  // footer
    html += '</div>';  // modalWindow
    $("#"+placementId).html(html);
    $("#modalWindow").modal();



function hideModal()

    // Using a very general selector - this is because $('#modalDiv').hide
    // will remove the modal window but not the mask
    $('.modal.in').modal('hide');

【讨论】:

第一个链接指向一个有编码问题的网站。它将代码部分中的 html 实体转换为两个错误。你应该在这里下载文件,否则代码将不起作用:raw.githubusercontent.com/mohdovais/utilities/master/… 只是一个建议。随着模板文字的出现,这使得编写这段代码的 htmlmuch 更加简洁。查看更多信息here。 @Chris-Jr:感谢它绝对更干净,但目前它仅在最近的浏览器中支持,在 IE 中尚不支持 在引导程序 4 中允许这样做吗? @MartinBraun 谢谢。自从我上次检查后,原始链接已失效...【参考方案2】:

更新

我最近偶然发现了bootbox.js,它是一个完整的库,致力于动态创建引导模式并响应用户与它们的交互。虽然与下面的方法不同,但 bootbox 接受回调而不是函数名。我还没有亲自使用它,因为我不能证明一个 26kb 的库基本上可以完成下面的函数。但我认为有人可能会觉得它很有用。

2016 年 8 月 17 日更新

我现在几乎所有需要动态模态的项目都使用 bootbox。效果很好,我强烈推荐它。

2018 年 10 月 1 日更新

Bootbox 尚未正式支持 bootstrap 4,但有一个 bootbox v5.x 分支,他们正在开发 bootstrap 4 支持。根据5.0.0 roadmap 和Bootbox 5.0 ship list 的票证,听起来分支已经准备就绪,但他们还没有发布。但是有一些关于如何使用它的说明。 免责声明:我还没有使用 v5.x 分支,不能保证它的完整性。

2019 年 3 月 25 日更新

Bootbox 5.0 发布,支持 Bootstrap 4。

原帖

代码取自上面 Ammon 的回答。 bootstrap 3.0 更新

function doModal(placementId, heading, formContent, strSubmitFunc, btnText)

    html =  '<div id="modalWindow" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="confirm-modal" aria-hidden="true">';
    html += '<div class="modal-dialog">';
    html += '<div class="modal-content">';
    html += '<div class="modal-header">';
    html += '<a class="close" data-dismiss="modal">×</a>';
    html += '<h4>'+heading+'</h4>'
    html += '</div>';
    html += '<div class="modal-body">';
    html += formContent;
    html += '</div>';
    html += '<div class="modal-footer">';
    if (btnText!='') 
        html += '<span class="btn btn-success"';
        html += ' onClick="'+strSubmitFunc+'">'+btnText;
        html += '</span>';
    
    html += '<span class="btn" data-dismiss="modal">';
    html += <?php echo "'".__t("Close")."'"; ?>;
    html += '</span>'; // close button
    html += '</div>';  // footer
    html += '</div>';  // content
    html += '</div>';  // dialog
    html += '</div>';  // modalWindow
    $("#"+placementId).html(html);
    $("#modalWindow").modal();
    $("#dynamicModal").modal('show');

这就是我最终用于满足我的需求的东西。还包括一个事件处理程序,用于在关闭 DOM 后从 DOM 中删除模式。我只需要一个信息模式,所以我取出了提交函数和按钮文本参数。

function doModal(heading, formContent) 
    html =  '<div id="dynamicModal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="confirm-modal" aria-hidden="true">';
    html += '<div class="modal-dialog">';
    html += '<div class="modal-content">';
    html += '<div class="modal-header">';
    html += '<a class="close" data-dismiss="modal">×</a>';
    html += '<h4>'+heading+'</h4>'
    html += '</div>';
    html += '<div class="modal-body">';
    html += formContent;
    html += '</div>';
    html += '<div class="modal-footer">';
    html += '<span class="btn btn-primary" data-dismiss="modal">Close</span>';
    html += '</div>';  // content
    html += '</div>';  // dialog
    html += '</div>';  // footer
    html += '</div>';  // modalWindow
    $('body').append(html);
    $("#dynamicModal").modal();
    $("#dynamicModal").modal('show');

    $('#dynamicModal').on('hidden.bs.modal', function (e) 
        $(this).remove();
    );


【讨论】:

bootbox 不错,但不幸的是仍然不支持 bootstrap 4 他们正在开发以 bootstrap 4 作为主要功能的 bootbox v5。但很可能在 bootstrap 4 结束测试版之前不会发布。 (观点,而非事实)。有一个 v5 分支可能可用(我没有测试过)【参考方案3】:

使用 DOM,我创建了 Button 以及在单击 Button 时立即弹出的 Bootstrap 模式。

在 HTML 页面的 head 部分也包括这些:

<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href=      
"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script  
src= "https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js">
</script>
<script  
src= "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js">     
</script>

这段代码需要全部写在JS文件中。

//首先,创建一个按钮,点击显示引导模式

var button = document.createElement("input");
button.className = 'btn btn-info btn-lg';
button.setAttribute("type", "button");
button.setAttribute("data-toggle", "modal");
button.setAttribute("data-target", "#myModal");              
button.setAttribute("value", "More Information...");
document.getElementsByTagName('body')[0].appendChild(button);   

//模态创建:

var div1 = document.createElement('div');
div1.id = 'myModal';
div1.className = 'modal fade';
div1.setAttribute("role", "dialog");     

var innerDiv1m = document.createElement('div');
innerDiv1m.className = 'modal-dialog modal-sm';
div1.appendChild(innerDiv1m);              

var innerDiv2m = document.createElement('div');
innerDiv2m.className = 'modal-content';
innerDiv1m.appendChild(innerDiv2m);

var innerDiv3 = document.createElement('div');
innerDiv3.className = 'modal-header';
innerDiv2m.appendChild(innerDiv3);

var buttonM = document.createElement("button");
buttonM.className = 'close';
buttonM.setAttribute("data-dismiss", "modal");
buttonM.setAttribute("aria-hidden", "true");
buttonM.setAttribute("value", "Close");
innerDiv3.appendChild(buttonM); 

var headerM = document.createElement("H4");
headerM.className = 'modal-title';
innerDiv3.appendChild(headerM);

var innerDiv31 =  document.createElement('div');
innerDiv31.className = 'modal-body';
innerDiv2m.appendChild(innerDiv31);

var para =  document.createElement('p'); 
innerDiv31.appendChild(para);
para.innerHTML = "paragraph";

var innerDiv32 =  document.createElement('div');
innerDiv32.className = 'modal-footer';
innerDiv2m.appendChild(innerDiv32);

var closeButton = document.createElement("input");
closeButton.className = 'btn btn-default';
closeButton.setAttribute("data-dismiss", "modal");
closeButton.setAttribute("type", "button");
closeButton.setAttribute("value", "Close");
innerDiv32.appendChild(closeButton);

document.getElementsByTagName('body')[0].appendChild(div1); 

//因此,点击创建的按钮时,屏幕上会弹出模态框。

【讨论】:

【参考方案4】:

与接受的答案非常相似的主题,但编写为 jQuery 插件。我一直在寻找一些逻辑来构建我正在开发的工具包,但找不到任何东西,所以写了这个。

下面有很多代码,但它的设计目的是编写一次,然后就可以轻松调用,所以作为剧透,一旦你把它全部设置好,它就很容易使用:

$.fn.alert("utils.js makes this so easy!");

作为一个完整的工作示例:

https://jsfiddle.net/63zvqeff/

页面上不需要任何现有的&lt;div /&gt;,它适用于嵌套对话,它取自我正在处理的工具包,因此我已包含所有相关位,因此它是一个工作副本/粘贴示例。

(function ($)

    $.utils = 
        // http://***.com/a/8809472
        createUUID: function ()
        
            var d = new Date().getTime();
            if (window.performance && typeof window.performance.now === "function")
            
                d += performance.now(); //use high-precision timer if available
            
            var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c)
            
                var r = (d + Math.random() * 16) % 16 | 0;
                d = Math.floor(d / 16);
                return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
            );
            return uuid;
        
    

    $.fn.dialogue = function (options)
    
        var defaults = 
            title: "", content: $("<p />"),
            closeIcon: false, id: $.utils.createUUID(), open: function ()  , buttons: []
        ;
        var settings = $.extend(true, , defaults, options);

        // create the DOM structure
        var $modal = $("<div />").attr("id", settings.id).attr("role", "dialog").addClass("modal fade")
                        .append($("<div />").addClass("modal-dialog")
                            .append($("<div />").addClass("modal-content")
                                .append($("<div />").addClass("modal-header")
                                    .append($("<h4 />").addClass("modal-title").text(settings.title)))
                                .append($("<div />").addClass("modal-body")
                                    .append(settings.content))
                                .append($("<div />").addClass("modal-footer")
                                )
                            )
                        );
        $modal.shown = false;
        $modal.dismiss = function ()
        
            // loop until its shown
            // this is only because you can do $.fn.alert("utils.js makes this so easy!").dismiss(); in which case it will try to remove it before its finished rendering
            if (!$modal.shown)
            
                window.setTimeout(function ()
                
                    $modal.dismiss();
                , 50);
                return;
            

            // hide the dialogue
            $modal.modal("hide");
            // remove the blanking
            $modal.prev().remove();
            // remove the dialogue
            $modal.empty().remove();

            $("body").removeClass("modal-open");
        

        if (settings.closeIcon)
            $modal.find(".modal-header").prepend($("<button />").attr("type", "button").addClass("close").html("&times;").click(function ()  $modal.dismiss() ));

        // add the buttons
        var $footer = $modal.find(".modal-footer");
        for(var i=0; i < settings.buttons.length; i++)
        
            (function (btn)
            
                $footer.prepend($("<button />").addClass("btn btn-default")
                    .attr("id", btn.id)
                    .attr("type", "button")
                    .text(btn.text)
                    .click(function ()
                    
                        btn.click($modal)
                    ))
            )(settings.buttons[i]);
        

        settings.open($modal);

        $modal.on('shown.bs.modal', function (e) 
            $modal.shown = true;
        );
        // show the dialogue
        $modal.modal("show");

        return $modal;
    ;
)(jQuery);

然后,当您只需要基本的 alert() 时,我编写了一个辅助函数

(function ($)

    $.fn.alert = function (message)
    
        return $.fn.dialogue(
            title: "Alert", 
            content: $("<p />").text(message),
            closeIcon: true,
            buttons: [
                 text: "Close", id: $.utils.createUUID(), click: function ($modal)  $modal.dismiss();  
            ]
        );
    ;

)(jQuery);

否则,您需要将内容构建为 jQuery 对象,然后以如下对象的形式传入:


    title: "", // what ever you want in the title bar
    content: $("<p />"), // any DOM structure you can build as a jQuery object
    closeIcon: false, // does the dialogue have a X in the tilte bar to close it
    id: $.utils.createUUID(), // a reference id 
    open: function ()  , // a function called after the DOM structure is built but BEFORE rendering
    buttons: [ // an array of buttons to include in the footer
        // example "close" button, all buttons get a reference to $modal passed into them 
        // .dismiss() is a function attached to $modal to revert the DOM changes
         text: "Close", click: function ($modal)  $modal.dismiss();  
    ]
;

【讨论】:

谢谢。这仍然很有帮助。就像 Bootstrap4 的魅力一样,只需附加关闭按钮,而不是附加。 如何传递一个 HTML 文件? @jpcmf80 它不允许您直接传入 HTML 文件,但您可以使用 fetch(file.html).then(response =&gt; let $dialogueContent = JSON.parse(response.text()); ) 获取文件,然后将其传入 ie ` content: $dialogueContent ` @jpcmf80,我昨天的评论包含一个基本错误。代码示例应为:fetch(file.html).then(response =&gt; let $dialogueContent = $(response.text()); )【参考方案5】:

我也遇到了同样的问题,经过大量研究,我终于构建了一个js函数,可以根据我的要求动态创建模态。使用此功能,您可以在一行中创建弹出窗口,例如:

puyModal(title:'Test Title',heading:'Heading',message:'This is sample message.')

或者您可以使用其他复杂的功能,例如 iframe、视频弹出窗口等。

在https://github.com/aybhalala/puymodals 上找到它,如需演示,请转到http://pateladitya.com/puymodals/

【讨论】:

以上是关于动态构建 Twitter Bootstrap modal的主要内容,如果未能解决你的问题,请参考以下文章

Twitter bootstrap 跨越动态网站

Twitter BootStrap Confirmation 不适用于动态生成的元素

Twitter Bootstrap Popover 通过 ajax 动态生成内容

将信息动态加载到 Twitter Bootstrap 模式

Twitter Bootstrap 弹出框不适用于动态生成的内容

如何根据内容动态调整 Twitter Bootstrap 模式的大小