Select2在嵌入自举模式时不起作用

当我在引导模式中使用select2 (input)时,我不能输入任何东西。就像残疾?在modal之外select2工作正常。

enter image description here

工作示例:http://jsfiddle.net/byJy8/1/ 代码:< / p >

<!-- 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">Panel</h3>
</div>
<div class="modal-body" style="max-height: 800px">
<form class="form-horizontal">
<!-- Text input-->
<div class="control-group">
<label class="control-label" for="vdn_number">Numer</label>
<div class="controls">
<!-- seleect2 -->
<input name="vdn_number" type="hidden" id="vdn_number"  class="input-large" required=""  />
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
<button class="btn btn-primary">Save changes</button>
</div>
</div>
< h2 id = " js " > js < / h2 >
$("#vdn_number").select2({
placeholder: "00000",
minimumInputLength: 2,
ajax: {
url: "getAjaxData/",
dataType: 'json',
type: "POST",
data: function (term, page) {
return {
q: term, // search term
col: 'vdn'
};
},
results: function (data) { // parse the results into the format expected by Select2.
// since we are using custom formatting functions we do not need to alter remote JSON data
return {results: data};
}
}
});

答案:

在这里你可以找到一个快速的修复

这里是“正确的方式”:Select2在嵌入自举模式时不起作用

333430 次浏览

好的,我把它弄好了。

改变

<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">Panel</h3>
</div>
<div class="modal-body" style="max-height: 800px">

<div id="myModal" class="modal hide fade" 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">Panel</h3>
</div>
<div class="modal-body" style="max-height: 800px">

(从模态中移除tabindex =“1”;)

我在github上找到了select2的解决方案

https://github.com/ivaynberg/select2/issues/1436

对于bootstrap 3,解决方案是:

$.fn.modal.Constructor.prototype.enforceFocus = function() {};

Bootstrap 4将enforceFocus方法重命名为_enforceFocus,所以你需要修补它:

$.fn.modal.Constructor.prototype._enforceFocus = function() {};

从以上链接复制的解释:

Bootstrap向focusin事件注册了一个监听器,它检查被聚焦的元素是覆盖本身还是它的后代——如果不是,它只是重新聚焦在覆盖上。随着select2下拉框被附加到正文,这有效地防止你在文本框中输入任何东西。

您可以通过覆盖在模态上注册事件的enforceFocus函数来快速修复这个问题

更改select2.css文件

z-index: 9998;
...
z-index: 9999;
...
z-index: 10000;

z-index: 10000;
...
z-index: 10001;
...
z-index: 10002;

如果你使用jquery移动弹出窗口,你必须重写_handleDocumentFocusIn函数:

.
$.mobile.popup.prototype._handleDocumentFocusIn = function(e) {
if ($(e.target).closest('.select2-dropdown').length) return true;
}

.select2-close-mask{
z-index: 2099;
}
.select2-dropdown{
z-index: 3051;
}
这是我的解决方案与select2 4.0.0。只需要覆盖select2.css导入下面的css。 请确保z指数大于对话框或模态。我只是在默认值上加了2000。因为我的对话框的z-index大约是1000

对于Select2 v4:

使用dropdownParent将下拉框附加到模态对话框,而不是HTML主体。

<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="myModalLabel">Modal title</h4>
</div>
<div class="modal-body">
<select id="select2insidemodal" multiple="multiple">
<option value="AL">Alabama</option>
...
<option value="WY">Wyoming</option>
</select>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>




<script>


$(document).ready(function() {
$("#select2insidemodal").select2({
dropdownParent: $("#myModal")
});
});


</script>

这将附加Select2下拉框,因此它位于模态的DOM中,而不是HTML主体(默认)。看到https://select2.org/dropdown#dropdown-placement

为了更好地理解tabindex元素是如何工作的,完成公认的回答:

tabindex全局属性是一个整数,表示元素是否可以接受输入焦点(是可聚焦的),它是否应该参与顺序键盘导航,如果是,在什么位置。它可以取几个值:
-负值意味着元素应该是可聚焦的,但不应该通过顺序键盘导航到达;
-0表示元素应该是可聚焦的,并且可以通过顺序键盘导航到达,但是它的相对顺序是由平台约定定义的;
-一个正值意味着应该是可聚焦的,并且可以通过顺序键盘导航到达;它的相对顺序由属性的值定义:顺序遵循tabindex数量的增加。如果几个元素共享相同的tabindex,它们的相对顺序遵循它们在文档中的相对位置

from: Mozilla开发人员网络

只需删除tabindex="-1"并添加样式overflow:hidden

这里有一个例子:

<div id="myModal" class="modal fade" role="dialog" style="overflow:hidden;">
<!---content modal here -->
</div>

我在bootstrap modal中的select2有同样的问题,解决方案是删除overflow-y: auto;overflow: hidden;.modal-open.modal classes

下面是使用jQuery移除overflow-y的例子:

$('.modal').css('overflow-y','visible');
$('.modal').css('overflow','visible');

我以前遇到过这个问题,我用yii2解决了它

$.fn.modal.Constructor.prototype.enforceFocus = $.noop;

我也有同样的问题,为.select2-container更新z-index应该可以解决这个问题。确保你的模态z-index低于select2的。

.select2-container {
z-index: 99999;
}
< p >更新: 如果上面的代码不能正常工作,也从你的模式中删除表索引@breq建议

对于bootstrap3版本,只需在document ready上使用以下代码:

$(document).ready(function(){
$.fn.modal.Constructor.prototype.enforceFocus = function () {};
});

对我有用的答案在这里找到:https://github.com/select2/select2-bootstrap-theme/issues/41

$('select').select2({
dropdownParent: $('#my_amazing_modal')
});

Also不需要移除tabindex

$("#IlceId").select2({
allowClear: true,
multiple: false,
dropdownParent: $("#IlceId").parent(),
escapeMarkup: function (m) {
return m;
},
});

这段代码正在工作。谢谢你!

如果你在点击select2输入时遇到隐藏 引导模式iPad键盘问题,你可以通过添加以下规则来解决这个问题:

if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {
var styleEl = document.createElement('style'), styleSheet;
document.head.appendChild(styleEl);
styleSheet = styleEl.sheet;
styleSheet.insertRule(".modal { position:absolute; bottom:auto; }", 0);
document.body.scrollTop = 0; // Only for Safari
}

取自https://github.com/angular-ui/bootstrap/issues/1812#issuecomment-135119475

编辑:如果你的选项没有正确显示,你需要在初始化select2时使用dropdownParent属性:

$(".select2").select2({
dropdownParent: $("#YOURMODALID")
});

祝你好运

基于@pymarco的答案,我写了这个解决方案,它不是完美的,但解决了select2焦点问题,并保持制表符序列在模态内工作

    $.fn.modal.Constructor.prototype.enforceFocus = function () {
$(document)
.off('focusin.bs.modal') // guard against infinite focus loop
.on('focusin.bs.modal', $.proxy(function (e) {
if (this.$element[0] !== e.target && !this.$element.has(e.target).length && !$(e.target).closest('.select2-dropdown').length) {
this.$element.trigger('focus')
}
}, this))
}
好吧,我知道我迟到了。但让我和你们分享对我有效的方法。 tabindex和z-index解决方案不适合我

设置select元素的父元素是根据select2站点上列出的常见问题进行的。

我只是通过包含select2.min.css来让它工作

试一试

我的模态html bootstrap 3是

<div id="changeTransportUserRequestPopup" class="modal fade" role="dialog">
<div class="modal-dialog" style="width: 40%!important; ">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h3>Warning</h3>
</div>
<div class="modal-body" id="changeTransportUserRequestPopupBody">
<select id="cbTransport" class="js-example-basic-single" name="cbTransport" style="width:100%!important;"></select>
</div>
<div class="modal-footer">
<button id="noPost" class="btn btn-default" name="postConfirm" value="false" data-dismiss="modal">Cancel</button>
<button type="submit" id="yesChangeTransportPost" class="btn btn-success" name="yesChangeTransportPost" value="true" data-dismiss="modal">Yes</button>
</div>
</div>
</div>
</div>

我通常在我的项目中通过重载__abc0函数来解决这个问题。现在,它将检查是否没有dropdownParent,以及该函数是否在父元素类型为div.modal的元素上调用。如果是,它将添加该模态作为下拉列表的父类。

这样,就不必在每次创建select2-input框时都指定它。

(function(){
var oldSelect2 = jQuery.fn.select2;
jQuery.fn.select2 = function() {
const modalParent = jQuery(this).parents('div.modal').first();
if (arguments.length === 0 && modalParent.length > 0) {
arguments = [{dropdownParent: modalParent}];
} else if (arguments.length === 1
&& typeof arguments[0] === 'object'
&& typeof arguments[0].dropdownParent === 'undefined'
&& modalParent.length > 0) {
arguments[0].dropdownParent = modalParent;
}
return oldSelect2.apply(this,arguments);
};
// Copy all properties of the old function to the new
for (var key in oldSelect2) {
jQuery.fn.select2[key] = oldSelect2[key];
}
})();

这个问题解决了工作为我单一Jquery函数

$('#myModal .select2').each(function() {
var $p = $(this).parent();
$(this).select2({
dropdownParent: $p
});
});

我在一个应用程序中遇到了一个半相关的问题,所以我将输入我的2c。

我有多个形态的形式包含select2小部件。打开模态A,然后打开模态A中的另一个模态,将导致模态B中的select2小部件消失,无法初始化。

这些模式都是通过ajax加载表单的。

解决方案是在关闭模态时从dom中删除表单。

$(document).on('hidden.bs.modal', '.modal', function(e) {
// make sure we don't leave any select2 widgets around
$(this).find('.my-form').remove();
});

设置dropdownParent。我必须在modal中设置。modal-content,否则文本会居中。

$("#product_id").select2({
dropdownParent: $('#myModal .modal-content')
});
$('.modal').on('shown.bs.modal', function (e) {
$(this).find('.select2me').select2({
dropdownParent: $(this).find('.modal-content')
});
})

在我的情况下,我这样做,它工作。我使用bundle来加载它,在这种情况下,它为我工作

 $(document).on('select2:select', '#Id_Producto', function (evt) {
// Here your code...
});

根据官方的select2文档,这个问题的发生是因为Bootstrap模态倾向于从模态之外的其他元素窃取焦点。

默认情况下,Select2将下拉菜单附加到元素上,它被认为是“在模式之外”。

相反,使用dropdownParent设置将下拉菜单附加到模式本身:

$('#myModal').select2({
dropdownParent: $('#myModal')
});

参见参考:https://select2.org/troubleshooting/common-problems

在我的情况下,我有两个情态动词同样的问题,所有都解决了使用:

$('.select2').each(function() {
$(this).select2({ dropdownParent: $(this).parent()});
})

正如在项目问题# 41一个用户说。

你可以在$(文档)中再次调用select2 trigger

$(".select2").select2({
width: '120'
});

要使用bootstrap 4.0与服务器端(ajax或json数据内联),你需要添加所有这些:

$.fn.modal.Constructor.prototype._enforceFocus = function() {};

然后当modal打开时,创建select2:

  // when modal is open
$('.modal').on('shown.bs.modal', function () {
$('select').select2({
// ....
});
});

我也遇到过类似的问题,我用

    $('#CompId').select2({
dropdownParent: $('#AssetsModal')
});

还有modal with select

    <div class="modal fade" id="AssetsModal" role="dialog"
aria-labelledby="exampleModalCenterTitle"
aria-hidden="true"  style="overflow:hidden;" >
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLongTitle" >Добави активи</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<form role="form" action="?action=dma_act_documents_assets_insert&Id=<?=$ID?>"
method="post" name="dma_act_documents_assets_insert"
id="dma_act_documents_assets_insert">
<div class="form-group col-sm-12">
<label for="recipient-name" class="col-form-label">Актив:</label>
<span style="color: red">*</span>
<select class="form-control js-example-basic-single col-sm-12"
name="CompId" id="CompId">
<option></option>
</select>
</div>
</form>
</div>
</div>
</div>

但是我不知道为什么选择菜单比其他字段小 enter image description here < / p >

当开始使用select2时,它是这样开始的。当我取出它时,一切都好了。

有谁能分享一下这方面的经验吗?

谢谢。

如果你使用stisla并使用firemodal:

$('#modal-create-promo').click(()=>{
setTimeout(()=>{
$('#fire-modal-1').removeAttr('tabindex');
});
});


$("#modal-create-promo").fireModal({
...
});

这是我的工作

从模态中移除tabindex="-1"。我检查了这个解决方案,它是有效的。

裁判:https://github.com/select2/select2-bootstrap-theme/issues/41

这对所有人都有效

body .select2-container {
z-index: 9999 !important;
}

在页面上使用此代码

$(function () {
$(".select2").select2({
dropdownParent: $('#myModal')
});


$("#myModal").on('change', '#vdn_number', function () {
var term = $(this).val();
ajax: ({
url: "getAjaxData/",
dataType: 'json',
type: "POST",
data: function (term, page) {
return {
q: term, // search term
col: 'vdn'
};
},
results: function (data) { // parse the results into the format expected by Select2.
// since we are using custom formatting functions we do not need to alter remote JSON data
return { results: data };
}
});
});
});

我想这对你有帮助

你不应该像大部分答案中所建议的那样,将下拉框固定在模态上。 如果你的select2在模态的底部,你需要向下滚动来找到它,那么你就会有一个下拉的位置问题,因为你把它粘在模态上了

相反,您应该将下拉父目录设置为输入父目录。在你的例子中,它应该是这样的

$(document).ready(function() {
$("#vdn_number").select2({
dropdownParent: $("#vdn_number").parent()
});
});

像这样在引导模式中使用选择2 Bootstrap 5 Theme:

  1. 修复了select2 & bootstrap模态搜索输入的错误。
  2. 修复select2 & bootstrap模态选择选项后滚动错误

jQuery(function() {


$('.my-select2').each(function() {
$(this).select2({
theme: "bootstrap-5",
dropdownParent: $(this).parent(), // fix select2 search input focus bug
})
})


// fix select2 bootstrap modal scroll bug
$(document).on('select2:close', '.my-select2', function(e) {
var evt = "scroll.select2"
$(e.target).parents().off(evt)
$(window).off(evt)
})


})
<!DOCTYPE html>
<html>


<head>
<!-- Styles -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/select2-bootstrap-5-theme@1.2.0/dist/select2-bootstrap-5-theme.min.css" />


<!-- Scripts -->
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.0/dist/jquery.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>


</head>


<body>


<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">
Launch demo modal
</button>


<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
Select2 v4.1


<select class="my-select2">
<option>Test 1</option>
<option>Test 2</option>
<option>Test 3</option>
<option>Test 4</option>
<option>Test 5</option>
<option>Test 6</option>
<option>Test 7</option>
<option>Test 8</option>
<option>Test 9</option>
<option>Test 10</option>
</select>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
</body>


</html>