2012-06-14 4 views
12

Я использую jquery ui autocomplete combobox, и он отлично работает, но теперь я становлюсь немного жадным. Я хотел бы иметь возможность добавлять к нему категории. Выпадающий генерируется прочь меню, так что если я добавил категории см ниже пример тега будет отображаться как категории находятся в jquery ui autocomplete categories versionjquery ui autocomplete combobox с категориями

<select> 
<optgroup name="Cat 1">  
<option value="1a">One A</option> 
<option value="1b">One B</option> 
<option value="1c">One C</option> 
</optgroup> 
<optgroup name="Cat 2">  
<option value="2a">Two A</option> 
<option value="2b">Two B</option> 
<option value="2c">Two C</option> 
</optgroup> 
</select> 

Я создал http://jsfiddle.net/nH3b6/11/.

Спасибо за любую помощь или руководство.

ответ

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 = $("<span>").addClass("ui-combobox").insertAfter(select); 

      input = $("<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"), "<strong>$1</strong>"), 
          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 $("<li></li>").data("item.autocomplete", item).append("<a>" + item.label + "</a>").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("<li class='ui-autocomplete-category'>" + item.category + "</li>"); 
         } 
         currentCategory = item.category; 
        } 
        self._renderItem(ul, item); 
       }); 
      }; 

      $("<a>").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/

+1

Это отлично работает. Спасибо. –

+0

Эй, поэтому я нашел небольшую ошибку в качестве побочного продукта вашей корректировки. Если я выпадаю из списка и выбираю один из вариантов из категории, он отображает «Нет совпадений». Если я выберу вариант, который не под категорией, он отлично работает. Я попытался понять это безрезультатно. –

+0

Ничего не выдумал ... select.children («optgroup»). Children («option»). Each (function() { –

2

, как вы можете видеть в jQueryUI docs, вы должны настроить виджет, чтобы сделать это

_renderMenu: function(ul, items) { 
      var self = this, 
       currentCategory = ""; 
      $.each(items, function(index, item) { 
       if (item.category != currentCategory) { 
        ul.append("<li class='ui-autocomplete-category'>" + item.category + "</li>"); 
        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("<li class='ui-autocomplete-category'>" + item.parent.attr('label') + "</li>"); 
        currentCategory = item.parent.attr('label'); 
       } 
       self._renderItem(ul, item); 
      }); 
     } 

если это оленья кожа работа, возможно, вам следует отлаживать, чтобы увидеть, что находится в массиве items, который поставляется как параметр _renderMenu.

сторона примечание: это называется MonkeyPatching, я бы не рекомендовал делать это много, но, поскольку документы показывают это, я говорю, сделайте это.

+0

Спасибо за ответ. Исправьте меня, если я ошибаюсь, но вы начинаете с кода из «категории» версии autoco mplete Я начинаю с версии «combobox». Таким образом, код выше не будет работать. –

+0

вы не ошибаетесь. код из категории. Я не уверен, что это сработает, и я не могу проверить его прямо сейчас. я думаю, что это сработает, вам просто нужно переопределить (AKA monkeypatch) функцию _renderMenu.я уверен, что его называют, несмотря на то, что товары приходят – Jarry

3

Существует несколько функций с JQuery 10. Я принимаю автозаполнения выпадающий с веб-сайта Jquery UI : http://jqueryui.com/autocomplete/#combobox и присоединитесь к нему с ответом Андрея Уайтакера.

(function($) { 
$.widget("custom.combobox_with_optgroup", { 
    _create: function() { 
     this.wrapper = $("<span>") 
      .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 = $("<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("<li class='custom-autocomplete-category'>" + item.category + "</li>"); 
        } 
        currentCategory = item.category; 
       } 
       self._renderItemData(ul, item); 
      }); 
     }; 
    }, 
    _createShowAllButton: function() { 
     var input = this.input, 
      wasOpen = false; 
     $("<a>") 
      .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); 
1

I'am использованием jqueryui автозаполнения виджет на моем веб-приложение, с выпадающий обезьяны заплат, OPTGROUP (категории) и способность Seach также в именах категорий. Термин seach также подчеркивается внутри совместимого варианта и optgroup. Я использовал несколько ответов из stackoverflow и jqueryui веб-сайта, чтобы добраться до этого момента, спасибо!

Мне нравится, чтобы он работал над последней версией jqueryui. Jqueryui 1.9 и 1.11 внесли изменения в изменение (в автозаполнение и плагин меню, последний из которых используется первым), и мне, наконец, удалось заставить его работать с последней версией jqueryui (1.11.0) и jquery (2.1.1)

jsbin here

Важных часть: варианты меню изменения виджета, чтобы не рассмотреть категории, как обычная ссылка меню с помощью новой опции пунктов (так новая, что не внутри документа, но в jqueryui обновить руководство по 1,11

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

Это прекрасно! Сначала я колебался, чтобы использовать это, но это действительно сработало и решило мою проблему, спасибо большое! – NinaNa

Смежные вопросы