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

338

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

введите описание изображения здесь

Рабочий пример: 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>

и 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 не работает, когда встраивается в модал начальной загрузки

breq
источник
1
То есть удаление атрибута tabindex = "- 1" из элемента.
Никит Барочия
Ответ dboswell - правильное решение, НО, он dropdownParentне должен быть в корневом div, а должен быть глубже, например, div с class modal-content, в противном случае позиции выпадающего меню будут испорчены при прокрутке модального окна.
Шахин Дохан

Ответы:

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

breq
источник
22
Может быть, есть другое решение? Потому что модальное окно не закроется клавишей Esc.
woto
19
удаление tabindex = "- 1" не работает со мной. Я только что изменил <div class = "modal-body"> на <div class = "modal-body" style = "overflow: hidden;">
Wissem
39
Как, черт возьми, вы это обнаружили?
DontVoteMeDown
6
Я перепробовал все варианты, но у меня ничего не работает. Я использую select2 4.0
Гириш Гупта
7
Спасибо! Прошло 4 года, и это все еще исправление.
Linek
248

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

dboswell
источник
12
Подтверждено, что это работает как шарм и, кажется, лучшее решение этой проблемы!
Lacco
29
Это работало для меня (с v4.0.2), но я должен был использовать dropdownParent: $("#myModal"), а не dropdownParent: "#myModal".
Саксонский друс
6
FWIW, в моем случае мне нужно было установить dropdownParent на тело модала, привязав его к самому модалу, что не подняло z-индекс достаточно высоко. например, dropdownParent: $ ('. modal-body', '#myModal')
DrewInTheMountains
1
Это прекрасно работает без удаления tabindex. +1
Самри
1
@DrewInTheMountains У меня также были проблемы с установкой dropdownParentкорня модального режима, действительно лучше выбрать тело, в противном случае вы получаете очень плохие ошибки позиционирования при прокрутке. Я поставил мой на div с классом, modal-contentи это работает как шарм!
Шахин Дохан
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 эффективно предотвращает ввод чего-либо в текстовое поле.

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

pymarco
источник
1
@pymarco Это нужно было сделать немного раньше, чтобы выбрать ответ! Спасибо, мужчина, за реальный ответ на действительно надоедливую проблему.
ilter
3
@pymarco Это правильное решение. Спасибо, что сэкономили мое время.
ВКПРО
2
Вы сэкономили мне массу времени с проблемой, которая не всегда поднимала его голову. Спасибо!
user3036342
1
Это сработало для меня! Я просматривал и просматривал темы вопросов для select2 в github и не столкнулся с тем сообщением, которое вы предоставили. Я нашел эту страницу в stackoverflow, и это спасло мне жизнь. Спасибо!
luis.ap.uyen
2
куда мне поместить этот код и к какой функции он должен обращаться? Извините, JS noob здесь, я попытался сделать это частью select2 JS или разместить его в верхней / конце страницы, но все безуспешно. $.fn.modal.Constructor.prototype.enforceFocus = $.noop;
Armitage2k
39

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

Вот пример:

<div id="myModal" class="modal fade" role="dialog" style="overflow:hidden;">
    <!---content modal here -->
</div>
MrBii
источник
это работает, но когда у меня длинный модальный режим, я не могу прокрутить вниз!
Тарек Каладжи
1
@TarekKalaji Вы когда-нибудь выясняли, как разрешить прокрутку с помощью этого решения?
OverflowingTheGlass
Попытка удаления tabindex, но не было достаточно. Добавление переполнения: скрыто полезно, если модальное поле длинное ...
Plasebo
Сработало у меня удаление атрибута индекса вкладки.
Глен
К вашему сведению: удаление атрибута tab-index удалит возможность закрытия модального всплывающего окна кнопкой esc.
curiousBoy
31
.select2-close-mask{
    z-index: 2099;
}
.select2-dropdown{
    z-index: 3051;
}

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

Дилука W
источник
1
Ни одно из решений не работало для select2 4.0.0, кроме этого. Большое спасибо.
Нил
Та же проблема возникает, если Select2 (v4.0.0) находится в поповере. В bootstrap.cssz-index .popoverустановлено значение 1060, так что это исправление также работает. Мне нравится это, потому что это просто, и это решает проблему так же, как проблема была создана: z-index установлен в таблице стилей.
Пол
2
Самое тривиальное, пока единственное решение, которое сработало. Спасибо!
Иштьяк Хан
Я добавил выше в моем файле CSS, но он не имеет изменений. Я использую jQuery Mobile. Любые предложения, пожалуйста?
Сахил Кханна
@Sahil 1. убедитесь, что он успешно переопределил исходные. простой способ - добавить это после того, как все файлы по умолчанию css files2.check z-index, убедитесь, что он больше, чем у диалога
Diluka W 22.02.16
26

Установите dropdownParent. Я должен был установить его на .modal-content в модальном режиме, иначе текст окажется по центру.

$("#product_id").select2({
    dropdownParent: $('#myModal .modal-content')
});
Bezz
источник
2
.modal-contentДействительно сделать разницу. Спасибо за указание 👍
Js Lim
Это сработало для меня. Интересно, почему это не получило столько голосов.
chrisbjr
Работал для меня также спасибо
Неха
11

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

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

Также не требует удаления tabindex.

Ашраф Сламанг
источник
Это самый хороший способ, он также сохраняет все функциональные возможности модальными.
Edofre
9

Согласно официальной документации select2, эта проблема возникает из-за того, что модальности Bootstrap стремятся украсть фокус у других элементов вне модальных.

По умолчанию Select2 прикрепляет раскрывающееся меню к элементу и считается «за пределами модального».

Вместо этого прикрепите выпадающий список к самому модалу с помощью параметра dropdownParent:

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

См. Ссылку: https://select2.org/troublesho//monmon-problems.

Анас
источник
Хорошо. он не работал с увеличенным всплывающим окном, теперь после добавления опции dropdownParent работает нормально.
Йогеш Сароя
8

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

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

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

HHK
источник
1
вам нужно реализовать это с помощью ответа @breq, чтобы все заработало.
Райан Ариф
7

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

$.fn.modal.Constructor.prototype.enforceFocus = function () {};
С.Мохамед Махди Ахмадиан Заде
источник
1
Правильное имя функции - «$ (document) .ready». Поэтому код должен выглядеть следующим образом: $ (document) .ready (function () {$ .fn.modal.Constructor.prototype.enforceFocus = function () {};});
Лех
1
@ LechOsiński - Спасибо, что на самом деле описали, как использовать этот маленький кусок кода. Ваше решение - единственное, которое сработало для меня. +1
Фрэнсис Бартковяк
7

Эта проблема не подходит для одной функции Jquery

$('#myModal .select2').each(function() {  
   var $p = $(this).parent(); 
   $(this).select2({  
     dropdownParent: $p  
   });  
});
Винот Смарт
источник
5

изменить файл select2.css

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

в

z-index: 10000;
...
z-index: 10001;
...
z-index: 10002;
user1616435
источник
Это единственное, что работает для меня (jquery-ui-1.10.3.css, jquery-ui-1.9.1.js и select2 3.4.0). У меня есть 2 диалоговых окна jquery UI, один поверх другого, и select2 во втором. Также я добавил // разрешить взаимодействие выбора 2, выбора даты и времени в диалоговом окне пользовательского интерфейса jQuery $ .ui.dialog.prototype._allowInteraction = function (e) {return !! $ (e.target) .closest ('. Ui- диалог, .ui-datepicker, .select2-drop '). length; }; Я понятия не имею, если это поможет или нет.
Адриан П.
5

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

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

от: сеть разработчиков Mozilla

538ROMEO
источник
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 у меня не сработали.

Установка родителя элемента select работала в соответствии с общими проблемами, перечисленными на сайте select2.

джокер
источник
1

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

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

Доктор Кло Лука
источник
Я использую jQuery Mobile и встроил Select2 во всплывающее окно. Предоставленный вами код хорошо работает в браузере ПК. Но когда я запускаю этот код в мобильном браузере, всплывающее окно закрывается и снова открывается, когда выбрано любое значение. Можете ли вы предложить какие-либо изменения, которые мне нужно сделать?
Сахил Кханна
1

У меня та же проблема с select2in bootstrap modal, и решением было удалить overflow-y: auto;и overflow: hidden; от .modal-openи.modal classes

Вот пример использования jQueryдля удаления overflow-y:

$('.modal').css('overflow-y','visible');
$('.modal').css('overflow','visible');
Brane
источник
1

у меня была эта проблема раньше, я использую yii2, и я решил ее таким образом

$.fn.modal.Constructor.prototype.enforceFocus = $.noop;
Юсеф
источник
1

У меня была проблема, связанная с полусвязью в приложении, поэтому я добавлю свой 2c.

У меня есть несколько модальных форм с формами, содержащими виджеты select2. Открытие модала А, затем другого модала внутри модала А, приведет к тому, что виджеты 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')
    });
})
ocobacho
источник
1

Я решил это вообще в моем проекте, перегрузив 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);
    };
    // Copy all properties of the old function to the new
    for (var key in oldSelect2) {
        jQuery.fn.select2[key] = oldSelect2[key];
    }
})();
Zombaya
источник
0

Я просто работаю, включив select2.min.css

Попробуй

Мой модальный 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>
разработчик
источник
0

Вы можете снова вызвать триггер select2 внутри своего $ (документа)

$(".select2").select2({ 
                width: '120' 
            });
Синатря Йоги Ризал
источник
0

чтобы использовать начальную загрузку 4.0 со стороны сервера (встроенные данные ajax или json), вам необходимо добавить все это:

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

и затем, когда модальный режим открыт, создайте select2:

  // when modal is open
  $('.modal').on('shown.bs.modal', function () {
            $('select').select2({
                  // ....
            });
  });
Vero O
источник
-1

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

 $(document).on('select2:select', '#Id_Producto', function (evt) {
   // Here your code...
  });
Гильермо Пуэртас Кастийон
источник