jquery - 以编程方式添加新的 jquery-select2-4 选项并重置搜索字段?

标签 jquery jquery-select2-4 jquery-select2

我正在使用jquery-select2-4搜索外部数据库并向用户呈现可供选择的搜索结果。

我有一个运行在 this jsfiddle 上的工作版本.

但是,例如,如果仅返回 1 个搜索结果,我想跳过整个选择过程,而只需将返回的搜索结果添加到所选选项列表中。根据select2 docs我可以添加一个新选项,如下所示:

option = new Option("Sample text", "123", true, true);
select2_element.append(option);
select2_element.trigger('change');

这似乎在某种程度上有效。但也存在一些问题。

  • 添加选项后我无法清除搜索字段。
  • 除了 idtext 之外,我无法添加任何其他内容。
  • 添加的选项向用户显示为未定义

我意识到这个问题包含 3 个方面,但所有 3 个方面可能都指向这 1 个问题:

如何以编程方式添加新的 jquery-select2-4 选项并重置搜索字段?

供您引用,这是我要询问的代码的上下文:

var formatRepo, formatRepoSelection, selectRepos;

formatRepoSelection = function(element) {
  return element.name + ' ' + element.forks + ' ' + element.id;
};

formatRepo = function(element) {
  var markup;
  if (!element.loading) {
    return markup = element.name + ' ' + element.id;
  }
};

selectRepos = function() {
  var option, select2_element;
  select2_element = $('#select2_element');
  select2_element.select2({
    ajax: {
      url: "https://api.github.com/search/repositories",
      dataType: 'json',
      data: function (params) {
        return {
          q: params.term,
          page: params.page
        };
      },
      processResults: function (data, params) {

        if (data.items.length === 1) {
          // START: The code I am asking about.
          // Add the search result directly as an option.
          option = new Option("Sample text", "123", true, true);
          select2_element.append(option);
          return select2_element.trigger('change');
          // END: The code I am asking about.
        } else {
          params.page = params.page || 1;

          return {
            results: data.items,
            pagination: {
              more: (params.page * 30) < data.total_count
            }
          };
        }
      },
      cache: true
    },

    escapeMarkup: function(markup) {
      return markup;
    },
    templateResult: formatRepo,
    templateSelection: formatRepoSelection
  });
};

$(function() {
  return selectRepos();
});

最佳答案

我对原始代码做了两处更改:

1。模拟选择仅剩的一项

正如您所指出的,创建 option 元素有其局限性:您只能指定 idtext 属性,不能指定可以访问所选项目的其他属性。

此外,它还会生成未定义值。这是因为回调函数formatRepoSelection尝试访问为选项创建的对象未定义的属性(nameforks) 元素。在这种情况下,您可以尝试解决此问题并使用 text 属性,但您仍然无法解决上述限制。

我在这里建议的解决方案有不同的方法。您可以模拟用户对最后一项的选择,向该列表项发送 mouseup 事件,而不是直接创建标记。

这具有直接的优势,即应用正常的选择行为,就好像用户单击了该项目一样,因此它可以立即解决您遇到的所有三个问题:

  • 过滤文本会自动清除;
  • formatRepoSelection函数接收通常的对象,因此标签的标签符合预期;
  • 您可以使用与任何项目相同的属性。

这是实现此功能的代码:

    if (data.items.length === 1) {
      // Change 1:
      // Allow the list to update
      setTimeout(function() {
          // ... and then send a click event to the first list item
          // Note the used id has the SELECT id in the middle.
          $("#select2-select2_element-results li:first-child").trigger('mouseup');
      }, 0);

此解决方案的缺点是您使自己依赖于实现方面; select2 的 future 版本可能会根据 HTML 元素和属性以不同的方式组织结果。

但是,每当您决定使用较新版本的 select2 时,更新代码应该不是什么大问题。

2。返回正确的对象

您的代码在 select2 库中生成了错误:

TypeError: b is undefined, at select2.min.js:2:9842

这是因为以下声明:

return select2_element.trigger('change');

这将返回 jQuery select2_element 对象,但库期望返回值具有 results 属性。

由于不再需要触发器,因此可以通过将上面的内容替换为以下内容来解决此问题:

  // Change 2:
  // Return empty results array
  return {
    results: data.items
  };

不要试图设置结果:[],因为我们仍然需要该项目在那里模拟鼠标事件。

而且......仅此而已。

这是有效的解决方案:JS fiddle .

关于jquery - 以编程方式添加新的 jquery-select2-4 选项并重置搜索字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35112644/

相关文章:

javascript - Select2 initSelection 已弃用

jquery - 使用 select2 插件 (v4) 防止重新加载数据

javascript - 使用 select2 在悬停/鼠标悬停时激活选择菜单

javascript - 使用watcher在Vue条件渲染中选择2

asp.net - ASP.NET 按钮中的多色文本

jquery - 如何找到两个形状之间的最短路径?

JQuery - 将样式表应用于 Iframe(同一域)

javascript - 使用 sprite 对 jQuery slider 进行分页时遇到问题

javascript - select2 和 select2 full 有什么区别?

javascript - 使用 select2.js 选择文本的不同显示值