在不关闭下拉框的情况下清空Select2自动完成输入框
给Select2下拉搜索框添加一键清空按钮的解决方案
我懂你这种痛点——每次要重新搜索就得按半天退格键,太麻烦了。你之前尝试操作.select2-search--dropdown .select2-search__field没成功,还触发了下拉框关闭,主要是没处理好事件冒泡和搜索框的更新逻辑。我给你一套适配你现有多选Select2组件的方案,一步一步来:
实现思路
- 在Select2的搜索容器里插入一个Font Awesome的
×按钮作为清空按钮 - 给按钮添加点击事件:清空搜索框文本,触发搜索更新,同时阻止事件冒泡避免下拉框关闭
- 通过CSS控制按钮的定位和显示时机,让它只在下拉框打开时出现
具体代码修改
1. 添加清空按钮的CSS样式
在你的现有CSS里加上这段:
/* 搜索框清空按钮样式 */ .select2-search--dropdown { position: relative; } .select2-search__clear { position: absolute; right: 15px; top: 50%; transform: translateY(-50%); cursor: pointer; color: #999; display: none; /* 默认隐藏,下拉打开时显示 */ } .select2-search__clear:hover { color: #333; } /* 下拉框打开时显示清空按钮 */ .select2-dropdown--below.select2-container--open .select2-search__clear, .select2-dropdown--above.select2-container--open .select2-search__clear { display: inline-block; }
2. 修改JavaScript逻辑,插入按钮并绑定事件
在你的S2MultiCheckboxes初始化代码里,找到self.select2 = self.$element.select2({ ... }).data('select2');这一行,之后添加插入按钮和绑定事件的代码:
// 插入搜索清空按钮 function addClearButton() { // 避免重复添加按钮 if (self.select2.$dropdown.find('.select2-search__clear').length === 0) { const clearBtn = $('<span class="select2-search__clear"><i class="fa fa-times"></i></span>'); self.select2.$dropdown.find('.select2-search--dropdown').append(clearBtn); // 绑定清空事件 clearBtn.on('click', function(e) { e.stopPropagation(); // 阻止事件冒泡,避免下拉框关闭 const searchField = self.select2.$dropdown.find('.select2-search__field'); searchField.val(''); // 清空输入框 searchField.trigger('input'); // 触发输入事件,让Select2更新搜索结果 }); } } // 初始化时添加按钮 addClearButton(); // 监听下拉框打开事件,确保按钮存在 self.$element.on('select2:open', function() { addClearButton(); });
3. 完整整合后的代码
把这些修改整合到你的现有代码里,最终的完整代码如下:
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css"> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js"></script> <body class='bodyClass'> <div class="row"> <select id="SteelList" name="SteelList" class="form-control select2-multiple"> <option value="40">France</option> <option value="960">Spain</option> <option value="540">Italy</option> </select> </div> </body> <style> .bodyClass { min-height: 100vh; } .select2-results__option .wrap:before { font-family: fontAwesome; color: #999; content: "\f096"; width: 25px; height: 25px; padding-right: 10px; } .select2-results__option[aria-selected=true] .wrap:before { content: "\f14a"; } .select2-container--default .select2-search--dropdown .select2-search__field { border: 1px solid red; } .row { padding: 10px; } .select2-multiple, .select2-multiple2 { width: 50% } .select2-results__group .wrap:before { display: none; } /* 新增的清空按钮样式 */ .select2-search--dropdown { position: relative; } .select2-search__clear { position: absolute; right: 15px; top: 50%; transform: translateY(-50%); cursor: pointer; color: #999; display: none; } .select2-search__clear:hover { color: #333; } .select2-dropdown--below.select2-container--open .select2-search__clear, .select2-dropdown--above.select2-container--open .select2-search__clear { display: inline-block; } </style> <script> $(function() { var S2MultiCheckboxes = function(options, element) { var self = this; self.options = options; self.$element = $(element); var values = self.$element.val(); self.$element.removeAttr('multiple'); self.select2 = self.$element.select2({ allowClear: true, placeholder: options.placeholder, closeOnSelect: false, templateSelection: function() { return self.options.templateSelection(self.$element.val() || [], $('option', self.$element).length); }, templateResult: function(result) { if (result.loading !== undefined) return result.text; return $('<div>').text(result.text).addClass(self.options.wrapClass); } }).data('select2'); // 新增:添加搜索清空按钮逻辑 function addClearButton() { if (self.select2.$dropdown.find('.select2-search__clear').length === 0) { const clearBtn = $('<span class="select2-search__clear"><i class="fa fa-times"></i></span>'); self.select2.$dropdown.find('.select2-search--dropdown').append(clearBtn); clearBtn.on('click', function(e) { e.stopPropagation(); const searchField = self.select2.$dropdown.find('.select2-search__field'); searchField.val(''); searchField.trigger('input'); }); } } addClearButton(); self.$element.on('select2:open', addClearButton); self.select2.$results.off("mouseup").on("mouseup", ".select2-results__option[aria-selected]", (function(self) { return function(evt) { var $this = $(this); var data = $this.data('data'); if ($this.attr('aria-selected') === 'true') { self.trigger('unselect', { originalEvent: evt, data: data }); return; } self.trigger('select', { originalEvent: evt, data: data }); } })(self.select2)); self.$element.attr('multiple', 'multiple').val(values).trigger('change.select2'); } $.fn.extend({ select2MultiCheckboxes: function() { var options = $.extend({ placeholder: 'Choose elements', templateSelection: function(selected, total) { return selected.length + ' > ' + total + ' total'; }, wrapClass: 'wrap' }, arguments[0]); this.each(function() { new S2MultiCheckboxes(options, this); }); } }); }) $(function() { $('.select2-multiple').select2MultiCheckboxes({ closeOnSelect: true, templateSelection: function(selected, total) { return "Select Country - Selected " + selected.length + " of " + total; } }) }); </script>
关键注意点
- 阻止事件冒泡:按钮点击时调用
e.stopPropagation(),不然点击事件会传递给Select2的容器,导致下拉框直接关闭,这就是你之前遇到的问题。 - 触发输入事件:清空文本后要调用
trigger('input'),让Select2重新执行搜索逻辑,显示所有选项。 - 重复添加防护:通过判断按钮是否存在来避免每次下拉打开都重复插入按钮。
这样修改后,用户打开下拉框时,搜索框右边就会出现一个×按钮,点击就能一键清空搜索内容,下拉框也不会关闭,完美解决你的需求!
内容的提问来源于stack exchange,提问作者Silverburch
相关产品推荐
相关产品推荐

