/** * @fileOverview Better Autocomplete is a flexible jQuery plugin which offers * rich text autocompletion, both from local and remote sources. * * @author Didrik Nordström, http://betamos.se/ * * @version v1.0-dev * * @requires * * * @preserve Better Autocomplete v1.0-dev * https://github.com/betamos/Better-Autocomplete * * Copyright 2011, Didrik Nordström, http://betamos.se/ * Dual licensed under the MIT or GPL Version 2 licenses. * * Requires jQuery 1.4+ * http://jquery.com/ */ /** * Create or alter an autocomplete object instance that belongs to * the elements in the selection. Make sure there are only text field elements * in the selection. * * @constructor * * @name jQuery.betterAutocomplete * * @param {String} method * Should be one of the following: * * * @param {String|Object} [resource] * If String, it will become the path for a remote resource. If not, it will * be treated like a local resource. The path should provide JSON objects * upon HTTP requests. * * @param {Object} [options] * An object with configurable options: * * * @param {Object} [callbacks] * An object containing optional callback functions on certain events. See * {@link callbacks} for details. These callbacks should be used when * customization of the default behavior of Better Autocomplete is required. * * @returns {Object} * The jQuery object with the same element selection, for chaining. */ (function($) { $.fn.betterAutocomplete = function(method) { /* * Each method expects the "this" object to be a valid DOM text input node. * The methods "enable", "disable" and "destroy" expects an instance of a * BetterAutocomplete object as their first argument. */ 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(); } }, args = Array.prototype.slice.call(arguments, 1); // Method calling logic this.each(function() { switch (method) { case 'init': methods[method].apply(this, args); break; case 'enable': case 'disable': case 'destroy': var bac = $(this).data('better-autocomplete'); if (bac instanceof BetterAutocomplete) { methods[method].call(this, bac); } break; default: $.error(['Method', method, 'does not exist in jQuery.betterAutocomplete.'].join(' ')); } }); // Maintain chainability return this; }; /** * The BetterAutocomplete constructor function. Returns a BetterAutocomplete * instance object. * * @private @constructor * @name BetterAutocomplete * * @param {Object} $input * A single input element wrapped in jQuery. */ var BetterAutocomplete = function($input, resource, options, callbacks) { var lastRenderedQuery = '', cache = {}, // Key-valued caching of search results cacheOrder = [], // Array of query strings, in the order they are added cacheSize = 0, // Keep count of the cache's size timer, // Used for options.delay activeRemoteCalls = [], // A flat array of query strings that are pending disableMouseHighlight = false, // Suppress the autotriggered mouseover event inputEvents = {}, isLocal = ($.type(resource) != 'string'), $results = $('