jQuery组合框/选择框自动完成?

29

是否存在一个jQuery插件来替换选择框/组合框?

我试过SexyCombo,它接近我想要的,但如果你从中间开始输入,它就不能自动完成了。

我有两个级别的类别(20个顶级类别和120个子类别),所以当用户提交条目时,他必须尽快找到所需的类别。

因此... 2个级别+自动完成即使您在中间写字也可以填充文本。

或者还有其他解决方案吗?

5个回答

46

11
这正是我喜欢 Stackoverflow 的原因。谢谢! - palmic
1
@Lance May,感谢您的回复。正如您在此页面http://jqueryui.com/demos/autocomplete/#combobox中所说的那样,我想要相同的组合框。但是当用户单击“向下箭头”时,它应该从远程位置加载所有数据,并且当用户在“文本字段”区域中键入单词时,它应该根据该条件加载相关数据。最后,我的要求是组合框应该显示为与组合框相同。不是一个文本字段。如果我提出了任何不可能或不寻常的要求,请忽略并让我知道。 - vissu
1
@Vissu,我认为你需要的是一个下拉框式的解决方案,数据源是远程位置,并且没有最小搜索条件。当你移除这个两个字符(我相信这是它们的默认值)的搜索障碍时,然后在箭头向下点击时调用搜索,你实际上只是在 "" 上进行了“搜索”,所有结果都应该返回,然后你可以使用输入的 .val() 进行文本输入过滤。如果我错过了真正的问题,请原谅。 - Lance
这很好用,谢谢。 不过有一个问题 - $('#combobox').change(function () {..} 已经不起作用了。我该如何合并? - Avi Kehat
要添加“onChange”功能,请参见:https://dev59.com/CW445IYBdhLWcg3wpL5_#18428586 - Avi Kehat
显示剩余3条评论

31

[编辑] 我注意到了可爱的chosen jQuery插件,看起来是一个很好的替代品。

或者如果你只想使用jQuery自动完成,我已经扩展了combobox示例来支持默认值并删除工具提示,以达到我认为更符合预期的行为。试一下

(function ($) {
    $.widget("ui.combobox", {
        _create: function () {
            var input,
              that = this,
              wasOpen = false,
              select = this.element.hide(),
              selected = select.children(":selected"),
              defaultValue = selected.text() || "",
              wrapper = this.wrapper = $("<span>")
                .addClass("ui-combobox")
                .insertAfter(select);

            function removeIfInvalid(element) {
                var value = $(element).val(),
                  matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex(value) + "$", "i"),
                  valid = false;
                select.children("option").each(function () {
                    if ($(this).text().match(matcher)) {
                        this.selected = valid = true;
                        return false;
                    }
                });

                if (!valid) {
                    // remove invalid value, as it didn't match anything
                    $(element).val(defaultValue);
                    select.val(defaultValue);
                    input.data("ui-autocomplete").term = "";
                }
            }

            input = $("<input>")
              .appendTo(wrapper)
              .val(defaultValue)
              .attr("title", "")
              .addClass("ui-state-default ui-combobox-input")
              .width(select.width())
              .autocomplete({
                  delay: 0,
                  minLength: 0,
                  autoFocus: true,
                  source: function (request, response) {
                      var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
                      response(select.children("option").map(function () {
                          var text = $(this).text();
                          if (this.value && (!request.term || matcher.test(text)))
                              return {
                                  label: text.replace(
                                    new RegExp(
                                      "(?![^&;]+;)(?!<[^<>]*)(" +
                                      $.ui.autocomplete.escapeRegex(request.term) +
                                      ")(?![^<>]*>)(?![^&;]+;)", "gi"
                                    ), "<strong>$1</strong>"),
                                  value: text,
                                  option: this
                              };
                      }));
                  },
                  select: function (event, ui) {
                      ui.item.option.selected = true;
                      that._trigger("selected", event, {
                          item: ui.item.option
                      });
                  },
                  change: function (event, ui) {
                      if (!ui.item) {
                          removeIfInvalid(this);
                      }
                  }
              })
              .addClass("ui-widget ui-widget-content ui-corner-left");

            input.data("ui-autocomplete")._renderItem = function (ul, item) {
                return $("<li>")
                  .append("<a>" + item.label + "</a>")
                  .appendTo(ul);
            };

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

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

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

        _destroy: function () {
            this.wrapper.remove();
            this.element.show();
        }
    });
})(jQuery);

jQuery官网上的那个不起作用,这个可以。谢谢。 - eggie5
这是页面上最好的。谢谢! - dotancohen
3
“Chosen”非常棒,谢谢! - peter
非常有用,谢谢。 - Ahmet Remzi EKMEKCI

4
我知道这之前已经有人提到过,但是jQuery Autocomplete会完全满足你的需求。你应该查看文档,因为自动完成很容易定制。如果你熟悉javascript,那么你应该能够解决这个问题。如果不熟悉,我可以给你一些指导,因为我以前做过一次,但是请注意,我自己对javascript也不是很精通,请耐心等待。
我认为你首先应该在页面上让一个简单的自动完成文本字段起作用,然后你可以从那里进行自定义。
自动完成小部件接受JSON数据作为其“source:”选项。因此,您应该设置您的应用程序以JSON格式生成20个顶级类别和子类别。
下一件要知道的事情是,当用户输入文本字段时,自动完成小部件将在名为“term”的参数中发送键入的值。
所以,假设您首先设置您的网站从此URL传递JSON数据:
/categories.json

那么您的自动完成源选项将是 'source: /categories.json'。

当用户在文本框中输入,例如 'first-cata...',自动完成小部件将开始发送'term'参数中的值,如下所示:

/categories.json?term=first-cata

这将返回JSON数据到小部件,过滤任何与“first-cata”匹配的内容,并显示为自动完成建议。
我不确定你在编程什么,但你可以指定“term”参数如何找到匹配项。因此,如果您想要,可以自定义此内容,以便单词中间的术语找到匹配项。例如,如果用户键入“or”,您的代码可以在“sports”上进行匹配。
最后,您提到您希望能够选择类别名称,但自动完成小部件提交类别ID而不是名称。
这可以通过隐藏字段轻松完成。这就是jQuery自动完成文档中显示的内容。
当用户选择类别时,您的JavaScript应该使用ID更新隐藏字段。
我知道这个答案不是很详细,但这主要是因为我不确定你正在编程什么,但以上内容应该指引你走向正确的方向。需要知道的是,如果你愿意花时间学习它,你可以对这个小部件进行几乎任何自定义。
这些是大体的概述,但你可以在这里查看我在Rails应用程序中实现类似于你想要的东西时所做的一些笔记。
希望这会有所帮助。

3

这对我来说非常有效,通过修改jQuery示例,我可以更多地实现功能,减少编写代码的时间。

我在页面上定义了选择对象,就像jQuery示例一样。我将文本推送到数组中,然后使用该数组作为我的输入自动完成源。完成了。

$(function() {
   var mySource = [];
   $("#mySelect").children("option").map(function() {
      mySource.push($(this).text());
   });

   $("#myInput").autocomplete({
      source: mySource,
      minLength: 3
   });
}

1

jQuery 1.8.1中有一个自动完成的示例。它非常容易实现。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接