如何在页面上仅修补一个自动完成实例

时间:2012-01-09 18:52:42

标签: jquery jquery-ui jquery-autocomplete

记住这篇文章(How to patch *just one* instance of Autocomplete on a page?

我正在尝试做类似的事情,除非我想有条件地覆盖_renderMenu函数。基本上,我希望能够有一个maxResults属性,如果列表中的项目数超过该值,我想将列表截断为maxResults,并附加一个“超出最大结果”消息/项作为最后一项列表。

例如:

var self = this;
$.each( items, function(index, item) {
    var max = maxResults;  // here we define how many results to show

    if (index < max) {
      self._renderItem(ul, item);
    }
    else if (index == max) {
      var message = "<span class='auto-complete-max-results'>" + 
        items.length + " results - Add more characters to refine results" +
        "</span>";

      return $( "<li></li>" )
          .data( "item.autocomplete", item )
          .append( message )
          .appendTo( ul );
    }
  });

我遇到的主要问题之一是如何有条件地覆盖方法和/或如果我总是覆盖它,我可以调用超级impl吗?

1 个答案:

答案 0 :(得分:1)

以下是我解决这个问题的方法。在自动完成字段初始化期间,我执行以下操作:

$(fieldId).autocomplete({
    ...
  }).data('maxResults', maxResults);

然后我这样做:

var defaultRenderMenu = $.ui.autocomplete.prototype._renderMenu;

$.ui.autocomplete.prototype._renderMenu = function(ul, items) {

  var autoField = this.element;  
  var max = autoField.data('maxResults');
  var numResults = items.length;

  // if maxResults is defined and the number of results exceeds the max, we want to trim the list
  if (max != null && numResults > max) {
    var self = this;

    $.each( items, function(index, item) {
      // render all items less than the max normally
      if (index < max) {
        self._renderItem(ul, item);
      }
      else if (index == max) {
        var message = "<span class='auto-complete-max-results'>" + 
          "*** " + items.length + " results - Add more characters to refine results ***" +
          "</span>";

        return $("<li></li>")
            .data("item.autocomplete", item)
            .append(message)
            .appendTo(ul);
      }
      else {
        return false;  // break out of loop after max
      }
    });
  }
  // otherwise, use the default implementation of renderMenu
  else {
    defaultRenderMenu.apply(this, [ul, items]);
  }
};