Select2 не работает при внедрении в модальный загрузчик

когда я использую select2 (input) в модальном bootstrap, я не могу ничего ввести в него. Это как инвалид? Снаружи он modal select2 отлично работает.

enter image description here

пример: 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 не работает при внедрении в bootstrap модальный

19 ответов


хорошо, я должен работать.

изменить

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

to

<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" из модала)


для 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


Я нашел решение этого на github для select2

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

решение:

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

объяснение скопировано из ссылки выше:

Bootstrap регистрирует прослушиватель события focusin, который проверяет, является ли сфокусированный элемент либо самим наложением, либо его потомком - если он не просто перефокусируется на наложении. С select2 выпадающего добавленные в тело это предотвращает вас от ввода в текстовое поле.

вы можете быстро исправить это, перезаписав функцию enforceFocus, которая регистрирует событие на модальном


просто удалить tabindex="-1" и добавить стиль overflow:hidden

вот пример:

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

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

Это мое решение с select2 4.0.0. Просто переопределите css прямо под select2.импорт css. Пожалуйста, убедитесь, что Z-индекс больше, чем ваш диалог или модальный. Я просто добавляю 2000 по умолчанию. Потому что z-индекс моих диалогов составляет около 1000.


изменить select2.в CSS

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

to

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

у меня была такая же проблема, обновление z-index на .select2-container следует сделать трюк. Убедитесь, что ваш модальный z-index ниже, чем select2.

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

обновление: В случае, если выше код не работает должным образом, также удалите tabindexes из вашего модального как @ breq предложил


Jus используйте этот код в документе.read ()

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

ответ, который работал для меня, нашел здесь:https://github.com/select2/select2-bootstrap-theme/issues/41

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

также не требует снятия tabindex.


чтобы лучше понять, как элементы tabindex работают для завершения принятого ответа:

глобальный атрибут tabindex-это целое число, указывающее, может ли элемент принимать фокус ввода (фокусируется), должен ли он участвовать в последовательной навигации по клавиатуре, и если да, то в какой позиции. Он может принимать несколько значений:
  - отрицательное значение означает, что элемент должен быть фокусируемым, но не должен быть доступен с помощью последовательной навигации по клавиатуре;
  -0 означает, что элемент должен быть фокусируемым и достижимым с помощью последовательной навигации по клавиатуре, но его относительный порядок определяется соглашением платформы;
  - положительное значение означает, что должно быть фокусируемым и достижимым с помощью последовательной навигации по клавиатуре; его относительный порядок определяется значением атрибута: последовательное следует за возрастающим числом tabindex. Если несколько элементов имеют одинаковое tabindex, их относительный порядок следует за их относительным положением в документ.

from:Сеть Mozilla Devlopper


на основе ответа @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))
    }

Если вы используете всплывающее окно jQuery mobile, вы должны переписать функцию _handleDocumentFocusIn:

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

если у вас есть проблемы с для iPad клавиатурой, которая скрыть на bootstrap modal при нажатии на select2 input, вы можете решить эту проблему, добавив следующее правило после инициализации 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

EDIT: если ваши возможности не показано правильно, вам нужно использовать при инициализации select2 :

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

удачи (:


у меня такая же проблема с select2 на bootstrap modal, и решением было удалить 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;

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

этот код работает. Спасибо.


Я просто заставляю его работать, включая select2.минута.в CSS

попробуйте iy out

мой модальный 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>

я решил это вообще в моем проекте, перегрузив select2-функция. Теперь он проверит, нет ли dropdownParent и вызывается ли функция для элемента, у которого есть родитель типа div.modal. Если это так, он добавит этот модальный в качестве родителя для раскрывающегося списка.

таким образом, вам не нужно указывать его каждый раз, когда вы создаете select2-input-box.

(function(){
    var oldSelect2 = jQuery.fn.select2;
    jQuery.fn.select2 = function() {
        if (arguments.length === 1 && typeof arguments[0] === 'object' && typeof arguments[0].dropdownParent !== 'defined') {
            const modalParent = jQuery(this).parents('div.modal').first();
            if (modalParent.length > 0) {
                arguments[0].dropdownParent = modalParent;
            }
        }
        return oldSelect2.apply(this,arguments);
    };
})();