动态构建 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/
页面上不需要任何现有的<div />
,它适用于嵌套对话,它取自我正在处理的工具包,因此我已包含所有相关位,因此它是一个工作副本/粘贴示例。
(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("×").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 => let $dialogueContent = JSON.parse(response.text()); )
获取文件,然后将其传入 ie ` content: $dialogueContent `
@jpcmf80,我昨天的评论包含一个基本错误。代码示例应为:fetch(file.html).then(response => 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 Confirmation 不适用于动态生成的元素
Twitter Bootstrap Popover 通过 ajax 动态生成内容