嵌入到引导模态中时,Select2不起作用


337

当我在引导模式下使用select2(输入)时,无法在其中输入任何内容。就像残疾吗?在模态外部select2可以正常工作。

在此处输入图片说明

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

<!-- 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>

  </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>

和js:

$("#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不起作用


1
也就是说,从元素中删除属性tabindex =“-1”
Nikit Barochiya

dboswell的答案是正确的解决方案,但是,该选项dropdownParent不应位于根div上,而应位于更深的位置,例如具有class的div modal-content,否则在滚动模态时下拉位置会变得混乱。
Shahin Dohan

Answers:


605

好的,我已经开始工作了。

更改

<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”


22
可能还有其他解决方案吗?因为模态窗口不会被Esc键关闭。
woto

19
删除tabindex =“-1”对我不起作用。我刚刚将<div class =“ modal-body”>更改为<div class =“ modal-body” style =“ overflow:hidden;”>
Wissem 2013年

39
你怎么发现的?
DontVoteMeDown 2014年

6
我已经尝试了所有选项,但对我没有任何帮助。我正在使用select2 4.0
Girish Gupta

7
谢谢!已经四年了,仍然是有效的解决方案。
Linek '17

247

对于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


12
确认,这正在起作用,似乎是解决此问题的最佳方法!
lacco

29
这对我有效(使用v4.0.2),但是我不得不使用dropdownParent: $("#myModal"),而不是dropdownParent: "#myModal"
Saxon Druce

6
FWIW,在我的情况下,我需要将dropdownParent设置为模态的主体,将其附加到模态本身并不能使z索引足够高。例如dropdownParent:$('。modal-body','#myModal')
DrewInTheMountains

1
这在不删除tabindex的情况下工作得很好。+1
惊ry

1
@DrewInTheMountains我也遇到了将设置为dropdownParent模态根的问题,选择主体确实更好,否则滚动时会遇到非常糟糕的定位错误。我在课堂上将我的课程设置为div,modal-content它的工作原理就像是一种魅力!
Shahin Dohan

193

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

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

对于引导程序3,解决方案是:

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

Bootstrap 4将enforceFocus方法重命名为_enforceFocus,因此您需要对其进行修补:

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

从上面的链接复制的说明:

Bootstrap将一个侦听器注册到focusin事件,该事件将检查聚焦的元素是叠加层本身还是它的后代-如果不是,则仅将其重新聚焦在叠加层上。通过将select2下拉列表附加到正文,这可以有效地防止您在文本字段中输入任何内容。

您可以通过覆盖在模式上注册事件的executeFocus函数来快速解决此问题


1
@pymarco应该早一点到那里来作为答案!谢谢男人,为真正令人烦恼的问题提供了真正的答案。
ilter 2013年

3
@pymarco这是正确的解决方案。谢谢您节省我的时间。
VKPRO

2
您为我节省了很多时间,而这个问题并不总是引起人们的关注。谢谢!
user3036342

1
这对我有用!我浏览并浏览了github中select2的问题线程,但没有遇到您提供的那篇文章。谷歌搜索并在stackoverflow中找到此页面可以拯救我的生命。谢谢!
luis.ap.uyen

2
该代码放在哪里,应该处理什么功能?抱歉,这里的JS菜鸟,我尝试将其作为select2 JS的一部分或将其放置在页面的顶部/结尾,但都没有成功。$.fn.modal.Constructor.prototype.enforceFocus = $.noop;
2016年

39

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

这是一个例子:

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

它有效,但是当我有很长的模态时,我不能向下滚动!
塔雷克·卡拉吉

1
@TarekKalaji您是否曾经想过如何使用此解决方案进行滚动?
OverflowingTheGlass'Mar

试图删除tabindex但还不够。添加溢出:如果模态框很长,则隐藏起来很有用...
Plasebo

为我工作,删除标签索引属性。
格伦(Glen

仅供参考:删除tab-index attr将删除通过esc按钮关闭模式弹出窗口的功能。
curiousBoy

31
.select2-close-mask{
    z-index: 2099;
}
.select2-dropdown{
    z-index: 3051;
}

这是我的select2 4.0.0解决方案。只需覆盖select2.css导入下方的CSS。请确保z-index大于对话框或模态。我只是在默认值上加上2000。因为我的对话框的z-index大约为1000。


1
除此之外,所有解决方案都不适用于select2 4.0.0。非常感谢。
Neel 2015年

如果Select2(v4.0.0)位于弹出窗口中,则会发生相同的问题。在bootstrap.css的z-index中.popover设置为1060,因此此修复程序也适用。我喜欢它,因为它很简单,并且可以用创建问题的方式解决问题:在样式表中设置z-index。
Paul

2
最琐碎但唯一可行的解​​决方案。谢谢!
伊什蒂克·汗

我已经在css文件中添加了以上内容,但没有任何更改。我正在使用jQuery Mobile。有什么建议吗?
Sahil Khanna

@Sahil 1.确保已成功覆盖原始文件。简单的方法是在所有默认的css files2.check之后添加此值,请确保z-index大于对话框的
Diluka W 16/02/22

26

设置dropdownParent。我必须将其设置为模态内的.modal-content,否则文本将最终居中。

$("#product_id").select2({
    dropdownParent: $('#myModal .modal-content')
});

2
.modal-content真正有所作为。感谢您指出👍
的js林

这对我有用。我不知道为什么没有这么多的支持。
chrisbjr

为我工作也谢谢
Neha


9

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

默认情况下,Select2将下拉菜单附加到元素,并且将其视为“模态之外”。

而是使用dropdownParent设置将下拉列表附加到模式本身:

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

请参阅参考资料:https : //select2.org/troubleshooting/common-problems


好。在添加dropdownParent选项后,它无法正常工作,现在还不能正常工作。
Yogesh Saroya

8

我有同样的问题,更新z-index.select2-container应该做的伎俩。确保您的模态z-index低于select2的模态。

.select2-container {
    z-index: 99999;
}

更新:如果上述代码无法正常工作,请按照@breq的建议从模态中删除tabindexs


1
您需要使用@breq答案来实现它,以使其正常工作。
Ryan Arief

7

Jus在Document.read()上使用此代码

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

1
正确的函数名称为“ $(document).ready”。因此代码应类似于:$(document).ready(function(){$ .fn.modal.Constructor.prototype.enforceFocus = function(){};});
LechOsiński17年

1
@LechOsiński-感谢您实际描述了如何使用这一小段代码。您的解决方案是唯一对我有用的解决方案。+1
Francis Bartkowiak

7

此问题适合我的单个Jquery函数

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

谢谢!这解决了我的问题
Mihai Alexandru-Ionut

5

更改select2.css文件

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

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

那是我唯一的作品(jquery-ui-1.10.3.css,jquery-ui-1.9.1.js和select2 3.4.0)。我有2个jquery UI对话框,一个在另一个之上,select2在第二个之上。我还把//允许SELECT2,日期和时间选择器的交互作用放在jQuery UI对话框$ .ui.dialog.prototype._allowInteraction = function(e){return !! $(e.target).closest('。ui-对话框,.ui-datepicker,.select2-drop')。length; }; 我不知道是否有帮助。
Adrian P.

5

只是为了更好地了解tabindex元素如何完成已接受的答案:

tabindex全局属性是一个整数,指示元素是否可以获取输入焦点(可聚焦),是否应参与顺序键盘导航,如果可以,则在什么位置。它可以采用多个值:
  -负值表示该元素应该是可聚焦的,但不应通过顺序键盘导航来访问;
  -0表示该元素应该是可聚焦的,并且可以通过顺序键盘导航来访问,但是其相对顺序由平台约定定义;
  -正值表示应该通过顺序的键盘导航集中并可以到达;它的相对顺序由属性的值定义:依次跟随tabindex的数量递增。如果多个元素共享相同的tabindex,则它们的相对顺序将遵循它们在文档中的相对位置。

来自:Mozilla Devlopper网络


3

如果您对隐藏iPad键盘有疑问引导模式,而在点击选择2输入,您可以通过添加以下规则解决此之后的初始化select2输入:

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

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

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

祝好运 (:


3

基于我写的这个解决方案@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))
    }

3

在我的情况下,我在两个模态中遇到了相同的问题,并且使用以下方法解决了所有问题:

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

就像项目第41期中那样,一位用户说。


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

该代码有效。谢谢。


2

好吧,我知道我迟到了。但是,让我与您分享对我有用的东西。tabindex和z-index解决方案对我不起作用。

根据select2网站上列出的常见问题,设置select元素的父元素。


1

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

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


我正在使用jQuery Mobile,并在弹出窗口中嵌入了Select2。您提供的代码在PC浏览器上效果很好。但是,当我在移动浏览器上运行此代码时,选择任何值时,弹出窗口都会关闭并重新打开。您能建议我需要进行的任何更改吗?
Sahil Khanna

1

我对select2in 有同样的问题,bootstrap modal解决方案是删除overflow-y: auto;and overflow: hidden; 来自.modal-open.modal classes

这是jQuery用于删除的示例overflow-y

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

1

我之前有这个问题,我正在使用yii2,并且以这种方式解决了

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

1

我在应用程序中遇到一个半相关的问题,所以我将其放在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();
});

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

1

我通常在我的项目中通过重载select2-function 来解决此问题。现在,它将检查是否没有dropdownParent,以及是否在具有类型父元素的元素上调用该函数div.modal。如果是这样,它将添加该模式作为下拉菜单的父模式。

这样,您不必每次创建select2-input-box时都指定它。

(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];
    }
})();

0

我只是通过包括select2.min.css使其工作

试试看

我的引导3的模态HTML是

<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>


0

要在服务器端(ajax或json数据内联)上使用bootstrap 4.0,您需要添加以下所有内容:

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

然后当模式打开时,创建select2:

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

-1

就我而言,我做到了,而且行得通。我使用捆绑软件加载它,在这种情况下,它对我有用

 $(document).on('select2:select', '#Id_Producto', function (evt) {
   // Here your code...
  });
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.