如何以编程方式将搜索查询注入 Select2 v4?

Posted

技术标签:

【中文标题】如何以编程方式将搜索查询注入 Select2 v4?【英文标题】:How to programmatically inject search queries into Select2 v4? 【发布时间】:2015-08-11 14:02:41 【问题描述】:

我使用 Select2 搜索框构建了一个网络应用程序,它通过 AJAX 连接到我们的后端。搜索框将查询(比如“APPLES”)传递到后端,然后更新页面。如何以编程方式将搜索查询注入搜索框?我需要传入“val”,以便 select2 通过 AJAX 调用后端并更新页面。我确定这很明显,但我在文档中找不到。

例如,我不希望用户在搜索框中输入“APPLES”,而是希望用户单击一个按钮并将“APPLES”一词自动填充到搜索字段中,然后更新页面.

谢谢!


根据 Kevin 的评论,我没有处于文本嵌入到搜索框中并且选择器选择了正确项目的状态。我如何提交(或触发)这个请求,我尝试了“keydown”、“pressdown”、“submit”、“click”(清除框)等。

【问题讨论】:

顺便说一句,赏金是不可能的,因为如果不挂钩到全局 AJAX 处理程序,就无法检测触发的 AJAX 请求何时完成。 只是为了确认,没有办法强制点击? 不管怎样,我很感激你的帮助,赏金是你的。 可以通过模拟mouseup 事件来强制选择结果(或者如果您有信息,只需注入<option>),但您不能预测(准确)结果列表何时显示结果。 【参考方案1】:

Select2 曾经提供一个 select2('search', 'term') 辅助方法来帮助解决这个问题,但它没有被带到 Select2 4.0.0。

有几种方法可以做到这一点,但总的来说,它们都遵循相同的步骤模式

    打开 Select2 下拉菜单 在搜索框中输入搜索文本 触发 Select2 开始搜索所需的键盘事件(通常为 input

所以,现在,在 Select2 4.0.0 中执行此操作的代码如下所示

$('select').select2();

function select2_search ($el, term) 
  $el.select2('open');
  
  // Get the search box within the dropdown or the selection
  // Dropdown = single, Selection = multiple
  var $search = $el.data('select2').dropdown.$search || $el.data('select2').selection.$search;
  // This is undocumented and may change in the future
  
  $search.val(term);
  $search.trigger('keyup');


$('button').on('click', function () 
  var $select = $($(this).data('target'));
  select2_search($select, 'Arizona');
);
<link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.css" rel="stylesheet"/>

<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.js"></script>

<select style="width: 200px;" id="single">
  <option value="AL">Alabama</option>
  <option value="AK">Alaska</option>
  <option value="AZ">Arizona</option>
</select>

<button type="button" data-target="#single">Search for 'Arizona'</button>
<br /><br />

<select style="width: 200px;" id="multiple" multiple="multiple">
  <option value="AL">Alabama</option>
  <option value="AK">Alaska</option>
  <option value="AZ">Arizona</option>
</select>

<button type="button" data-target="#multiple">Search for 'Arizona'</button>

虽然此示例不使用 AJAX,但如果为其配置了 Select2,它将触发 AJAX 请求。

【讨论】:

感谢凯文的回复。不幸的是,在 $e1.data('select2').dropdown 之后我没有看到 $search 变量。我也在进行 AJAX 调用,所以 select2 直到 AJAX 请求之后才看到所有的 id。我已经为此工作了几天,希望您能澄清一下。谢谢 我应该补充一点,我有两个搜索框,只有一个使用 AJAX。非 ajax select2 框通过 $selectionBox.val(23).change('trigger') 无缝处理注入。我猜 AJAX 版本失败了,因为它没有 ID。当我运行此函数 $selectionBoxAJAX.val(47).change('trigger') 时,会推送更新(屏幕更新)但查询为空,并且正确的文本没有得到更新 谢谢凯文,快到了!文本现在位于选择框中并在下拉菜单中突出显示,提交它的“触发器”是什么? 这还不完整,之后如何模拟 ENTER 以便下拉菜单接受输入的字符串并关闭? 我可以用 $('.select2-results__option[aria-selected]') .trigger("mouseup"); 模拟 ENTER;【参考方案2】:

对我来说,触发“keyup”仅在用户尚未选择任何选项时才有效。每次都有效的是触发“输入”。 (仅在 Chrome 上测试)

所以基于凯文布朗的回答:

$('select').select2();

function select2_search ($el, term) 
  $el.select2('open');

  // Get the search box within the dropdown or the selection
  // Dropdown = single, Selection = multiple
  var $search = $el.data('select2').dropdown.$search || $el.data('select2').selection.$search;
  // This is undocumented and may change in the future

  $search.val(term);
  $search.trigger('input');


$('button').on('click', function () 
  var $select = $($(this).data('target'));
  select2_search($select, 'Arizona');
);

【讨论】:

【参考方案3】:

这个页面上的答案让我几乎到了那里。因为其他人似乎也有同样的问题,所以我分享了我是如何解决它的。

Kevin Browns 回答中的一些 cmets 询问如何在输入文本并突出显示后模拟 ENTER。

我设法做到了只有超时:

setTimeout(function()  $('.select2-results__option').trigger("mouseup"); , 500);

所以,完整的解决方案是这样的:

$('select').select2();

function select2_search ($el, term) 
  $el.select2('open');

  // Get the search box within the dropdown or the selection
  // Dropdown = single, Selection = multiple
  var $search = $el.data('select2').dropdown.$search || $el.data('select2').selection.$search;
  // This is undocumented and may change in the future

  $search.val(term);
  $search.trigger('input');
  setTimeout(function()  $('.select2-results__option').trigger("mouseup"); , 500);



$('button').on('click', function () 
  var $select = $($(this).data('target'));
  select2_search($select, 'Arizona');
);

【讨论】:

【参考方案4】:

您可以将minimumInputLength 设置为0,然后在data 函数中检查params.term length,如果是0,请将过滤器值设置为您预定义的搜索值。

这很愚蠢,但它有效;)

【讨论】:

这就是我要找的!感谢“minimumInputLength:0”的建议。我的任务是使用 ajax 调用预先填充一些初始数据的 select2。所以我需要做的就是将最小输入设置为 0,并在服务器上过滤掉带有空 GET 参数“q=”的请求并返回默认值。太棒了!【参考方案5】:

作为对这个答案的补充,我们试图以编程方式将一个新的“标签”添加到配置为标签的 select2 中。我们必须执行以下操作,而不是在 $search 框上触发 keyup 事件。

$search.val(tag);
$search.closest('.select2-search--inline')
    .trigger($.Event('input',  which: 13 ));
$search.closest('.select2-selection--multiple')
    .trigger($.Event('keydown',  which: 13 ));

这首先触发一个事件,导致 select2 中的“搜索”模块添加一个包含标签文本的“突出显示”结果,然后第二个事件导致 select2 在内部触发“选择”事件,从而将新标签添加到select2 选项,也可能触发其他内容,具体取决于您的配置方式。

【讨论】:

出于安全原因,自 2019 年起,浏览器阻止了关键事件触发器【参考方案6】:

对于那些使用 Ajax 调用来填充 select2 并希望搜索和设置选定值的人。

您还有其他方法,但这个答案对我来说非常适合 Select2 4.0.0

为了打击设置,我使用了 deley 函数

JS

$('.select2').select2();

    function select2_search_and_set(controlId, term) 
var control = $("#" + controlId);
var $search = control.data('select2').dropdown.$search || control.data('select2').selection.$search;

$search.val(term);
$search.trigger('keyup');

setTimeout(function () 
    $search.trigger($.Event('keydown',  which: 13 ));
, 500);


   select2_search_and_set("target", 'term');

HTML

<select class="form-control select2" id="target" name="target"></select>

【讨论】:

【参考方案7】:

我一直在发疯,直到我来到这个线程。我想要一个 select2 对话框,用户可以在其中输入一个可能不是选项之一但我仍然可以设置它并且可见的名称。

借助此处的答案组合,我设法解决了我的问题。

为此:

    我首先需要将 select2 上的 tags 选项设置为 true

    没有必要打开select2

    我需要将触发器从“keyup”更改为“input”

    我需要在最后添加以下行来模拟输入键 $('.select2-results__option').trigger("mouseup");

     Here is the jsfiddle sample for you to try for yourself
    

    https://jsfiddle.net/jainpankaj/o8g37wfu/8/#&togetherjs=I0e96aNexC

【讨论】:

以上是关于如何以编程方式将搜索查询注入 Select2 v4?的主要内容,如果未能解决你的问题,请参考以下文章

Select2 v4.0 - 选择多个值

在 react-router V4 中,如何以编程方式设置查询字符串参数?

以编程方式设置 Select2 ajax 的值

不使用 jQuery 以编程方式控制 Select2

不使用jQuery以编程方式控制Select2

如何以编程方式更改 select2 值