jquery ui自动完成combobox与类别

我正在使用jquery ui autocompletecombobox,它工作得很好,但现在我有点贪心了。 我希望能够为其添加类别。 combobox是从菜单生成的,所以如果我添加了类别,请参阅下面的示例,标签将显示类似于jquery ui自动完成类别版本中的类别

  One A One B One C   Two A Two B Two C   

我创建了一个http://jsfiddle.net/nH3b6/11/ 。

感谢您的帮助或指导。

扩展@ Jarry的建议,我会更新您的代码以确定该选项属于哪个optgroup 。 从那里,您可以使用jQueryUI网站上的类似代码:

 (function($) { $.widget("ui.combobox", { _create: function() { var input, self = this, select = this.element.hide(), selected = select.children(":selected"), value = selected.val() ? selected.text() : "", wrapper = this.wrapper = $("").addClass("ui-combobox").insertAfter(select); input = $("").appendTo(wrapper).val(value).addClass("ui-state-default ui-combobox-input").autocomplete({ delay: 0, minLength: 0, source: function(request, response) { var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i"); response(select.find("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"), "$1"), value: text, option: this, category: $(this).closest("optgroup").attr("label") }; //MK $('#test').attr('style', 'display: none;'); }).get()); }, select: function(event, ui) { ui.item.option.selected = true; self._trigger("selected", event, { item: ui.item.option }); }, change: function(event, ui) { if (!ui.item) { var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex($(this).val()) + "$", "i"), valid = false; select.children("option").each(function() { if ($(this).text().match(matcher)) { this.selected = valid = true; return false; } }); if (!valid) { $('#test').attr('style', 'display: block;'); // remove invalid value, as it didn't match anything //$( this ).val( "" ); //select.val( "" ); //input.data( "autocomplete" ).term = ""; //return false; } } } }).addClass("ui-widget ui-widget-content ui-corner-left"); input.data("autocomplete")._renderItem = function(ul, item) { return $("
  • ").data("item.autocomplete", item).append("" + item.label + "").appendTo(ul); }; input.data("autocomplete")._renderMenu = function(ul, items) { var self = this, currentCategory = ""; $.each(items, function(index, item) { if (item.category != currentCategory) { if (item.category) { ul.append("
  • " + item.category + "
  • "); } currentCategory = item.category; } self._renderItem(ul, item); }); }; $("").attr("tabIndex", -1).attr("title", "Show All Items").appendTo(wrapper).button({ icons: { primary: "ui-icon-triangle-1-s" }, text: false }).removeClass("ui-corner-all").addClass("ui-corner-right ui-combobox-toggle").click(function() { // close if already visible if (input.autocomplete("widget").is(":visible")) { input.autocomplete("close"); return; } // work around a bug (likely same cause as #5265) $(this).blur(); // pass empty string as value to search for, displaying all results input.autocomplete("search", ""); input.focus(); }); }, destroy: function() { this.wrapper.remove(); this.element.show(); $.Widget.prototype.destroy.call(this); } }); })(jQuery); $(function() { $("#combobox").combobox(); $("#toggle").click(function() { $("#combobox").toggle(); }); });

    示例: http //jsfiddle.net/gB32r/

    jquery 10有一些function。我从jquery ui的网站上获取autocompletecombobox: http : //jqueryui.com/autocomplete/#combobox并加入Andrew Whitaker的答案。

     (function( $ ) { $.widget( "custom.combobox_with_optgroup", { _create: function() { this.wrapper = $( "" ) .addClass( "custom-combobox" ) .insertAfter( this.element ); this.element.hide(); this._createAutocomplete(); this._createShowAllButton(); }, _createAutocomplete: function() { var selected = this.element.find( ":selected" ), value = selected.val() ? selected.text() : ""; this.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({ tooltipClass: "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" }); this.input.data("uiAutocomplete")._renderMenu = function(ul, items) { var self = this, currentCategory = ""; $.each(items, function(index, item) { if (item.category != currentCategory) { if (item.category) { ul.append("
  • " + item.category + "
  • "); } currentCategory = item.category; } self._renderItemData(ul, item); }); }; }, _createShowAllButton: function() { var input = this.input, wasOpen = false; $( "" ) .attr( "tabIndex", -1 ) .attr( "title", "Показать все" ) .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" ) .mousedown(function() { wasOpen = input.autocomplete( "widget" ).is( ":visible" ); }) .click(function() { input.focus(); if ( wasOpen ) { return; } input.autocomplete( "search", "" ); }); }, _source: function( request, response ) { var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" ); response( this.element.find( "option" ).map(function() { var text = $( this ).text(); if ( this.value && ( !request.term || matcher.test(text) ) ) return { label: text, value: text, option: this, category: $(this).closest("optgroup").attr("label") }; }) ); }, _removeIfInvalid: function( event, ui ) { if ( ui.item ) { return; } var value = this.input.val(), valueLowerCase = value.toLowerCase(), valid = false; this.element.find( "option" ).each(function() { if ( $( this ).text().toLowerCase() === valueLowerCase ) { this.selected = valid = true; return false; } }); if ( valid ) { return; } this.input .val( "" ) .attr( "title", value + " не существует" ) .tooltip( "open" ); this.element.val( "" ); this._delay(function() { this.input.tooltip( "close" ).attr( "title", "" ); }, 2500 ); this.input.data( "ui-autocomplete" ).term = ""; }, _destroy: function() { this.wrapper.remove(); this.element.show(); } }); })( jQuery );

    正如您在jQueryUI文档中看到的那样 ,您必须自定义窗口小部件才能执行此操作

     _renderMenu: function( ul, items ) { var self = this, currentCategory = ""; $.each( items, function( index, item ) { if ( item.category != currentCategory ) { ul.append( "
  • " + item.category + "
  • " ); currentCategory = item.category; } self._renderItem( ul, item ); }); }

    这没有经过测试,但应该是一个好的开始:

     _renderMenu: function( ul, items ) { var self = this, currentCategory = ""; $.each( items, function( index, item ) { if ( item.parent.attr('label') != currentCategory ) { ul.append( "
  • " + item.parent.attr('label') + "
  • " ); currentCategory = item.parent.attr('label'); } self._renderItem( ul, item ); }); }

    如果这不起作用,也许您应该调试以查看作为_renderMenu参数的items数组中的内容。

    旁注:这叫做MonkeyPatching ,我不建议这样做很多,但是自从文档显示它以后,id就说了。

    我在我的webapp上使用了jqueryui自动完成小部件,使用了combobox monkey补丁,optgroup(类别)以及在类别名称中搜索的能力。 在兼容选项和optgroup中也强调了搜索术语。 我使用stackoverflow和jqueryui网站的几个答案来达到这一点,谢谢!

    我喜欢让它继续使用最后一个版本的jqueryui。 Jqueryui 1.9和1.11引入了重大更改(在自动完成和菜单插件中,前者使用了最新的),我终于成功地使用最新版本的jqueryui(1.11.0)和jquery(2.1.1)

    jsbin在这里

    重要的一部分:更改菜单小部件选项,不要将类别视为通过新项目选项的正常菜单链接(所以新的不在文档内但在jqueryui升级指南1.11中

     $.extend($.ui.menu.prototype.options, { items: "> :not(.aureltime-autocomplete-category)" });