jQuery Combobox 模糊搜索

介绍

在 Web 开发过程中,我们经常需要使用下拉框来选择选项。传统的下拉框只能在给定的选项中选择,但是有时候我们希望用户能够进行模糊搜索来快速找到所需的选项。jQuery Combobox 就是一个解决方案,它可以将一个普通的下拉框转换为具有模糊搜索功能的下拉框。

实现

要实现一个 jQuery Combobox,我们需要以下几个步骤:

1. 引入 jQuery 和 jQuery UI

首先,在 HTML 文档中引入 jQuery 和 jQuery UI 的库文件。可以通过以下代码进行引入:

<script src="
<link rel="stylesheet" href="
<script src="

2. 创建 HTML 结构

在 HTML 文档中创建一个普通的下拉框,并添加一个输入框用于模糊搜索。代码示例如下:

<input id="combobox-input">
<select id="combobox">
  <option value="option1">Option 1</option>
  <option value="option2">Option 2</option>
  <option value="option3">Option 3</option>
  <!-- 更多选项... -->
</select>

3. 初始化 Combobox

在 JavaScript 中,使用以下代码初始化 Combobox:

$(function() {
  $("#combobox").combobox();
});

4. 添加 Combobox 插件

要使用 Combobox 功能,需要添加一个 jQuery 插件。该插件可以将普通的下拉框转换为具有模糊搜索功能的下拉框。以下是一个简单的 Combobox 插件的示例代码:

(function($) {
  $.widget("custom.combobox", {
    _create: function() {
      this.wrapper = $("<span>")
        .addClass("custom-combobox")
        .insertAfter(this.element);

      this.element.hide();
      this._createAutocomplete();
      this._createShowAllButton();
    },

    _createAutocomplete: function() {
      var selected = this.element.children(":selected"),
        value = selected.val() ? selected.text() : "";

      this.input = $("<input>")
        .appendTo(this.wrapper)
        .val(value)
        .attr("title", "")
        .addClass("custom-combobox-input ui-widget ui-widget-content ui-state-default ui-corner-left")
        .autocomplete({
          delay: 0,
          minLength: 0,
          source: $.proxy(this, "_source")
        })
        .tooltip({
          classes: {
            "ui-tooltip": "ui-state-highlight"
          }
        });

      this._on(this.input, {
        autocompleteselect: function(event, ui) {
          ui.item.option.selected = true;
          this._trigger("select", event, {
            item: ui.item.option
          });
        },

        autocompletechange: "_removeIfInvalid"
      });
    },

    _createShowAllButton: function() {
      var input = this.input,
        wasOpen = false;

      $("<a>")
        .attr("tabIndex", -1)
        .attr("title", "Show All Items")
        .tooltip()
        .appendTo(this.wrapper)
        .button({
          icons: {
            primary: "ui-icon-triangle-1-s"
          },
          text: false
        })
        .removeClass("ui-corner-all")
        .addClass("custom-combobox-toggle ui-corner-right")
        .on("mousedown", function() {
          wasOpen = input.autocomplete("widget").is(":visible");
        })
        .on("click", function() {
          input.trigger("focus");

          // Close if already visible
          if (wasOpen) {
            return;
          }

          // Pass empty string as value to search for, displaying all results
          input.autocomplete("search", "");
        });
    },

    _source: function(request, response) {
      var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
      response(this.element.children("option").map(function() {
        var text = $(this).text();
        if (this.value && (!request.term || matcher.test(text)))
          return {
            label: text,
            value: text,
            option: this
          };
      }));
    },

    _removeIfInvalid: function(event, ui) {

      // Selected an item, nothing to do
      if (ui.item) {
        return;
      }

      // Search for a match (case-insensitive)
      var value = this.input.val(),
        valueLowerCase = value.toLowerCase(),
        valid = false;
      this.element.children("option