我正在使用Twitter Bootstrap模式,使用默认选项,您可以单击背景或按[Esc]关闭模式。
然而,当我在模态中启动ajax操作时,我想禁用模态以任何方式关闭。所以我禁用按钮并隐藏模态的关闭按钮,但我无法弄清楚如何禁用背景和[Esc]键。
我试过了:
$('#myModal').modal({
backdrop: 'static',
keyboard: false
});
但这似乎没有动态。
一旦ajax操作完成,我还需要重新启用背景和键盘。
答案 0 :(得分:17)
注意:此解决方案的目标是twitter bootstrap 2.x!有关根据bootstrap 3的差异,请参阅this answer(仅在下方)。
扩展引导模式功能,无需修改原始源。
感谢@David和他在How to Extend Twitter Bootstrap Plugin的建议,我终于得到了它的工作。这是他的解决方案的略微修改版本,添加了模态“锁定”。我发布它作为一个额外的答案,因为我认为这可能是其他像我一样努力解决这个问题的人的起点。
// save the original function object
var _superModal = $.fn.modal;
// add locked as a new option
$.extend( _superModal.defaults, {
locked: false
});
// create a new constructor
var Modal = function(element, options) {
_superModal.Constructor.apply( this, arguments )
}
// extend prototype and add a super function
Modal.prototype = $.extend({}, _superModal.Constructor.prototype, {
constructor: Modal
, _super: function() {
var args = $.makeArray(arguments)
// call bootstrap core
_superModal.Constructor.prototype[args.shift()].apply(this, args)
}
, lock : function() {
this.options.locked = true
}
, unlock : function() {
this.options.locked = false
}
, hide: function() {
if (this.options.locked) return
this._super('hide')
}
});
// override the old initialization with the new constructor
$.fn.modal = $.extend(function(option) {
var args = $.makeArray(arguments),
option = args.shift()
// this is executed everytime element.modal() is called
return this.each(function() {
var $this = $(this)
var data = $this.data('modal'),
options = $.extend({}, _superModal.defaults, $this.data(), typeof option == 'object' && option)
if (!data) {
$this.data('modal', (data = new Modal(this, options)))
}
if (typeof option == 'string') {
data[option].apply( data, args )
}
});
}, $.fn.modal);
使用这种技术,改变bootstrap.js不应该是不必要的,并且可以更容易地在引导项目之间共享相同的功能。此方法应适用于所有其他引导程序插件。到目前为止只用按钮试过,但我不知道为什么它不应该。
看工作小提琴 - >的 http://jsfiddle.net/Sz7ZS/ 强>
答案 1 :(得分:10)
有一种更简单的方法。 This bootstrap pull请求解释了一点。该解决方案禁用关闭模式的所有方法(键盘,鼠标单击,关闭按钮)。
要禁用关闭模式,您只需:
$('#myModal').data('bs.modal').isShown = false;
要再次启用关闭:
$('#myModal').data('bs.modal').isShown = true;
示例强>
以下是一些与jQuery get一起使用的示例代码:
// disable closing the modal
$('#myModal').data('bs.modal').isShown = false;
// Send an HTTP GET request to the server - replace this with getJSON, post or ajax as needed
$.get( "ajax/test.html", function( data ) {
// enable closing the modal
$('#myModal').data('bs.modal').isShown = true;
// Do something with the data
$( ".result" ).html( data );
});
答案 2 :(得分:9)
您不是唯一缺少该功能的人。我认为bootstrap有时太“简约”了,后面的人有很多想法应该在“实现层”中完成,但是当引导jQuery插件本身使它变得不可能时它是没有用的!
您必须自己实施这项功能,例如:
bootstrap.js
v2.1.1模式中的从第61行开始。
在Modal.prototype
中添加两个函数,lock
和unlock
,所以它看起来像这样(我在这里只显示modal.prototype
的开头,因为它太多了代码)
Modal.prototype = {
constructor: Modal
//add this function
, lock: function () {
this.options.locked = true
}
//add this function
, unlock: function () {
this.options.locked = false
}
, toggle: function () {
...
...
然后,同样在Modal.prototype中,找到函数hide
,并添加一行,使其看起来像这样(再次,只显示隐藏的顶部)
, hide: function (e) {
e && e.preventDefault()
var that = this
//add this line
if (that.options.locked) return
e = $.Event('hide')
...
...
最后,将$.fn.modal.defaults
改为:
$.fn.modal.defaults = {
backdrop: true
, keyboard: true
, show: true
, locked: false //this line is added
}
现在,您在自举模式中具有即时锁定/解锁功能,可防止用户在关键时刻关闭模态。
示例:
这是http://twitter.github.com/bootstrap/javascript.html#modals
的“现场演示”的修改版本<!-- Button to trigger modal -->
<a href="#myModal" role="button" class="btn" data-toggle="modal">Launch demo modal</a>
<!-- Modal -->
<div id="myModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="myModalLabel">Modal header</h3>
</div>
<div class="modal-body">
<p>One fine body…</p>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
<button class="btn btn-primary" onclick="$('#myModal').modal('lock');">lock</button>
<button class="btn btn-primary" onclick="$('#myModal').modal('unlock');">unLock</button>
</div>
</div>
<script type="text/javascript">
我已插入两个按钮,“锁定”和“解锁” - 点击后,他们将模态设置为锁定或正常模式(初始化设置)
编辑,在你的情况下,你只需要在执行ajax时调用lock / onlock:
$("myModal").modal('lock');
$.ajax({
url: url,
...
...
, success(html) {
...
...
$("#myModal").modal('unlock');
}
});
答案 3 :(得分:8)
你可以创建一个变量isBlocked,你可以在AJAX调用为true时设置,然后你可以用这种方式在bootsrap模态隐藏事件上检查它:
$('#myModal').on('hide.bs.modal', function (e) {
//Prevent modal from closing is isBlocked is true
if(isBlocked) return e.preventDefault();
})
我认为这种方式比扩展Bootsrap更容易,希望它可以帮助某人:D
答案 4 :(得分:6)
感谢@davidkonrad对此的工作。我也试图实现这一点,似乎事情已经改变了bootstrap 3.现在而不是:
_superModal.defaults
它现在已附加到构造函数,因此您必须执行
_superModal.Constructor.DEFAULTS
此外,构造函数已更改,这意味着我必须复制它并修改它不太理想。相反,我提出了以下代码,它可以工作,不会复制构造函数,如果引导程序发生变化,应该更加万无一失。去吧:
// save the original function object
var _superModal = $.fn.modal;
// add locked as a new option
$.extend( _superModal.Constructor.DEFAULTS, {
locked: false
});
// capture the original hide
var _hide = _superModal.Constructor.prototype.hide;
// console.log('HIDE:', _hide);
// add the lock, unlock and override the hide of modal
$.extend(_superModal.Constructor.prototype, {
// locks the dialog so that it cannot be hidden
lock: function() {
// console.log('lock called');
// console.log('OPTIONS',this.options);
this.options.locked = true;
}
// unlocks the dialog so that it can be hidden by 'esc' or clicking on the backdrop (if not static)
,unlock: function() {
// console.log('unlock called');
this.options.locked = false;
}
// override the original hide so that the original is only called if the modal is unlocked
,hide: function() {
// console.log('hide called');
if (this.options.locked) return;
_hide.apply(this, arguments);
}
});
所以为了锁定模态:
$('#dlg').modal('lock');
并解锁:
$('#dlg').modal('unlock');
耶!
答案 5 :(得分:0)
我更新了这个很棒的脚本以与Bootstrap 4和Bootstrap 3一起使用。 我保留这两种情况,因为我在项目中使用了一个全局脚本,其中一些脚本同时使用了两个版本的Boostrap(不用担心,每个项目一个引导程序)。如果有人有更好的主意,请与我们分享。
// save the original function object
var _superModal = $.fn.modal;
// Bootstrap 3: Constructor.DEFAULTS
// Bootstrap 4: Constructor.Default
var _superModalDefault = (typeof _superModal.Constructor.DEFAULTS === 'undefined') ? _superModal.Constructor.Default : _superModal.Constructor.DEFAULTS;
// add locked as a new option
$.extend(_superModalDefault, {
locked: false
});
// capture the original hide
var _hide = _superModal.Constructor.prototype.hide;
// console.log('HIDE:', _hide);
// add the lock, unlock and override the hide of modal
$.extend(_superModal.Constructor.prototype, {
// locks the dialog so that it cannot be hidden
// Bootstrap 3: this.options
// Bootstrap 4: this._config
lock: function() {
// console.log('lock called');
if (this.options)
this.options.locked = true; // Bootstrap 3
else
this._config.locked = true; // Bootstrap 4
}
// unlocks the dialog so that it can be hidden by 'esc' or clicking on the backdrop (if not static)
,unlock: function() {
// console.log('unlock called');
if (this.options)
this.options.locked = false; // Bootstrap 3
else
this._config.locked = false; // Bootstrap 4
}
// override the original hide so that the original is only called if the modal is unlocked
,hide: function() {
// console.log('hide called');
if (this.options)
if (this.options.locked) return; // Bootstrap 3
else
if (this._config.locked) return; // Bootstrap 4
_hide.apply(this, arguments);
}
});