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


338

ブートストラップモーダルで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 2017

dboswellの答えは正しい解決策ですが、dropdownParentルートdivにあるべきではありませんが、たとえばdivとclassを深くする必要がありますmodal-content。そうしないと、モーダルをスクロールするときにドロップダウンの位置がめちゃくちゃになります。
Shahin Dohan

回答:


606

わかりました。

変化する

<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
ありがとう!それは4年になります、そしてそれはまだ有効な修正です。
Linek 2017

248

Select2 v4の場合:

dropdownParentHTMLボディではなく、モーダルダイアログにドロップダウンを添付するために使用します。

<!-- 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を参照してください


12
確認されました、これは魅力のように機能しており、この問題の最善の解決策のようです!
lacco

29
これは(v4.0.2で)機能しましたが、を使用する必要dropdownParent: $("#myModal")がありましたdropdownParent: "#myModal"
Saxon Druce

6
FWIW、私の場合、私はdropdownParentをモーダルの本体に設定する必要があり、それをモーダル自体にアタッチしても、zインデックスが十分に高くなりませんでした。例:dropdownParent:$( '。modal-body'、 '#myModal')
DrewInTheMountains

1
これはtabindexを削除せずに完全に正常に動作します。+1
sammry

1
@DrewInTheMountains dropdownParentモーダルのルートにを設定する際にも問題がありました。実際にボディを選択する方が良いです。そうしないと、スクロール時に位置が非常に悪くなります。私はクラスmodal-contentでdivに私のを設定し、それは魅力のように動作します!
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() {};

上のリンクからコピーされた説明:

ブートストラップは、フォーカスされた要素がオーバーレイ自体であるか、その子孫であるかを確認するfocusinイベントにリスナーを登録します。そうでない場合は、オーバーレイに再度フォーカスします。本文にselect2ドロップダウンがアタッチされているため、これにより、テキストフィールドに何も入力できなくなります。

これをすばやく修正するには、モーダルにイベントを登録するenforceFocus関数を上書きします


1
@pymarcoその答えとして選ばれるには、少し前にそこにいるべきでした!本当に迷惑な問題に本当の答えを提供してくれてありがとう。
ilter

3
@pymarcoこれは正しい解決策です。時間を節約していただきありがとうございます。
VKPRO 2015年

2
いつも頭を悩ませるわけではなかった問題で、私は時間を大幅に節約できました。ありがとうございました!
user3036342

1
これは私のために働いた!! 私はgithubのselect2の課題スレッドを閲覧していて、あなたが提供した投稿に出くわしませんでした。私の人生を救ったのは、グーグルでこのページをstackoverflowで見つけることでした。ありがとうございました!
luis.ap.uyen

2
このコードはどこに配置し、どの機能に対処する必要がありますか?申し訳ありませんが、ここではJS noobです。これをselect2 JSの一部にするか、ページの上部または末尾に配置しようとしましたが、すべて成功しませんでした。$.fn.modal.Constructor.prototype.enforceFocus = $.noop;
Armitage2k 2016年

39

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

次に例を示します。

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

動作しますが、モーダルが長いと下にスクロールできません!
Tarek Kalaji 2018年

1
@TarekKalajiこのソリューションでスクロールを許可する方法を理解したことがありますか?
オーバーフロー

tabindexを削除しようとしましたが、十分ではありませんでした。オーバーフローの追加:モーダルボックスが長い場合、非表示は便利です...
Plasebo

タブインデックス属性を削除するために私のために働いた。
Glen

参考までに:tab-index attrを削除すると、escボタンでモーダルポップアップを閉じる機能が削除されます。
curiousBoy 2018

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

これはselect2 4.0.0での私のソリューションです。select2.cssインポートのすぐ下のcssをオーバーライドするだけです。Z-indexがダイアログまたはモーダルより大きいことを確認してください。デフォルトのものに2000を追加するだけです。ダイアログのZインデックスが約1000であるためです。


1
これを除いて、select2 4.0.0で機能するソリューションはありませんでした。どうもありがとう。
Neel、2015年

Select2(v4.0.0)がポップオーバーにある場合も同じ問題が発生します。中bootstrap.cssのz屈折率.popoverこの修正は、同様に動作するので、1060に設定されています。シンプルで、問題が作成されたのと同じ方法でスタイルシートにz-indexを設定するため、問題が解決します。
Paul

2
最も些細なことですが、機能した唯一のソリューションです。ありがとう!
Ishtiaque Khan、2015

上記をcssファイルに追加しましたが、変更はありません。私はjQuery Mobileを使用しています。何か提案してください?
Sahil Khanna 2016

@Sahil 1.元のファイルが正常に上書きされることを確認してください。簡単な方法は、それがダイアログのより大きいです確保、Zインデックスfiles2.checkすべてのデフォルトCSSの後にこれを追加することです
Diluka W

26

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

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

2
.modal-content本当に違いを生みます。ご指摘いただきありがとうございます
Js Lim

これでうまくいきました。なぜこれが多くの賛成票を得られなかったのかしら。
chrisbjr

また私のために働いた
ネハ


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が提案したように、モーダルからtabindexesも削除します


1
これを機能させるには、@ breq回答でこれを実装する必要があります。
Ryan Arief 2017年

7

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

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

1
適切な関数名は "$(document).ready"です。したがって、コードは次のようになります。$(document).ready(function(){$ .fn.modal.Constructor.prototype.enforceFocus = function(){};});
LechOsiński2017年

1
@LechOsiński-このコードの小さなチャンクの使用方法を実際に説明していただきありがとうございます。あなたの解決策は私のために働いた唯一のものです。+1
Francis Bartkowiak 2018年

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ダイアログを重ねて表示し、2番目にselect2を表示しています。また、jQuery UIダイアログにselect2、日付と時刻ピッカーの// allowインタラクションを配置しました$ .ui.dialog.prototype._allowInteraction = function(e){return !! $(e.target).closest( '。ui-ダイアログ、.ui-datepicker、.select2-drop ')。length; }; これが役立つかどうかはわかりません。
Adrian P.

5

受け入れられた回答を完了するためにtabindex要素がどのように機能するかをよりよく理解するために:

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

から:Mozilla Devlopper Network


3

あなたはに問題がある場合のiPadのキーボード隠しブートストラップモーダルをクリックしながら、SELECT2の入力を、次のルールを追加することでこの問題を解決することができた後の初期化を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

私の場合、2つのモーダルで同じ問題が発生し、すべてを使用して解決しました:

$('.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ソリューションは私にとってはうまくいきませんでした。

select要素の親の設定は、select2サイトにリストされている一般的な問題に従って機能しました。


1

jqueryモバイルポップアップを使用する場合は、_handleDocumentFocusIn関数を書き換える必要があります。

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


私はjQuery Mobileを使用しており、ポップアップにSelect2を埋め込みました。あなたが提供したコードはPCブラウザ上でうまく動作します。しかし、このコードをモバイルブラウザーで実行すると、値が選択されるとポップアップが閉じて再び開きます。私に必要な変更を提案できますか?
Sahil Khanna 2016

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

ブートストラップ4.0をサーバー側(ajaxまたはjsonデータインライン)で使用するには、次のすべてを追加する必要があります。

$.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...
  });
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.