2012-06-14 47 views
12

Tôi đang sử dụng hộp kết hợp tự động hoàn thành jquery ui, và nó hoạt động rất tốt nhưng bây giờ tôi nhận được một chút tham lam. Tôi muốn có thể thêm các danh mục vào nó. Combobox được tạo ra của một thực đơn vì vậy nếu tôi thêm loại xem ví dụ bên dưới thẻ sẽ hiển thị như các loại đang trong jquery ui autocomplete categories versioncombobox jquery ui autocomplete với các loại

<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> 

Tôi tạo ra một http://jsfiddle.net/nH3b6/11/.

Cảm ơn mọi trợ giúp hoặc chỉ đường.

Trả lời

11

Mở rộng đề xuất của @ Jarry, tôi sẽ cập nhật mã của bạn để xác định những gì optgroup tùy chọn thuộc về. Từ đó, bạn có thể sử dụng mã tương tự như tìm thấy trên trang 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 = $("<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(); 
    }); 
}); 

Ví dụ:http://jsfiddle.net/gB32r/

+1

Điều này làm việc tuyệt vời. Cám ơn rất nhiều. –

+0

Xin chào, tôi đã tìm thấy một lỗi nhỏ là sản phẩm phụ của việc điều chỉnh mà bạn đã thực hiện. Nếu tôi thả danh sách xuống và chọn một trong các tùy chọn từ danh mục, nó sẽ hiển thị "Không có kết quả phù hợp". Nếu tôi chọn một tùy chọn không thuộc danh mục, nó hoạt động tốt. Tôi đã cố gắng tìm ra nó không có kết quả. –

+0

Nevermind đã tìm ra ... select.children ("optgroup"). Child ("option") mỗi (function() { –

2

như bạn có thể nhìn thấy trong jQueryUI docs, bạn phải tùy chỉnh widget để làm điều đó

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

này nó chưa được thử nghiệm, nhưng phải là một khởi đầu tốt đẹp:

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

nếu doesnt này công việc, có lẽ bạn nên gỡ lỗi để xem whats vào mảng items mà đến như là một tham số của _renderMenu.

lưu ý phụ: đây được gọi là MonkeyPatching, tôi sẽ không khuyên bạn nên thực hiện việc này nhiều, nhưng vì tài liệu hiển thị, id nói hãy làm điều đó.

+0

Cám ơn Trả lời tôi nếu tôi sai, nhưng bạn đang bắt đầu với mã từ phiên bản "category" của autoco mplete Tôi bắt đầu từ phiên bản "combobox". Vì vậy, mã ở trên sẽ không hoạt động. –

+0

bạn không sai. mã từ danh mục. im không chắc chắn nếu nó sẽ làm việc, và tôi không thể kiểm tra nó ngay bây giờ. tôi nghĩ rằng nó sẽ làm việc, bạn chỉ cần ghi đè (AKA monkeypatch) chức năng _renderMenu.tôi đặt cược rằng nó được gọi là mặc dù từ nơi các mặt hàng đến – Jarry

3

Có một vài tính năng với jquery 10 Tôi lấy combobox autocomplete từ trang web của jquery ui : http://jqueryui.com/autocomplete/#combobox và tham gia với câu trả lời của Andrew Whitaker.

(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

Tôi đang sử dụng tiện ích tự động hoàn thành jqueryui trên webapp của tôi, với hộp chú khỉ combobox, nhóm (danh mục) và khả năng tìm kiếm cũng trong tên danh mục. Thuật ngữ tìm kiếm cũng được nhấn mạnh bên trong tùy chọn tương thích và chọn nhóm. Tôi đã sử dụng một số câu trả lời từ stackoverflow và trang web jqueryui để có được đến thời điểm này, cảm ơn!

Tôi muốn giữ nó hoạt động trên phiên bản jqueryui cuối cùng. Jqueryui 1.9 và 1.11 giới thiệu các thay đổi đột phá (trong tự động hoàn thành và trình đơn plugin, mới nhất được sử dụng bởi trước đây) và cuối cùng tôi đã thành công trong việc làm cho nó hoạt động với phiên bản mới nhất của jqueryui (1.11.0) và jquery (2.1.1)

jsbin here

phần Chú ý: tùy chọn trình đơn thay đổi phụ tùng không coi là danh mục như liên kết menu bình thường thông qua lựa chọn các mặt hàng mới (vì vậy mới mà không bên trong doc nhưng trong jQueryUI nâng cấp dẫn đến 1,11

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

Điều này là hoàn hảo! Tôi đã do dự lúc đầu tiên sử dụng này, nhưng điều này thực sự làm việc và giải quyết vấn đề của tôi, cảm ơn rất nhiều! – NinaNa

Các vấn đề liên quan