0

With this post in mind (How to patch *just one* instance of Autocomplete on a page?)

I'm trying to do something similar except I want to conditionally override the _renderMenu function. Basically, I want to be able to have a maxResults attribute and if the number of items in the list exceeds that value, I want to truncate the list to maxResults and append a 'Max results exceeded' message/item as the last item in the list.

For example:

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

One of the main issues I'm having is how to conditionally override the method and/or if I always override it, can I call the super impl?

Community
  • 1
  • 1
fmpdmb
  • 1,370
  • 3
  • 21
  • 34

1 Answers1

1

Here's how I solved this. During autocomplete field initialization, I do the following:

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

Then I do this:

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]);
  }
};
fmpdmb
  • 1,370
  • 3
  • 21
  • 34