Writing a better alternative to jQuery Autocomplete Over the last months I have been writing a jQuery plugin called Better Autocomplete (Code on Github). It originated from another project, a Drupal module called Linkit, but I decided it should be a standalone plugin. I have spent a lot of time refactoring the code, mainly to make it more generic and flexible for multiple purposes. I have now reached a point where it makes sense to actually ask for advice on the code, hopefully by professional, more experienced JavaScript developers.

EDIT: I read in the FAQ that I'm supposed to include some of the code. This is a shorter version of the code, describing the structure of the code. There is also documentation available.

(function ($) {

$.fn.betterAutocomplete = function(method) {

  var methods = {
    init: function(resource, options, callbacks) {
      var $input = $(this),
        bac = new BetterAutocomplete($input, resource, options, callbacks);
      $input.data('better-autocomplete', bac);
      bac.enable();
    },
    enable: function(bac) {
      bac.enable();
    },
    disable: function(bac) {
      bac.disable();
    },
    destroy: function(bac) {
      bac.destroy();
    }
  };

  var args = Array.prototype.slice.call(arguments, 1);

  // Method calling logic
  this.filter(':input[type=text]').each(function() {
    switch (method) {
        // ... Code here
    }
  });

  // Maintain chainability
  return this;
};

// This is the constructor function. Instantiated by using the new keyword
var BetterAutocomplete = function($input, resource, options, callbacks) {

  options = $.extend({
    charLimit: 3,
    // More options
  }, options);

  /**
   * These callbacks are supposed to be overridden by you when you need
   * customization of the default behavior. When you are overriding a callback
   * function, it is a good idea to copy the source code from the default
   * callback function, as a skeleton.
   */
  callbacks = $.extend({

    /**
     * Gets fired when the user selects a result by clicking or using the
     * keyboard to select an element.
     *
     * &lt;br /&gt;&lt;br /&gt;&lt;em&gt;Default behavior: Simply blurs the input field.&lt;/em&gt;
     *
     * @param {Object} result
     *   The result object that was selected.
     */
    select: function(result) {
      $input.blur();
    },
    // ... More callbacks for fetching data, parsing results etc.
  }

  var self = this,
    lastRenderedQuery = '',
    results = {}, // Caching database of search results.
    // ... More private instance variables

  // Create the DOM elements necessary and attach eventhandlers
  var $wrapper = $('&lt;div /&gt;')
      .addClass('better-autocomplete')
      .insertAfter($input);

  // Public methods
  this.enable = function() { ... };

  // Then private methods
  var fetchResults = function() { ... };

  var getHighlighted = function() { ... };
};

}(jQuery);


Some hands on questions:


Does my design patterns look good? I am talking about modularity, namespacing, closures etc.
How can I stand out more from jQuery UI autocomplete and other existing plugins? What can I provide that they can't? Also, where can I reach the people who need this plugin?
Documentation. I have been using JSDoc toolkit but it is sometimes hard to understand. I have a few warnings when I generate the docs. Also I'm unsure about if I have correctly labeled functions, constructors etc. Can I improve it?


I can take criticism, so don't be shy, rather be honest.
You should strongly consider using a JS templating language such as Handlebars.js when rendering the interface.

  // Add the group if it doesn't exist
  var group = callbacks.getGroup(result);
  if ($.type(group) == 'string' &amp;&amp; !groups[group]) {
    var $groupHeading = $('&lt;li /&gt;').addClass('group')
      .append($('&lt;h3 /&gt;').html(group))
      .appendTo($results);
    groups[group] = $groupHeading;
  }

  var $result = $('&lt;li /&gt;').addClass('result')
    .append(output)
    .data('result', result) // Store the result object on this DOM element
    .addClass(result.addClass);


You are doing enough dom manipulation to warrant its use (above is just one part of your code). Furthermore, templates will help separate presentation logic from your business logic which at the moment is quite tangled.