jquery ui combobox autocomplete avec des catégories

J’utilise la combobox jquery ui autocomplete, et cela fonctionne très bien, mais maintenant, je suis un peu gourmand. J’aimerais pouvoir y append des catégories. La liste déroulante est générée à partir d’un menu. Par conséquent, si j’ajoutais des catégories, voir l’exemple ci-dessous, la balise s’afficherait comme si les catégories se trouvaient dans la version des catégories jquery ui autocomplete

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

J’ai créé un http://jsfiddle.net/nH3b6/11/ .

Merci pour toute aide ou direction.

optgroup le optgroup la optgroup , je voudrais mettre à jour votre code pour déterminer le groupe optgroup l’option appartient. À partir de là, vous pouvez utiliser un code similaire à celui trouvé sur le site Web 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._sortinggger("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-sortingangle-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 ssortingng 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(); }); });

    Exemple: http://jsfiddle.net/gB32r/

    Jquery présente quelques fonctionnalités. Je prends la liste déroulante autocomplete du site Web de jquery ui: http://jqueryui.com/autocomplete/#combobox et la joins à la réponse de 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._sortinggger( "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-sortingangle-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 );

    comme vous pouvez le voir dans la documentation jQueryUI , vous devez personnaliser le widget pour le faire.

     _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 ); }); }

    ceci n’est pas testé, mais devrait être un bon début:

     _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 ); }); }

    si cela ne fonctionne pas, vous devriez peut-être déboguer pour voir ce qui se trouve dans le tableau items qui vient en tant que paramètre de _renderMenu.

    une note de côté: cela s’appelle MonkeyPatching , je ne recommanderais pas cela beaucoup, mais puisque la documentation l’indique, c’est ce que je veux dire.

    J’utilise le widget jqueryui autocomplete sur mon application Web, avec les correctifs combobox monkey, optgroup (catégories) et la possibilité de rechercher également des noms de catégories. Le terme recherche est également mis en évidence dans les options compatibles et optgroup. J’ai utilisé plusieurs réponses de stackoverflow et du site Web jqueryui pour en arriver à ce point, merci!

    J’aime que cela fonctionne sur la dernière version de jqueryui. Jqueryui 1.9 et 1.11 ont introduit des changements de dernière minute (en mode autocomplete et menu plugin, le dernier utilisé par l’ancien) et j’ai finalement réussi à le faire fonctionner avec la dernière version de jqueryui (1.11.0) et jquery (2.1.1)

    jsbin ici

    Partie importante: changez les options du widget de menu pour ne pas considérer les catégories comme des liens de menu normaux via une option de nouvel élément (donc nouveau, pas dans la documentation, mais dans le guide de mise à niveau jqueryui vers la version 1.11).

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