Select2 tidak berfungsi ketika disematkan dalam modal bootstrap

338

Ketika saya menggunakan select2 (input) dalam modal bootstrap, saya tidak bisa mengetikkan apa pun ke dalamnya. Ini seperti dinonaktifkan? Di luar modal, select2 berfungsi dengan baik.

masukkan deskripsi gambar di sini

Contoh kerja: http://jsfiddle.net/byJy8/1/ kode:

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

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

jawaban:

di sini Anda dapat menemukan perbaikan cepat

dan di sini adalah 'jalan yang benar': Select2 tidak berfungsi ketika tertanam dalam modal bootstrap

breq
sumber
1
Yaitu, menghapus atribut tabindex = "- 1" dari elemen.
Nikit Barochiya
Jawaban dboswell adalah solusi yang tepat, TETAPI, dropdownParentseharusnya tidak berada di root div, tetapi lebih dalam, misalnya div dengan kelas modal-content, jika tidak posisi dropdown akan kacau ketika menggulir modal.
Shahin Dohan

Jawaban:

606

Ok, saya harus bekerja.

perubahan

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

untuk

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

(hapus tabindex = "- 1" dari modal)

breq
sumber
22
Mungkin ada solusi lain? Karena modal window tidak akan ditutup oleh tombol Esc.
woto
19
menghapus tabindex = "- 1" tidak berfungsi dari saya. Saya baru saja mengubah <div class = "modal-body"> menjadi <div class = "modal-body" style = "overflow: hidden;">
Wissem
39
Bagaimana kamu menemukan itu?
DontVoteMeDown
6
Saya sudah mencoba semua opsi, tetapi tidak ada yang berhasil untuk saya. Saya menggunakan select2 4.0
Girish Gupta
7
Terima kasih! Sudah 4 tahun dan itu masih merupakan perbaikan yang valid.
Linek
248

Untuk Select2 v4:

Gunakan dropdownParentuntuk melampirkan dropdown ke dialog modal, daripada badan 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>

Ini akan melampirkan dropdown Select2 sehingga jatuh dalam DOM modal daripada ke tubuh HTML (default). Lihat https://select2.org/dropdown#dropdown-placement

dboswell
sumber
12
Dikonfirmasi, ini berfungsi seperti pesona dan tampaknya menjadi solusi terbaik untuk masalah ini!
lacco
29
Ini bekerja untuk saya (dengan v4.0.2), tetapi saya harus menggunakannya dropdownParent: $("#myModal"), tidak dropdownParent: "#myModal".
Saxon Druce
6
FWIW, dalam kasus saya, saya perlu mengatur dropdownParent ke tubuh modal, melampirkannya ke modal itu sendiri tidak membawa indeks z cukup tinggi. mis. dropdownParent: $ ('. modal-body', '#myModal')
DrewInTheMountains
1
Ini berfungsi dengan baik tanpa menghapus tabindex. +1
sammry
1
@DrewInTheMountains Saya juga punya masalah mengatur dropdownParentke akar modal, itu memang lebih baik untuk memilih tubuh, jika tidak, Anda mendapatkan bug positioning yang sangat buruk ketika menggulir. Saya mengatur milik saya ke div dengan kelas modal-contentdan itu bekerja seperti pesona!
Shahin Dohan
193

Saya menemukan solusi untuk ini di github untuk select2

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

Untuk bootstrap 3, solusinya adalah:

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

Bootstrap 4 mengubah nama enforceFocusmetode menjadi _enforceFocus, jadi Anda harus menambal itu:

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

Penjelasan disalin dari tautan di atas:

Bootstrap mendaftarkan pendengar ke acara focusin yang memeriksa apakah elemen fokus adalah overlay itu sendiri atau turunan darinya - jika tidak, ia hanya memfokuskan kembali pada overlay. Dengan dropdown select2 yang melekat pada tubuh, ini secara efektif mencegah Anda memasukkan apa pun ke dalam bidang teks.

Anda bisa memperbaiki ini dengan menimpa fungsi menegakkanFokus yang mendaftarkan acara di modal

pymarco
sumber
1
@pymarco Yang itu seharusnya ada di sana sedikit lebih awal untuk dipilih sebagai jawabannya! Terima kasih kawan, untuk memberikan jawaban nyata untuk masalah yang sangat menjengkelkan.
ilter
3
@ pymarco Ini adalah solusi yang tepat. Terima kasih telah menghemat waktu saya.
VKPRO
2
Anda menghemat banyak waktu dengan masalah yang tidak selalu ada di belakangnya. Terima kasih!
user3036342
1
Ini berhasil bagi saya !! Saya sedang menjelajah dan menelusuri utas masalah untuk select2 di github dan tidak mengalami posting yang Anda berikan. Itu googling dan menemukan halaman ini di stackoverflow yang menyelamatkan hidup saya. Terima kasih!
luis.ap.uyen
2
di mana saya meletakkan kode ini dan fungsi apa yang harus dialaminya? Maaf, JS noob di sini, saya mencoba menjadikan ini bagian dari select2 JS atau menempatkannya di atas / akhir halaman, semuanya tanpa hasil. $.fn.modal.Constructor.prototype.enforceFocus = $.noop;
Armitage2k
39

Hapus tabindex="-1"dan tambahkan gayaoverflow:hidden

Berikut ini sebuah contoh:

<div id="myModal" class="modal fade" role="dialog" style="overflow:hidden;">
    <!---content modal here -->
</div>
MrBii
sumber
itu bekerja tetapi ketika saya memiliki modal panjang saya tidak dapat gulir ke bawah!
Tarek Kalaji
1
@TarekKalaji apakah Anda pernah memikirkan cara mengizinkan pengguliran dengan solusi ini?
OverflowingTheGlass
Sudah mencoba menghapus tabindex tetapi tidak cukup. Menambahkan overflow: tersembunyi berguna jika kotak modal panjang ...
Plasebo
Berfungsi untuk saya menghapus atribut indeks tab.
Glen
Just FYI: menghapus tab-index attr akan menghapus kemampuan menutup modal popup dengan tombol esc.
curiousBoy
31
.select2-close-mask{
    z-index: 2099;
}
.select2-dropdown{
    z-index: 3051;
}

Ini adalah solusi saya dengan select2 4.0.0. Cukup timpa css tepat di bawah impor select2.css. Pastikan z-index lebih besar dari dialog atau modal Anda. Saya hanya menambahkan 2000 pada yang default. Karena indeks-dialog saya sekitar 1000.

Diluka W
sumber
1
Tidak ada solusi yang bekerja untuk select2 4.0.0 kecuali ini. Terima kasih banyak.
Neel
Masalah yang sama terjadi jika Select2 (v4.0.0) dalam popover. Dalam bootstrap.cssindeks-z .popoverdiatur ke 1060 sehingga perbaikan ini juga berfungsi. Saya suka karena ini sederhana dan menyelesaikan masalah dengan cara yang sama dengan masalah yang dibuat: z-index diatur dalam style sheet.
Paul
2
Solusi paling sepele namun satu-satunya yang berhasil. Terima kasih!
Ishtiaque Khan
Saya telah menambahkan hal di atas dalam file css saya, tetapi tidak ada perubahan. Saya menggunakan jQuery Mobile. Ada saran?
Sahil Khanna
@ Sahil 1. pastikan itu berhasil menimpa yang asli. cara sederhana adalah menambahkan ini setelah semua file default css2.cek z-indeks, pastikan itu lebih besar dari dialog
Diluka W
26

Atur dropdownParent. Saya harus meletakkannya di .modal-content dalam modal atau teks akan berakhir terpusat.

$("#product_id").select2({
    dropdownParent: $('#myModal .modal-content')
});
bezz
sumber
2
.modal-contentBenar - benar membuat perbedaan. Terima kasih telah menunjukkan 👍
Js Lim
Ini berhasil untuk saya. Saya bertanya-tanya mengapa ini tidak mendapatkan banyak upvotes.
chrisbjr
Bekerja untuk saya Juga Terima Kasih
Neha
9

Menurut dokumentasi select2 resmi masalah ini terjadi karena moda Bootstrap cenderung mencuri fokus dari elemen lain di luar modal.

Secara default, Select2 menempel menu dropdown ke elemen dan itu dianggap "di luar modal".

Alih-alih melampirkan dropdown ke modal itu sendiri dengan pengaturan dropdownParent:

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

Lihat referensi: https://select2.org/troubleshooting/common-problems

Anas
sumber
Baik. itu tidak bekerja dengan popup besar, sekarang setelah menambahkan opsi dropdownParent berfungsi dengan baik.
Yogesh Saroya
8

Saya memiliki masalah yang sama, memperbarui z-indexuntuk .select2-containerharus melakukan trik. Pastikan modal Anda z-indexlebih rendah dari select2's.

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

Diperbarui: Jika kode di atas tidak berfungsi dengan baik, hapus juga tabindex dari modal Anda seperti yang disarankan @breq

hhk
sumber
1
Anda perlu menerapkan ini dengan jawaban @breq untuk membuatnya berfungsi.
Ryan Arief
7

Jus menggunakan kode ini di Document.read ()

$.fn.modal.Constructor.prototype.enforceFocus = function () {};
S.Mohamed Mahdi Ahmadian zadeh
sumber
1
Nama fungsi yang tepat adalah "$ (dokumen). Sudah". Jadi kode harus seperti: $ (dokumen) .ready (function () {$ .fn.modal.Constructor.prototype.enforceFocus = function () {};});
Lech Osiński
1
@ LechOsiński - Terima kasih telah benar-benar menjelaskan cara menggunakan potongan kode kecil ini. Solusi Anda adalah satu-satunya yang bekerja untuk saya. +1
Francis Bartkowiak
7

Masalah Ini Berfungsi Untuk Saya Fungsi Single Jquery

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

ubah file select2.css

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

untuk

z-index: 10000;
...
z-index: 10001;
...
z-index: 10002;
pengguna1616435
sumber
Itulah satu-satunya yang berfungsi untuk saya (jquery-ui-1.10.3.css, jquery-ui-1.9.1.js dan select2 3.4.0). Saya memiliki 2 dialog UI jquery satu di atas yang lain dan select2 pada yang kedua. Saya juga telah meletakkan // mengizinkan interaksi select2, date dan time picker pada dialog jQuery UI $ .ui.dialog.prototype._allowInteraction = function (e) {return !! $ (e.target) .closest ('. Ui- dialog, .ui-datepicker, .select2-drop '). length; }; Saya tidak tahu apakah ini membantu atau tidak.
Adrian P.
5

Untuk lebih memahami bagaimana elemen tabindex bekerja untuk menyelesaikan jawaban yang diterima:

Atribut global tabindex adalah bilangan bulat yang menunjukkan apakah elemen dapat mengambil fokus input (dapat difokus), jika elemen tersebut harus berpartisipasi dalam navigasi keyboard berurutan, dan jika demikian, pada posisi apa. Ini dapat mengambil beberapa nilai:   -sebuah nilai positif berarti harus fokus dan dapat dijangkau melalui navigasi keyboard berurutan; urutan relatifnya ditentukan oleh nilai atribut: berurutan mengikuti peningkatan jumlah tabindex. Jika beberapa elemen berbagi tabindex yang sama, urutan relatifnya mengikuti posisi relatifnya dalam dokumen.
  -sebuah nilai negatif berarti bahwa elemen tersebut harus fokus, tetapi tidak dapat dijangkau melalui navigasi keyboard berurutan;
  -0 berarti bahwa elemen tersebut harus fokus dan dapat dijangkau melalui navigasi keyboard berurutan, tetapi urutan relatifnya ditentukan oleh konvensi platform;

dari: Jaringan Mozilla Devlopper

538ROMEO
sumber
3

Jika Anda memiliki masalah dengan iPad Keyboard yang menyembunyikan satu modal bootstrap sambil mengklik pada select2 masukan, Anda dapat mengatasi ini dengan menambahkan aturan berikut setelah inisialisasi dari select2masukan:

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
}

Diambil dari https://github.com/angular-ui/bootstrap/issues/1812#issuecomment-135119475

EDIT: Jika opsi Anda tidak ditampilkan dengan benar, Anda perlu menggunakan dropdownParentatribut saat menginisialisasi select2:

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

Semoga berhasil (:

Gangai Johann
sumber
3

Berdasarkan @pymarco jawaban saya menulis solusi ini, itu tidak sempurna tetapi menyelesaikan masalah fokus select2 dan mempertahankan urutan tab bekerja di dalam modal

    $.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))
    }
Angelo Cavalet
sumber
3

Dalam kasus saya, saya memiliki masalah yang sama dengan dua modals dan semua diselesaikan dengan menggunakan:

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

Seperti dalam masalah proyek # 41 kata pengguna.

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

kode ini berfungsi. Terima kasih.

ramazan polat
sumber
2

Oke, saya tahu saya terlambat ke pesta. Tetapi izinkan saya berbagi dengan Anda apa yang berhasil bagi saya. Tabindex dan solusi z-index tidak berfungsi untuk saya.

Pengaturan induk dari elemen pilih berfungsi sesuai dengan masalah umum yang terdaftar di situs select2.

pelawak
sumber
1

Jika Anda menggunakan popup seluler jquery, Anda harus menulis ulang fungsi _handleDocumentFocusIn:

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

Clò Luca
sumber
Saya menggunakan jQuery Mobile dan telah menyematkan Select2 di sembulan. Kode yang Anda berikan berfungsi baik di peramban PC. Tetapi ketika saya menjalankan kode ini di peramban seluler, sembulan ditutup dan dibuka kembali ketika nilai apa pun dipilih. Bisakah Anda menyarankan perubahan apa pun yang perlu saya lakukan?
Sahil Khanna
1

Saya memiliki masalah yang sama dengan select2di bootstrap modal, dan solusinya adalah menghapus overflow-y: auto;dan overflow: hidden; dari .modal-opendan.modal classes

Berikut adalah contoh penggunaan jQueryuntuk menghapus overflow-y:

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

saya punya masalah ini sebelumnya, saya menggunakan yii2 dan saya menyelesaikannya dengan cara ini

$.fn.modal.Constructor.prototype.enforceFocus = $.noop;
Yousef
sumber
1

Saya punya masalah semi-terkait dalam suatu aplikasi jadi saya akan memasukkan 2c saya.

Saya memiliki banyak modals dengan formulir yang berisi widget select2. Membuka modal A, lalu modal lain di dalam modal A, akan menyebabkan widget select2 di dalam modal B hilang dan gagal diinisialisasi.

Masing-masing modalnya memuat formulir melalui ajax.

Solusinya adalah menghapus formulir dari dom ketika menutup modal.

$(document).on('hidden.bs.modal', '.modal', function(e) {
    // make sure we don't leave any select2 widgets around 
    $(this).find('.my-form').remove();
});
mesin terbang
sumber
1
$('.modal').on('shown.bs.modal', function (e) {
    $(this).find('.select2me').select2({
        dropdownParent: $(this).find('.modal-content')
    });
})
ocobacho
sumber
1

Saya memecahkan ini secara umum dalam proyek saya dengan kelebihan select2-fungsi. Sekarang ia akan memeriksa apakah tidak ada dropdownParent dan apakah fungsinya dipanggil pada elemen yang memiliki induk dari tipe tersebut div.modal. Jika demikian, itu akan menambahkan modal itu sebagai induk untuk dropdown.

Dengan cara ini, Anda tidak perlu menentukannya setiap kali Anda membuat kotak select2-input-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];
    }
})();
Zombaya
sumber
0

Saya hanya membuatnya bekerja dengan memasukkan select2.min.css

Cobalah

Modal html saya untuk bootstrap 3 adalah

<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>
Pengembang
sumber
0

Anda dapat memanggil pemicu select2 lagi di dalam $ (dokumen) Anda

$(".select2").select2({ 
                width: '120' 
            });
Sinatrya Yogi Rizal
sumber
0

untuk menggunakan bootstrap 4.0 dengan sisi server (ajax atau json data inline), Anda perlu menambahkan semua ini:

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

dan kemudian ketika modal terbuka, buat select2:

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

Dalam kasus saya, saya melakukan ini dan berhasil. Saya menggunakan bundel untuk memuatnya dan dalam hal ini berfungsi untuk saya

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