web-dev-qa-db-ja.com

ブートストラップモーダルに埋め込むとSelect2が機能しない

ブートストラップモーダルでselect2(input)を使用すると、入力ができません。それは無効のようですか?彼の外でモーダルselect2はうまく機能します。

enter image description here

作業例: http://jsfiddle.net/byJy8/1/ / code:

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

adn 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};
        }
    }
});

答え:

ここであなたは素早い fix を見つけることができます

そしてここが '正しい方法'です: ブートストラップモーダルに埋め込まれたときSelect2は動作しません

292
breq

さて、私はそれがうまくいくようにしました。

変化する

<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" をモーダルから削除)

529
breq

Select2 v4の場合:

HTMLの本体ではなく、dropdownParentを使用してドロップダウンをモーダルダイアログに添付します。

<!-- 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ドロップダウンがアタッチされ、HTML本体(デフォルト)ではなくモーダルのDOM内に収まります。 https://select2.org/dropdown#dropdown-placement を参照してください。

213
dboswell

私はselect2のgithubでこれに対する解決策を見つけました

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ドロップダウンが本文に添付されているので、テキストフィールドに何も入力しなくて済みます。

モーダルにイベントを登録するenforceFocus関数を上書きすることでこれを簡単に解決できます。

173
pymarco

tabindex="-1"を削除してスタイルoverflow:hiddenを追加するだけです。

これが一例です。

<div id="myModal" class="modal fade" role="dialog" style="overflow:hidden;">
    <!---content modal here -->
</div>
31
MrBii
.select2-close-mask{
    z-index: 2099;
}
.select2-dropdown{
    z-index: 3051;
}

これはselect2 4.0.0での私の解決策です。 select2.cssインポートのすぐ下のcssをオーバーライドするだけです。 z-indexがあなたのダイアログまたはモーダルより大きいことを確認してください。デフォルトのものに2000を追加しただけです。原因私のダイアログのz-indexは約1000です。

24
Diluka W

DropdownParentを設定します。モーダル内の.modal-contentに設定する必要があります。そうしないと、テキストは中央に配置されることになります。

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

ここで見つけた私のために働いた答え: https://github.com/select2/select2-bootstrap-theme/issues/41

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

tabindexを削除する必要もありません。

7
Ashraf Slamang

私は同じ問題を抱えていました。z-index.select2-containerに更新するとうまくいくはずです。あなたのモーダルのz-indexがselect2のものより低いことを確認してください。

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

更新:上記のコードが正しく動作しない場合は、@ breqが示唆しているようにモーダルからtabindexesも削除してください。

7
hhk

JusはDocument.read()でこのコードを使います

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

Tabindex要素がどのようにして受け入れられた答えを完成させるかをよりよく理解するために:

Tabindexグローバル属性は、要素が入力フォーカスを取得できるか(フォーカス可能か)、シーケンシャルキーボードナビゲーションに参加する必要があるのか​​、そしてそうであれば、どの位置にあるのかを示す整数です。いくつかの値をとることができます。
- 負の値は、要素がフォーカス可能であるべきだがシーケンシャルキーボードナビゲーションで到達可能であるべきではないことを意味します。
-0は、要素がフォーカス可能でシーケンシャルキーボードナビゲーションで到達可能でなければならないことを意味しますが、その相対的な順序はプラットフォームの規約によって定義されます。
- 正の値は、フォーカス可能で、順次キーボードナビゲーションで到達可能であることを意味します。その相対的な順序は属性の値によって定義されます。シーケンシャルはtabindexの増加する数に従います。複数の要素が同じtabindexを共有している場合、それらの相対順序はドキュメント内の相対位置に従います。

から: Mozilla Devlopperネットワーク

5
538ROMEO

この問題は私のために働いていた

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

select2.css fileを変更します。

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

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

私がこの解決策を書いた@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
Angelo Cavalet
$("#IlceId").select2({
    allowClear: true,
    multiple: false,
    dropdownParent: $("#IlceId").parent(),
    escapeMarkup: function (m) {
        return m;
    },
});

このコードは機能しています。ありがとうございました。

2
ramazan polat

iPadキーボードに問題がある場合hideブートストラップモーダルselect2入力をクリックすると、次のルールafterselect2入力の初期化:

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 から取得

EDIT:オプションが適切に表示されない場合は、select2を初期化するときにdropdownParent属性を使用する必要があります。

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

がんばろう (:

2
Gangai Johann

公式のselect2ドキュメントによれば、この問題はブートストラップモーダルがモーダルの外側の他の要素からフォーカスを盗む傾向があるために起こります。

デフォルトでは、Select2はドロップダウンメニューを要素に添付し、それは「モーダルの外側」と見なされます。

代わりに、dropdownParent設定を使用してドロップダウンをモーダル自体に添付します。

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

参照先を参照してください。 https://select2.org/troubleshooting/common-problems

2
Anas

さて、私はパーティーに遅れていることを知っています。しかし、私のために働いたことをあなたと共有させてください。 tabindexとz-indexの解決策は私にとってはうまくいきませんでした。

Select要素の親を設定することは、select2サイトにリストされている 一般的な問題 に従って動作しました。

2
joker

私はselect2bootstrap modalについても同じ問題を抱えています、そして解決策はoverflow-y: auto;overflow: hiddenを削除することでした。 .modal-open.modal classesから

これはjQueryを使用してoverflow-yを削除する例です。

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

私は前にこの問題を抱えていた、私はyii2を使用していると私はこのようにそれを解決しました

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

私は自分のプロジェクトでselect2-関数をオーバーロードすることでこれを解決しました。これで、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);
    };
})();
1
Zombaya

あなたがjqueryモバイルポップアップを使うなら、あなたは_handleDocumentFocusIn関数を書き直さなければなりません:

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

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
Developer
$('.modal').on('shown.bs.modal', function (e) {
    $(this).find('.select2me').select2({
        dropdownParent: $(this).find('.modal-content')
    });
})
0
ocobacho

私は私の2cに入れていきますので、アプリケーションに半関連の問題がありました。

私はselect2ウィジェットを含むフォームを持つ複数のモーダルを持っています。モーダルAを開き、次にモーダルA内の別のモーダルを開くと、モーダルB内のselect2ウィジェットが消え、初期化に失敗します。

これらの各モーダルはajaxを介してフォームをロードしていました。

解決策は、モーダルを閉じるときにドームからフォームを削除することでした。

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