Chọn2 không hoạt động khi được nhúng trong một chế độ bootstrap


337

Khi tôi sử dụng select2 (đầu vào) trong phương thức bootstrap, tôi không thể nhập bất cứ thứ gì vào nó. Nó giống như người khuyết tật? Bên ngoài phương thức select2 hoạt động tốt.

nhập mô tả hình ảnh ở đây

Ví dụ hoạt động: http://jsfiddle.net/byJy8/1/ mã:

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

và 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};
        }
    }
});

câu trả lời:

ở đây bạn có thể tìm thấy một sửa chữa nhanh chóng

và đây là 'đúng cách': Chọn2 không hoạt động khi được nhúng trong phương thức bootstrap


1
Đó là, loại bỏ thuộc tính tabindex = "- 1" khỏi phần tử.
Nikit Barochiya

Câu trả lời của dboswell là giải pháp phù hợp, NHƯNG, dropdownParentkhông nên trên div gốc, nhưng sâu hơn, ví dụ như div với lớp modal-content, nếu không, các vị trí thả xuống bị rối khi cuộn phương thức.
Shahin Dohan

Câu trả lời:


605

Ok, tôi đã có nó để làm việc.

thay đổi

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

đến

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

(xóa tabindex = "- 1" khỏi phương thức)


22
Có thể có một giải pháp khác? Bởi vì cửa sổ phương thức sẽ không đóng bằng phím Esc.
woto

19
loại bỏ tabindex = "- 1" không hoạt động với tôi. Tôi vừa thay đổi <div class = "modal-body"> thành <div class = "modal-body" style = "overflow: hidden;">
Wissem

39
Làm thế quái nào bạn phát hiện ra điều đó?
DontVoteMeDown

6
Tôi đã thử tất cả các tùy chọn, nhưng không có gì làm việc cho tôi. Tôi đang sử dụng select2 4.0
Girish Gupta

7
Cảm ơn! Đã 4 năm và nó vẫn là một sửa chữa hợp lệ.
Linek

247

Đối với Chọn2 v4:

Sử dụng dropdownParentđể đính kèm danh sách thả xuống vào hộp thoại phương thức, thay vì phần thân 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>

Điều này sẽ đính kèm trình đơn thả xuống Chọn2 để nó nằm trong DOM của phương thức chứ không phải trong phần thân HTML (mặc định). Xem https://select2.org/dropdown#dropdown-plocation


12
Khẳng định, điều này đang hoạt động như một cơ duyên và dường như là giải pháp tốt nhất cho vấn đề này!
lacco 7/12/2015

29
Điều này làm việc cho tôi (với v4.0.2), nhưng tôi phải sử dụng dropdownParent: $("#myModal"), không phải dropdownParent: "#myModal".
Saxon Druce

6
FWIW, trong trường hợp của tôi, tôi cần đặt dropdownParent vào phần thân của phương thức, việc gắn nó vào chính phương thức không đưa chỉ số z lên đủ cao. ví dụ: dropdownParent: $ ('. modal-body', '#myModal')
DrewInTheMaxs

1
Điều này hoạt động hoàn toàn tốt mà không cần loại bỏ tabindex. +1
lấy mẫu

1
@DrewInTheMenezs Tôi cũng gặp vấn đề khi đặt dropdownParentgốc của phương thức, thực sự tốt hơn là chọn phần thân, nếu không bạn sẽ gặp lỗi định vị thực sự xấu khi cuộn. Tôi đặt tôi vào div với lớp modal-contentvà nó hoạt động như một bùa mê!
Shahin Dohan

193

Tôi đã tìm thấy một giải pháp cho vấn đề này trên github cho select2

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

Đối với bootstrap 3, giải pháp là:

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

Bootstrap 4 đổi tên thành enforceFocus phương thức thành _enforceFocus, vì vậy bạn sẽ cần phải vá nó thay vào đó:

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

Giải thích được sao chép từ liên kết ở trên:

Bootstrap đăng ký một người nghe đến sự kiện tập trung để kiểm tra xem phần tử được tập trung là chính lớp phủ hay hậu duệ của nó - nếu không nó chỉ tập trung vào lớp phủ. Với trình đơn thả xuống select2 được gắn vào thân máy, điều này giúp bạn không phải nhập bất cứ thứ gì vào trường văn bản một cách hiệu quả.

Bạn có thể nhanh chóng sửa lỗi này bằng cách ghi đè hàm execceF Focus đăng ký sự kiện trên phương thức


1
@pymarco Cái đó đáng lẽ phải có sớm hơn một chút để được chọn làm câu trả lời! Cảm ơn người đàn ông, đã cung cấp một câu trả lời thực sự cho một vấn đề thực sự gây phiền nhiễu.
ilter

3
@pymarco Đây là giải pháp chính xác. Cảm ơn bạn đã tiết kiệm thời gian của tôi.
VKPRO

2
Bạn đã tiết kiệm cho tôi rất nhiều thời gian với một vấn đề không phải lúc nào cũng đứng đầu. Cảm ơn bạn!
dùng3036342

1
Điều này làm việc cho tôi !! Tôi đã duyệt và duyệt qua các vấn đề chủ đề cho select2 trong github và không chạy vào bài đăng mà bạn cung cấp. Nó đã googling và tìm thấy trang này trong stackoverflow những gì đã cứu cuộc đời tôi. Cảm ơn bạn!
luis.ap.uyen

2
Tôi nên đặt mã này ở đâu và nên xử lý chức năng nào? Xin lỗi, JS noob ở đây, tôi đã thử biến nó thành một phần của select2 JS hoặc đặt nó ở đầu / cuối trang, tất cả đều không thành công. $.fn.modal.Constructor.prototype.enforceFocus = $.noop;
Armitage2k

39

Chỉ cần loại bỏ tabindex="-1" và thêm phong cáchoverflow:hidden

Đây là một ví dụ:

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

Nó hoạt động nhưng khi tôi có phương thức dài, tôi không thể cuộn xuống!
Tarek Kalaji 17/03/18

1
@TarekKalaji bạn đã bao giờ tìm ra cách cho phép cuộn với giải pháp này chưa?
Tràn đầy

Đã thử loại bỏ tabindex nhưng không đủ. Thêm tràn: ẩn rất hữu ích nếu hộp phương thức dài ...
Plasebo

Làm việc cho tôi loại bỏ thuộc tính chỉ mục tab.
Glen

Chỉ cần FYI: loại bỏ attr chỉ mục tab sẽ loại bỏ khả năng đóng cửa sổ bật lên phương thức bằng nút esc.
tò mòBoy

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

Đây là giải pháp của tôi với select2 4.0.0. Chỉ cần ghi đè css ngay bên dưới quá trình nhập select2.css. Vui lòng đảm bảo chỉ số z lớn hơn hộp thoại hoặc phương thức của bạn. Tôi chỉ cần thêm 2000 vào những cái mặc định. Vì chỉ số z của hộp thoại của tôi là khoảng 1000.


1
Không có giải pháp nào hoạt động cho select2 4.0.0 ngoại trừ điều này. Cảm ơn rất nhiều.
Neel

Vấn đề tương tự xảy ra nếu Chọn2 (v4.0.0) nằm trong cửa sổ bật lên. Trong bootstrap.csschỉ mục z của .popoverđược đặt thành 1060, vì vậy sửa lỗi này cũng hoạt động. Tôi thích nó bởi vì nó đơn giản và nó giải quyết vấn đề giống như cách tạo ra vấn đề: z-index được đặt trong một biểu định kiểu.
Paul

2
Các giải pháp tầm thường nhất nhưng duy nhất mà làm việc. Cảm ơn!
Ishtiaque Khan

Tôi đã thêm ở trên trong tập tin css của mình, nhưng nó không có thay đổi. Tôi đang sử dụng jQuery Mobile. Có gợi ý nào không?
Sahil Khanna

@Sahil 1. hãy chắc chắn rằng nó đã ghi đè thành công bản gốc. cách đơn giản là thêm cái này sau tất cả các tệp css mặc định2.kiểm tra chỉ mục z, đảm bảo nó lớn hơn hộp thoại
Diluka W

26

Đặt dropdownParent. Tôi đã phải đặt nó trên .modal-nội dung trong phương thức hoặc văn bản sẽ kết thúc ở giữa.

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

2
Sự .modal-contentthực sự làm cho một sự khác biệt. Cảm ơn bạn đã chỉ ra
Js Lim

Điều này làm việc cho tôi. Tôi tự hỏi tại sao điều này đã không nhận được nhiều upvote.
chrisbjr

Cũng làm việc cho tôi Cảm ơn
Neha


9

Theo tài liệu select2 chính thức, vấn đề này xảy ra do các phương thức Bootstrap có xu hướng đánh cắp sự tập trung từ các yếu tố khác bên ngoài phương thức.

Theo mặc định, Select2 đính kèm menu thả xuống với phần tử và nó được coi là "bên ngoài phương thức".

Thay vào đó, hãy đính kèm trình đơn thả xuống vào chính phương thức với cài đặt dropdownParent:

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

Xem tài liệu tham khảo: https://select2.org/troubledhoot/common-probols


Tốt nó không hoạt động với cửa sổ bật lên tuyệt vời, bây giờ sau khi thêm tùy chọn dropdownParent, nó hoạt động tốt.
Yogesh Saroya

8

Tôi đã có cùng một vấn đề, cập nhật z-indexcho .select2-containernên làm thủ thuật. Hãy chắc chắn rằng phương thức của bạn z-indexthấp hơn select2.

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

Đã cập nhật: Trong trường hợp mã trên không hoạt động chính xác, hãy xóa tabindexes khỏi phương thức của bạn như @oustq đề xuất


1
bạn cần thực hiện điều này với câu trả lời @enameq để làm cho nó hoạt động.
Ryan Arief

7

Jus sử dụng mã này trên Document.read ()

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

1
Tên hàm thích hợp là "$ (tài liệu). Đã". Vì vậy, mã phải giống như: $ (tài liệu). Đã (hàm () {$ .fn.modal.Constructor.prototype.enforceF Focus = function () {};});
Lech Osiński

1
@ LechOsiński - Cảm ơn bạn đã thực sự mô tả cách sử dụng đoạn mã nhỏ này. Giải pháp của bạn là người duy nhất làm việc cho tôi. +1
Francis Bartkowiak

7

Vấn đề này Sloved làm việc cho tôi Chức năng Jquery duy nhất

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

Cảm ơn bạn! Điều này đã giải quyết vấn đề của tôi
Mihai Alexandru-I Muff

5

thay đổi tập tin select2.css

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

đến

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

Đó là người duy nhất làm việc cho tôi (jquery-ui-1.10.3.css, jquery-ui-1.9.1.js và select2 3.4.0). Tôi có 2 hộp thoại UI jquery một trên đầu kia và select2 trên hộp thoại thứ hai. Ngoài ra, tôi đã đặt // cho phép tương tác của select2, bộ chọn ngày và giờ trên hộp thoại UI UI $ .ui.dialog.prototype._allowInteraction = function (e) {return !! $ (e.target) .closest ('. Ui- hộp thoại, .ui-datepicker, .select2-drop '). length; }; Tôi không có ý tưởng nếu điều này giúp đỡ hay không.
Adrian P.

5

Chỉ cần hiểu rõ hơn cách các yếu tố tabindex hoạt động để hoàn thành câu trả lời được chấp nhận:

Thuộc tính toàn cầu tabindex là một số nguyên cho biết phần tử có thể lấy tiêu điểm đầu vào (có thể lấy nét được không), nếu nó nên tham gia vào điều hướng bàn phím tuần tự và nếu vậy, ở vị trí nào. Nó có thể nhận một số giá trị:
  -một giá trị âm có nghĩa là phần tử phải có thể lấy nét được, nhưng không thể truy cập được thông qua điều hướng bàn phím tuần tự;   -một giá trị tích cực có nghĩa là có thể tập trung và có thể truy cập thông qua điều hướng bàn phím tuần tự; thứ tự tương đối của nó được xác định bởi giá trị của thuộc tính: tuần tự theo số lượng ngày càng tăng của tabindex. Nếu một số phần tử chia sẻ cùng một tabindex, thứ tự tương đối của chúng tuân theo vị trí tương đối của chúng trong tài liệu.
  -0 có nghĩa là phần tử phải có thể tập trung và có thể truy cập thông qua điều hướng bàn phím tuần tự, nhưng thứ tự tương đối của nó được xác định theo quy ước nền tảng;

từ: Mạng Mozilla Devlopper


3

Nếu bạn gặp vấn đề với bàn phím iPad ẩn chế độ bootstrap trong khi nhấp vào đầu vào select2 , bạn có thể giải quyết vấn đề này bằng cách thêm quy tắc sau sau khi khởi tạo select2đầu vào:

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
}

Lấy từ https://github.com/angular-ui/bootstrap/issues/1812#issuecomment-135119475

EDIT: Nếu các tùy chọn của bạn không được hiển thị đúng, bạn cần sử dụng dropdownParentthuộc tính khi khởi tạo select2:

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

Chúc may mắn (:


3

Dựa trên câu trả lời @pymarco tôi đã viết giải pháp này, nó không hoàn hảo nhưng giải quyết vấn đề lấy nét select2 và duy trì chuỗi tab hoạt động bên trong phương thức

    $.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

Trong trường hợp của tôi, tôi có cùng một vấn đề với hai phương thức và tất cả đã được giải quyết bằng cách sử dụng:

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

Như trong vấn đề dự án # 41, một người dùng nói.


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

mã này đang hoạt động. Cảm ơn bạn.


2

Được rồi, tôi biết tôi đến bữa tiệc muộn. Nhưng hãy để tôi chia sẻ với bạn những gì làm việc cho tôi. Các giải pháp tabindex và z-index không hoạt động với tôi.

Đặt cha mẹ của phần tử chọn hoạt động theo các vấn đề phổ biến được liệt kê trên trang select2.


1

Nếu bạn sử dụng cửa sổ bật lên di động jquery, bạn phải viết lại hàm _handleDocumentF FocusIn:

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


Tôi đang sử dụng jQuery Mobile và đã nhúng Select2 trong cửa sổ bật lên. Mã bạn đã cung cấp hoạt động tốt trên trình duyệt PC. Nhưng khi tôi chạy mã này trên trình duyệt di động, cửa sổ bật lên sẽ đóng và mở lại khi có bất kỳ giá trị nào được chọn. Bạn có thể đề nghị bất kỳ thay đổi tôi cần phải thực hiện?
Sahil Khanna

1

Tôi có vấn đề tương tự với select2bootstrap modal, và giải pháp là để loại bỏ các overflow-y: auto;overflow: hidden; từ .modal-open.modal classes

Dưới đây là ví dụ về việc sử dụng jQueryđể loại bỏ overflow-y:

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

1

tôi đã có vấn đề này trước đây, tôi đang sử dụng yii2 và tôi đã giải quyết nó theo cách này

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

1

Tôi đã có một vấn đề liên quan đến bán trong một ứng dụng vì vậy tôi sẽ đưa vào 2c của mình.

Tôi có nhiều phương thức với các biểu mẫu có chứa select2 widget. Mở phương thức A, sau đó một phương thức khác bên trong phương thức A, sẽ khiến các vật dụng select2 bên trong phương thức B biến mất và không thể khởi tạo.

Mỗi phương thức này đang tải các biểu mẫu thông qua ajax.

Giải pháp là loại bỏ các hình thức khỏi dom khi đóng một phương thức.

$(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

Tôi đã giải quyết điều này nói chung trong dự án của mình bằng cách quá tải select2chức năng. Bây giờ nó sẽ kiểm tra nếu không có dropdownParent và nếu hàm được gọi trên một phần tử có cha mẹ của loại div.modal. Nếu vậy, nó sẽ thêm phương thức đó làm cha mẹ cho trình đơn thả xuống.

Bằng cách này, bạn không phải chỉ định nó mỗi khi bạn tạo hộp 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

Tôi chỉ làm cho nó hoạt động bằng cách bao gồm select2.min.css

Hãy thử

Html modal của tôi của bootstrap 3 là

<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

bạn có thể gọi lại select2 kích hoạt bên trong $ (tài liệu) của bạn

$(".select2").select2({ 
                width: '120' 
            });

0

để sử dụng bootstrap 4.0 với phía máy chủ (ajax hoặc json data inline), bạn cần thêm tất cả những điều này:

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

và sau đó khi phương thức được mở, tạo select2:

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

-1

Trong trường hợp của tôi, tôi đã làm điều này và nó hoạt động. Tôi sử dụng gói để tải nó và trong trường hợp này nó hoạt động với tôi

 $(document).on('select2:select', '#Id_Producto', function (evt) {
   // Here your code...
  });
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.