Tell me more ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

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.
     *
     * <br /><br /><em>Default behavior: Simply blurs the input field.</em>
     *
     * @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 = $('<div />')
      .addClass('better-autocomplete')
      .insertAfter($input);

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

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

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

}(jQuery);

Some hands on questions:

  1. Does my design patterns look good? I am talking about modularity, namespacing, closures etc.
  2. 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?
  3. 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.

share|improve this question
1  
Firstly: I can't help with JSDoc and i'm not a very experienced jQuery plugin Developer but on #2 I think you should be asking the users of your plugin. Provide an email/discussion board/whatever as they are the ones who know what is needed. Maybe ask them specific questions like what have they done to extend your plugin etc. – James Khoury Jun 27 '11 at 3:03
1  
I do not want to put a damper on the work you have done, but I think that your hard work is better put helping one of the established projects become better other than starting a new fork. Just my $0.02 – ssmusoke Apr 10 '12 at 6:44

2 Answers

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' && !groups[group]) {
    var $groupHeading = $('<li />').addClass('group')
      .append($('<h3 />').html(group))
      .appendTo($results);
    groups[group] = $groupHeading;
  }

  var $result = $('<li />').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.

share|improve this answer

Make the code as terse as possible, make an alternative that does not depend on full jQuery.

I used jQuery as a stepping stone and now finally took the time to learn JavaScript. I figured I don't need to load a heck of a framework to do what I need. It feels good and light. Parsing unnecessary code eats out the battery of phones and kills the already bad experience on memory limited devices such as virus ridden PCs and old laptops, GPRS connections is another example.

Make a JavaScript autocomplete.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.