Select2 не працює, коли вбудований в режим завантаження


338

Коли я використовую select2 (input) в режимі завантаження, я нічого не можу вводити в нього. Це як інвалід? Поза модальним 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" з елемента.
Микит Барохія

Відповідь dboswell - це правильне рішення, Але dropdownParentНЕ має бути в кореневій діві, але глибше, наприклад, div з класом 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" з модального)


22
Може бути, є ще одне рішення? Тому що модальне вікно потім не закриється клавішею Esc.
woto

19
видалення tabindex = "- 1" не працювало у мене. Я щойно змінив <div class = "modal-body"> на <div class = "modal-body" style = "overflow: hidden;">
Wissem

39
Як чорт ти це відкрив?
DontVoteMeDown

6
Я спробував усі варіанти, але нічого не працює для мене. Я використовую select2 4.0
Girish Gupta

7
Дякую! Минуло 4 роки, і це все ще дійсне виправлення.
Лінек

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


12
Підтверджено, що це працює як шарм і, здається, найкраще рішення цієї проблеми!
лакко

29
Це працювало для мене (з v4.0.2), але я повинен був використовувати dropdownParent: $("#myModal"), не dropdownParent: "#myModal".
Саксонське Друче

6
FWIW, в моєму випадку мені потрібно було встановити dropdownParent до тіла модалу, приєднання його до самого модалу не піднесло z-індекс досить високо. наприклад, dropdownParent: $ ('. modal-body', '#myModal')
DrewInTheMountains

1
Це прекрасно працює без видалення табіндексу. +1
саммрій

1
@DrewInTheMountains У мене також виникли проблеми із встановленням dropdownParentкореня модалу , це дійсно краще вибрати тіло, інакше при прокрутці ви отримаєте дійсно погані помилки позиціонування. Я ставлю свою діву з класом, modal-contentі це працює як шарм!
Шахін Дохан

193

Я знайшов рішення для цього на github для select2

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

Для завантажувального пристрою 3 рішенням є:

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

Bootstrap 4 перейменував enforceFocusметод на _enforceFocus, тому вам потрібно буде виправити це:

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

Пояснення скопійовано із посилання вище:

Bootstrap реєструє слухача події focusin, який перевіряє, чи фокусований елемент є або самим накладом, або його нащадком - якщо не він просто переорієнтується на накладку. Завдяки прикріпленому до тіла випадаючому меню Select2 це ефективно запобігає введенню будь-чого в текстове поле.

Ви можете виправити це, замінивши функцію ExecuceFocus, яка реєструє подію на модалі


1
@pymarco Це, мабуть, було трохи раніше, щоб обрати його як відповідь! Спасибі людина, що ви дали реальну відповідь на справді роздратовану проблему.
ilter

3
@pymarco Це правильне рішення. Дякую, що заощадили мій час.
ВКПРО 12.01.15

2
Ви врятували мені багато часу з проблемою, яка не завжди перевертала голову. Дякую!
користувач3036342

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>

вона працює, але коли у мене довгий модальний режим, я не можу прокрутити вниз!
Тарек Каладжи

1
@TarekKalaji Ви коли-небудь придумували, як дозволити прокручування за допомогою цього рішення?
Переповнення

Намагався видалити табіндекс, але його не доводили. Додавання переповнення: приховано корисно, якщо модальне поле довге ...
Plasebo

Для мене було видалення атрибута індексу вкладки.
Глен

Просто FYI: видалення attr табулятора-індексу видалить можливість закриття модального спливаючого вікна кнопкою esc
цікавоБой

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

Це моє рішення з select2 4.0.0. Просто замініть css прямо під імпортом select2.css. Переконайтеся, що z-індекс перевищує діалог чи модаль. Я просто додаю 2000 до стандартних. Оскільки z-індекс моїх діалогів становить близько 1000.


1
Жодне з рішень не працювало для select2 4.0.0, крім цього. Дуже дякую.
Ніл

Ця ж проблема виникає, якщо Select2 (v4.0.0) перебуває у спокійному положенні. У bootstrap.cssz-індексі .popoverвстановлено 1060, тому це виправлення також працює. Мені це подобається, тому що це просто, і він вирішує проблему так само, як створювалася проблема: z-індекс встановлений у таблиці стилів.
Павло

2
Найбільш банальне, але єдине рішення, яке спрацювало. Дякую!
Іштяке Хан

Я додав вище у свій файл css, але він не має змін. Я використовую jQuery Mobile. Будь-які пропозиції, будь ласка?
Сахіл Ханна

@Sahil 1. переконайтесь, що він успішно перемінив оригінали. простий спосіб - додати це після всіх файлів CSS за замовчуванням. Перевірте z-індекс, переконайтеся, що він більший, ніж діалог
Diluka W

26

Встановити спадний параметр. Мені довелося встановити його .modal-content в модальному режимі, інакше текст закінчиться в центрі.

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

2
.modal-contentДійсно зробити різницю. Дякуємо, що вказали 👍
Js Lim

Це працювало для мене. Цікаво, чому це не отримало стільки відгуків.
chrisbjr

Також працював для мене Спасибі
Neha


9

Згідно з офіційною документацією select2, ця проблема виникає через те, що модалі Bootstrap, як правило, крадуть фокус у інших елементів поза модальним.

За замовчуванням Select2 додає елемент, що випадає, і вважається "поза модальним".

Замість цього прикріпіть спадне меню до самого модалу за допомогою налаштування dropdownParent:

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

Див. Посилання: https://select2.org/troubleshooting/common-problems


Добре. він не працює з чудовим спливаючим вікном, тепер після додавання випадаючого параметра Параметр його працює добре.
Yogesh Saroya

8

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

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

Оновлено: Якщо вищезгаданий код не працює належним чином, також видаліть tabindexes зі свого модального способу, як запропонував @breq


1
вам потрібно реалізувати це за допомогою відповіді @breq, щоб це працювало.
Ryan Arief

7

Jus використовувати цей код на Document.read ()

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

1
Власна назва функції - "$ (документ). Вже". Отже, код повинен бути таким: $ (document) .ready (function () {$ .fn.modal.Constructor.prototype.enforceFocus = function () {};});
Лех Осинський

1
@ LechOsiński - Дякую, що насправді описав, як використовувати цей маленький фрагмент коду. Ваше рішення - єдине, що працювало на мене. +1
Френсіс Бартковяк

7

Ця проблема Sloved працює для мене функцією одиночного 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;

Це єдина для мене робота (jquery-ui-1.10.3.css, jquery-ui-1.9.1.js та select2 3.4.0). У мене є два діалогових вікна інтерфейсу jquery один на іншому та select2 на другому. Також я поставив // дозволити взаємодію select2, вибору дати та часу у діалоговому вікні інтерфейсу jQuery $ .ui.dialog.prototype._allowInteraction = function (e) {return !! $ (e.target) .closest ('. Ui- діалог, .ui-datepicker, .select2-drop '). довжина; }; Я поняття не маю, допоможе це чи ні.
Адріан П.

5

Просто, щоб краще зрозуміти, як працюють елементи tabindex для завершення прийнятої відповіді:

Глобальний атрибут tabindex - це ціле число, яке вказує, чи може елемент брати фокус на вході (фокусується), чи повинен він брати участь у послідовній навігації по клавіатурі, і якщо так, то в якій позиції. Це може приймати кілька значень:
  -негативне значення означає, що елемент повинен бути орієнтованим, але не повинен бути доступний за допомогою послідовної навігації по клавіатурі;
  -0 означає, що елемент повинен бути орієнтованим і доступним через послідовну навігацію по клавіатурі, але його відносний порядок визначається конвенцією платформи;
  - засоби позитивного значення повинні бути орієнтованими та доступними через послідовну навігацію по клавіатурі; її відносний порядок визначається значенням атрибута: послідовне слідування за зростаючою кількістю табіндексу. Якщо декілька елементів поділяють один і той же табіндекс, їх відносний порядок відповідає їх відносному положенню в документі.

від: Мережа Mozilla Devlopper


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/isissue/1812#issuecomment-135119475

EDIT: Якщо ваші параметри не відображаються належним чином, вам потрібно використовувати 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 не працювали для мене.

Установка батьківського елемента вибору працювала відповідно до загальних проблем, перелічених на сайті 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');

1

У мене була ця проблема раніше, я використовую yii2, і я вирішив її таким чином

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

1

У мене в програмі була проблема, пов’язана з напівзв’язком, тому я поставив свою 2с

У мене є кілька модалів з формами, що містять віджети select2. Відкриття модального A, а потім інший модальний всередині модального A, призведе до зникнення віджетів select2 всередині мода B і відсутності ініціалізації.

Кожен із цих способів завантажував форми через ajax.

Рішення полягало в тому, щоб видалити форми з дому при закритті модалі.

$(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. Тепер він перевірить, чи немає спадногоПарента і чи викликана функція елемента, у якого є батьківський тип div.modal. Якщо це так, він додасть цей модаль як батьків для випадаючого.

Таким чином, вам не потрібно вказувати його щоразу, коли ви створюєте поле Select2-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];
    }
})();

0

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

Спробуйте iy

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

щоб використовувати bootstrap 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...
  });
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.