模态框中使用自定义数据的Select2组件搜索功能失效问题
解决Bootstrap 4模态框内Select2 4.0.5搜索失效问题
问题描述
使用Select2 4.0.5搭配Bootstrap 4框架时,自定义数据适配器在模态框外的测试select元素上运行完全正常,但模态框内的Select2组件搜索栏无法正常工作。
原代码
HTML部分
<div id="modal-schedule" class="modal fade"> <div class="modal-dialog modal-dialog-vertical-center modal-lg" role="document"> <form id="form-schedule" method="post"> <div class="modal-content bd-0"> <div class="modal-header pd-y-20 pd-x-25"> <h6 class="mg-b-0 tx-uppercase tx-primary tx-bold modal-title"><span></span> Record</h6> </div> <div class="modal-body pd-25"> <div class="row mg-b-20"> <label class="col-sm-3 form-control-label">Title<span class="tx-danger">*</span></label> <div class="col-sm-9 mg-t-10 mg-sm-t-0"> <input name="title" type="text" class="form-control" required> </div> </div> <div class="row mg-b-20"> <label class="col-sm-3 form-control-label">Company<span class="tx-danger">*</span></label> <div class="col-sm-9 mg-t-10 mg-sm-t-0"> <select name="company_id" class="form-control normal" required> </select> </div> </div> </div> <div class="modal-footer d-inline-block tx-center"> <input name="id" type="hidden" class="form-control"> <button name="submit-schedule" type="submit" class="btn btn-form btn-primary"><small>SUBMIT</small></button> <button type="button" class="btn btn-form btn-secondary modal-cancel-reload" data-modal="modal-schedule" data-reload="origin"><small>CANCEL</small></button> </div> </div> </form> </div> </div>
JavaScript部分
$(function(){ var items = <?php echo json_encode(array_map(function($company) { return [ 'id' => $company['id'], 'text' => $company['name'] ]; }, $data['company'])); ?>; var pageSize = 50; jQuery.fn.select2.amd.require(["select2/data/array", "select2/utils"], function (ArrayData, Utils) { function CustomData($element, options) { CustomData.__super__.constructor.call(this, $element, options); } Utils.Extend(CustomData, ArrayData); CustomData.prototype.query = function (params, callback) { console.log(params) var results = []; if (params.term && params.term !== '') { results = items.filter(e => e.text.toUpperCase().includes(params.term.toUpperCase())); } else { results = items; } if (!("page" in params)) { params.page = 1; } var data = { results: results.slice((params.page - 1) * pageSize, params.page * pageSize), pagination: { more: params.page * pageSize < results.length } }; callback(data); }; $(document).ready(function () { $('#modal-schedule').on('shown.bs.modal',function(){ $(".normal").select2({ ajax: {}, dataAdapter: CustomData, width: '100%', minimumInputLength: 1, tags: false, }); }) $('#modal-schedule').on('hidden.bs.modal', function() { $('.normal').select2('destroy'); }); }); }); })
问题原因及修复方案
核心原因
Bootstrap模态框默认启用焦点陷阱机制,会拦截内部元素的焦点获取;同时模态框的z-index层级高于Select2下拉菜单,导致搜索输入框无法正常交互。
具体修复步骤
1. 添加CSS调整层级与交互权限
在页面样式中添加以下代码,确保Select2组件在模态框内的层级和交互正常:
/* 确保Select2下拉菜单层级高于模态框 */ .select2-dropdown { z-index: 99999 !important; } /* 允许模态框内Select2搜索框获取焦点 */ .modal .select2-search__field { pointer-events: auto; }
2. 优化Select2初始化逻辑
修改JavaScript代码,解决元素选择范围、下拉菜单挂载位置等问题:
$(function(){ var items = <?php echo json_encode(array_map(function($company) { return [ 'id' => $company['id'], 'text' => $company['name'] ]; }, $data['company'])); ?>; var pageSize = 50; jQuery.fn.select2.amd.require(["select2/data/array", "select2/utils"], function (ArrayData, Utils) { function CustomData($element, options) { CustomData.__super__.constructor.call(this, $element, options); } Utils.Extend(CustomData, ArrayData); CustomData.prototype.query = function (params, callback) { var results = []; if (params.term && params.term !== '') { results = items.filter(e => e.text.toUpperCase().includes(params.term.toUpperCase())); } else { results = items; } if (!("page" in params)) { params.page = 1; } var data = { results: results.slice((params.page - 1) * pageSize, params.page * pageSize), pagination: { more: params.page * pageSize < results.length } }; callback(data); }; // 绑定模态框显示事件,仅初始化当前模态框内的select元素 $('#modal-schedule').on('shown.bs.modal', function(){ $(this).find(".normal").select2({ dataAdapter: CustomData, width: '100%', minimumInputLength: 1, tags: false, // 指定下拉菜单挂载到模态框内部,避免层级问题 dropdownParent: $(this) }); }) $('#modal-schedule').on('hidden.bs.modal', function() { // 仅销毁当前模态框内的Select2实例 $(this).find('.normal').select2('destroy'); }); }); })
关键修改点说明
- 使用
$(this).find(".normal")上下文选择器:避免影响页面其他Select2组件,仅操作当前模态框内的元素 - 添加
dropdownParent: $(this)配置:将下拉菜单挂载到模态框内部,解决层级和滚动冲突 - 移除无用的
ajax: {}配置:自定义数据适配器不需要空的ajax配置
内容的提问来源于stack exchange,提问作者BlackRegal
相关产品推荐
相关产品推荐

