autocomplete-base-debug.js revision 221103f45ef4ea2c4caacb9f367f88cac34b8299
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTrippYUI.add('autocomplete-base', function(Y) {
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp/**
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * Provides automatic input completion or suggestions for text input fields and
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * textareas.
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp *
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * @module autocomplete
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @main autocomplete
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @since 3.3.0
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp */
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp/**
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <code>Y.Base</code> extension that provides core autocomplete logic (but no
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * UI implementation) for a text input field or textarea. Must be mixed into a
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <code>Y.Base</code>-derived class to be useful.
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp *
5ecb8c8b041752f6b716054ff5cfc2c9992365c6Tripp * @submodule autocomplete-base
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp */
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp/**
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * <p>
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * Extension that provides core autocomplete logic (but no UI implementation)
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * for a text input field or textarea.
e7c7565d9550eaa87043aef0df77125ada996deaTripp * </p>
e7c7565d9550eaa87043aef0df77125ada996deaTripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * The <code>AutoCompleteBase</code> class provides events and attributes that
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * abstract away core autocomplete logic and configuration, but does not provide
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * a widget implementation or suggestion UI. For a prepackaged autocomplete
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * widget, see <code>AutoCompleteList</code>.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * This extension cannot be instantiated directly, since it doesn't provide an
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * actual implementation. It's intended to be mixed into a
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <code>Y.Base</code>-based class or widget.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <code>Y.Widget</code>-based example:
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <pre>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * YUI().use('autocomplete-base', 'widget', function (Y) {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * &nbsp;&nbsp;var MyAC = Y.Base.create('myAC', Y.Widget, [Y.AutoCompleteBase], {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * &nbsp;&nbsp;&nbsp;&nbsp;// Custom prototype methods and properties.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * &nbsp;&nbsp;}, {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * &nbsp;&nbsp;&nbsp;&nbsp;// Custom static methods and properties.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * &nbsp;&nbsp;});
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * &nbsp;
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * &nbsp;&nbsp;// Custom implementation code.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * });
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </pre>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <code>Y.Base</code>-based example:
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <pre>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * YUI().use('autocomplete-base', function (Y) {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * &nbsp;&nbsp;var MyAC = Y.Base.create('myAC', Y.Base, [Y.AutoCompleteBase], {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * &nbsp;&nbsp;&nbsp;&nbsp;initializer: function () {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this._bindUIACBase();
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this._syncUIACBase();
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * &nbsp;&nbsp;&nbsp;&nbsp;},
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * &nbsp;
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * &nbsp;&nbsp;&nbsp;&nbsp;// Custom prototype methods and properties.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * &nbsp;&nbsp;}, {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * &nbsp;&nbsp;&nbsp;&nbsp;// Custom static methods and properties.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * &nbsp;&nbsp;});
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * &nbsp;
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * &nbsp;&nbsp;// Custom implementation code.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * });
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </pre>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @class AutoCompleteBase
828c58761d90445b8b9d20a82d85dc1479317f71Tripp */
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Trippvar Escape = Y.Escape,
828c58761d90445b8b9d20a82d85dc1479317f71Tripp Lang = Y.Lang,
828c58761d90445b8b9d20a82d85dc1479317f71Tripp YArray = Y.Array,
828c58761d90445b8b9d20a82d85dc1479317f71Tripp YObject = Y.Object,
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp isFunction = Lang.isFunction,
828c58761d90445b8b9d20a82d85dc1479317f71Tripp isString = Lang.isString,
828c58761d90445b8b9d20a82d85dc1479317f71Tripp trim = Lang.trim,
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp INVALID_VALUE = Y.Attribute.INVALID_VALUE,
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp _FUNCTION_VALIDATOR = '_functionValidator',
828c58761d90445b8b9d20a82d85dc1479317f71Tripp _SOURCE_SUCCESS = '_sourceSuccess',
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp ALLOW_BROWSER_AC = 'allowBrowserAutocomplete',
828c58761d90445b8b9d20a82d85dc1479317f71Tripp INPUT_NODE = 'inputNode',
828c58761d90445b8b9d20a82d85dc1479317f71Tripp QUERY = 'query',
828c58761d90445b8b9d20a82d85dc1479317f71Tripp QUERY_DELIMITER = 'queryDelimiter',
828c58761d90445b8b9d20a82d85dc1479317f71Tripp REQUEST_TEMPLATE = 'requestTemplate',
828c58761d90445b8b9d20a82d85dc1479317f71Tripp RESULTS = 'results',
828c58761d90445b8b9d20a82d85dc1479317f71Tripp RESULT_LIST_LOCATOR = 'resultListLocator',
828c58761d90445b8b9d20a82d85dc1479317f71Tripp VALUE = 'value',
828c58761d90445b8b9d20a82d85dc1479317f71Tripp VALUE_CHANGE = 'valueChange',
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp EVT_CLEAR = 'clear',
828c58761d90445b8b9d20a82d85dc1479317f71Tripp EVT_QUERY = QUERY,
828c58761d90445b8b9d20a82d85dc1479317f71Tripp EVT_RESULTS = RESULTS;
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Trippfunction AutoCompleteBase() {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp // AOP bindings.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp Y.before(this._bindUIACBase, this, 'bindUI');
828c58761d90445b8b9d20a82d85dc1479317f71Tripp Y.before(this._destructorACBase, this, 'destructor');
828c58761d90445b8b9d20a82d85dc1479317f71Tripp Y.before(this._syncUIACBase, this, 'syncUI');
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp // -- Public Events --------------------------------------------------------
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp /**
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * Fires after the query has been completely cleared or no longer meets the
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * minimum query length requirement.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @event clear
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @param {EventFacade} e Event facade with the following additional
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * properties:
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dl>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dt>prevVal (String)</dt>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * Value of the query before it was cleared.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </dl>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @preventable _defClearFn
828c58761d90445b8b9d20a82d85dc1479317f71Tripp */
828c58761d90445b8b9d20a82d85dc1479317f71Tripp this.publish(EVT_CLEAR, {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp defaultFn: this._defClearFn
828c58761d90445b8b9d20a82d85dc1479317f71Tripp });
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp /**
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * Fires when the contents of the input field have changed and the input
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * value meets the criteria necessary to generate an autocomplete query.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @event query
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @param {EventFacade} e Event facade with the following additional
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * properties:
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dl>
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * <dt>inputValue (String)</dt>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * Full contents of the text input field or textarea that generated
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * the query.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dt>query (String)</dt>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * Autocomplete query. This is the string that will be used to
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * request completion results. It may or may not be the same as
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <code>inputValue</code>.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </dl>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @preventable _defQueryFn
828c58761d90445b8b9d20a82d85dc1479317f71Tripp */
828c58761d90445b8b9d20a82d85dc1479317f71Tripp this.publish(EVT_QUERY, {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp defaultFn: this._defQueryFn
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp });
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp /**
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * Fires after query results are received from the <code>source</code>. If
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * no source has been set, this event will not fire.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @event results
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @param {EventFacade} e Event facade with the following additional
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * properties:
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dl>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dt>data (Array|Object)</dt>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * Raw, unfiltered result data (if available).
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </dd>
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp *
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * <dt>query (String)</dt>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * Query that generated these results.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dt>results (Array)</dt>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * Array of filtered, formatted, and highlighted results. Each item in
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * the array is an object with the following properties:
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dl>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dt>display (Node|HTMLElement|String)</dt>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * Formatted result HTML suitable for display to the user. If no
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * custom formatter is set, this will be an HTML-escaped version of
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * the string in the <code>text</code> property.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </dd>
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp *
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * <dt>highlighted (String)</dt>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * Highlighted (but not formatted) result text. This property will
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * only be set if a highlighter is in use.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dt>raw (mixed)</dt>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dd>
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * Raw, unformatted result in whatever form it was provided by the
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * <code>source</code>.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dt>text (String)</dt>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * Plain text version of the result, suitable for being inserted
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * into the value of a text input field or textarea when the result
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * is selected by a user. This value is not HTML-escaped and should
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * not be inserted into the page using innerHTML.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </dd>
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * </dl>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </dl>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @preventable _defResultsFn
828c58761d90445b8b9d20a82d85dc1479317f71Tripp */
828c58761d90445b8b9d20a82d85dc1479317f71Tripp this.publish(EVT_RESULTS, {
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp defaultFn: this._defResultsFn
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp });
828c58761d90445b8b9d20a82d85dc1479317f71Tripp}
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp// -- Public Static Properties -------------------------------------------------
0341dba359758fa73cc2f2ae9f6f8ebe9bfa94beTrippAutoCompleteBase.ATTRS = {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp /**
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * Whether or not to enable the browser's built-in autocomplete
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * functionality for input fields.
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp *
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * @attribute allowBrowserAutocomplete
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * @type Boolean
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * @default false
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp */
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp allowBrowserAutocomplete: {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp value: false
828c58761d90445b8b9d20a82d85dc1479317f71Tripp },
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp /**
080b31a43c2a1d068c28eaa3e243bdd6e8a89ffaTripp * When a <code>queryDelimiter</code> is set, trailing delimiters will
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * automatically be stripped from the input value by default when the
080b31a43c2a1d068c28eaa3e243bdd6e8a89ffaTripp * input node loses focus. Set this to <code>true</code> to allow trailing
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * delimiters.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @attribute allowTrailingDelimiter
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @type Boolean
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @default false
828c58761d90445b8b9d20a82d85dc1479317f71Tripp */
828c58761d90445b8b9d20a82d85dc1479317f71Tripp allowTrailingDelimiter: {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp value: false
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp },
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp /**
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * Node to monitor for changes, which will generate <code>query</code>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * events when appropriate. May be either an input field or a textarea.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
aeee02c921674c7c98f1e3cbfdaa32b7da4a1ad5Tripp * @attribute inputNode
aeee02c921674c7c98f1e3cbfdaa32b7da4a1ad5Tripp * @type Node|HTMLElement|String
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @writeonce
828c58761d90445b8b9d20a82d85dc1479317f71Tripp */
828c58761d90445b8b9d20a82d85dc1479317f71Tripp inputNode: {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp setter: Y.one,
828c58761d90445b8b9d20a82d85dc1479317f71Tripp writeOnce: 'initOnly'
828c58761d90445b8b9d20a82d85dc1479317f71Tripp },
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
aeee02c921674c7c98f1e3cbfdaa32b7da4a1ad5Tripp /**
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * Maximum number of results to return. A value of <code>0</code> or less
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * will allow an unlimited number of results.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @attribute maxResults
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * @type Number
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @default 0
828c58761d90445b8b9d20a82d85dc1479317f71Tripp */
aeee02c921674c7c98f1e3cbfdaa32b7da4a1ad5Tripp maxResults: {
b08d5c81743759d32bccaf4bec55aa102491026eTripp value: 0
828c58761d90445b8b9d20a82d85dc1479317f71Tripp },
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp /**
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * Minimum number of characters that must be entered before a
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <code>query</code> event will be fired. A value of <code>0</code>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * allows empty queries; a negative value will effectively disable all
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <code>query</code> events.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @attribute minQueryLength
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @type Number
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @default 1
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp */
828c58761d90445b8b9d20a82d85dc1479317f71Tripp minQueryLength: {
aeee02c921674c7c98f1e3cbfdaa32b7da4a1ad5Tripp value: 1
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp },
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp /**
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * Current query, or <code>null</code> if there is no current query.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * <p>
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * The query might not be the same as the current value of the input
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * node, both for timing reasons (due to <code>queryDelay</code>) and
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * because when one or more <code>queryDelimiter</code> separators are
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * in use, only the last portion of the delimited input string will be
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * used as the query value.
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * </p>
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp *
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * @attribute query
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @type String|null
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @default null
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @readonly
828c58761d90445b8b9d20a82d85dc1479317f71Tripp */
828c58761d90445b8b9d20a82d85dc1479317f71Tripp query: {
9cc2c5945426b2b79c0a258026d750be74795924Tripp readOnly: true,
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp value: null
828c58761d90445b8b9d20a82d85dc1479317f71Tripp },
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp /**
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * Number of milliseconds to delay after input before triggering a
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <code>query</code> event. If new input occurs before this delay is
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * over, the previous input event will be ignored and a new delay will
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * begin.
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * </p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * This can be useful both to throttle queries to a remote data source
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * and to avoid distracting the user by showing them less relevant
aeee02c921674c7c98f1e3cbfdaa32b7da4a1ad5Tripp * results before they've paused their typing.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @attribute queryDelay
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @type Number
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * @default 100
828c58761d90445b8b9d20a82d85dc1479317f71Tripp */
828c58761d90445b8b9d20a82d85dc1479317f71Tripp queryDelay: {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp value: 100
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp },
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp /**
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * Query delimiter string. When a delimiter is configured, the input value
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * will be split on the delimiter, and only the last portion will be used in
b08d5c81743759d32bccaf4bec55aa102491026eTripp * autocomplete queries and updated when the <code>query</code> attribute is
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * modified.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp *
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * @attribute queryDelimiter
b08d5c81743759d32bccaf4bec55aa102491026eTripp * @type String|null
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * @default null
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp */
828c58761d90445b8b9d20a82d85dc1479317f71Tripp queryDelimiter: {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp value: null
828c58761d90445b8b9d20a82d85dc1479317f71Tripp },
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp /**
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * Source request template. This can be a function that accepts a query as a
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * parameter and returns a request string, or it can be a string containing
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * the placeholder "{query}", which will be replaced with the actual
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * URI-encoded query. In either case, the resulting string will be appended
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * to the request URL when the <code>source</code> attribute is set to a
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * remote DataSource, JSONP URL, or XHR URL (it will not be appended to YQL
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * URLs).
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * </p>
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * While <code>requestTemplate</code> may be set to either a function or
6c4ec9d420df654d019b936fd06bef6f769db4cbTripp * a string, it will always be returned as a function that accepts a
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * query argument and returns a string.
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * </p>
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp *
6c4ec9d420df654d019b936fd06bef6f769db4cbTripp * @attribute requestTemplate
6c4ec9d420df654d019b936fd06bef6f769db4cbTripp * @type Function|String|null
6c4ec9d420df654d019b936fd06bef6f769db4cbTripp * @default null
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp */
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp requestTemplate: {
6c4ec9d420df654d019b936fd06bef6f769db4cbTripp setter: '_setRequestTemplate',
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp value: null
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp },
6c4ec9d420df654d019b936fd06bef6f769db4cbTripp
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp /**
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * <p>
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * Array of local result filter functions. If provided, each filter
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * will be called with two arguments when results are received: the query
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * and an array of result objects. See the documentation for the
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * <code>results</code> event for a list of the properties available on each
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * result object.
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * </p>
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp *
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * <p>
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * Each filter is expected to return a filtered or modified version of the
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * results array, which will then be passed on to subsequent filters, then
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * the <code>resultHighlighter</code> function (if set), then the
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * <code>resultFormatter</code> function (if set), and finally to
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * subscribers to the <code>results</code> event.
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * </p>
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp *
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * <p>
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * If no <code>source</code> is set, result filters will not be called.
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * </p>
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp *
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * <p>
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * Prepackaged result filters provided by the autocomplete-filters and
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * autocomplete-filters-accentfold modules can be used by specifying the
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * filter name as a string, such as <code>'phraseMatch'</code> (assuming
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * the necessary filters module is loaded).
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * </p>
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp *
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * @attribute resultFilters
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * @type Array
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @default []
828c58761d90445b8b9d20a82d85dc1479317f71Tripp */
828c58761d90445b8b9d20a82d85dc1479317f71Tripp resultFilters: {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp setter: '_setResultFilters',
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp value: []
828c58761d90445b8b9d20a82d85dc1479317f71Tripp },
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp /**
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <p>
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * Function which will be used to format results. If provided, this function
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * will be called with two arguments after results have been received and
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * filtered: the query and an array of result objects. The formatter is
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * expected to return an array of HTML strings or Node instances containing
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * the desired HTML for each result.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </p>
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp *
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * See the documentation for the <code>results</code> event for a list of
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * the properties available on each result object.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </p>
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * If no <code>source</code> is set, the formatter will not be called.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </p>
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @attribute resultFormatter
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @type Function|null
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp */
828c58761d90445b8b9d20a82d85dc1479317f71Tripp resultFormatter: {
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp validator: _FUNCTION_VALIDATOR
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp },
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp /**
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * Function which will be used to highlight results. If provided, this
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * function will be called with two arguments after results have been
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * received and filtered: the query and an array of filtered result objects.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * The highlighter is expected to return an array of highlighted result
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * text in the form of HTML strings.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * See the documentation for the <code>results</code> event for a list of
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * the properties available on each result object.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </p>
9cc2c5945426b2b79c0a258026d750be74795924Tripp *
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * <p>
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * If no <code>source</code> is set, the highlighter will not be called.
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * </p>
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp *
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * @attribute resultHighlighter
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * @type Function|null
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp */
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp resultHighlighter: {
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp setter: '_setResultHighlighter'
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp },
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp /**
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp * <p>
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp * Locator that should be used to extract an array of results from a
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp * non-array response.
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp * </p>
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp *
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * <p>
9cc2c5945426b2b79c0a258026d750be74795924Tripp * By default, no locator is applied, and all responses are assumed to be
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * arrays by default. If all responses are already arrays, you don't need to
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * define a locator.
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * </p>
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp *
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * <p>
9cc2c5945426b2b79c0a258026d750be74795924Tripp * The locator may be either a function (which will receive the raw response
9cc2c5945426b2b79c0a258026d750be74795924Tripp * as an argument and must return an array) or a string representing an
9cc2c5945426b2b79c0a258026d750be74795924Tripp * object path, such as "foo.bar.baz" (which would return the value of
9cc2c5945426b2b79c0a258026d750be74795924Tripp * <code>result.foo.bar.baz</code> if the response is an object).
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * </p>
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp *
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * <p>
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * While <code>resultListLocator</code> may be set to either a function or a
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp * string, it will always be returned as a function that accepts a response
9cc2c5945426b2b79c0a258026d750be74795924Tripp * argument and returns an array.
9cc2c5945426b2b79c0a258026d750be74795924Tripp * </p>
9cc2c5945426b2b79c0a258026d750be74795924Tripp *
9cc2c5945426b2b79c0a258026d750be74795924Tripp * @attribute resultListLocator
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @type Function|String|null
828c58761d90445b8b9d20a82d85dc1479317f71Tripp */
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp resultListLocator: {
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp setter: '_setLocator'
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp },
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp /**
9cc2c5945426b2b79c0a258026d750be74795924Tripp * Current results, or an empty array if there are no results.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
9cc2c5945426b2b79c0a258026d750be74795924Tripp * @attribute results
9cc2c5945426b2b79c0a258026d750be74795924Tripp * @type Array
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * @default []
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * @readonly
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp */
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp results: {
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp readOnly: true,
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp value: []
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp },
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp /**
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * <p>
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * Locator that should be used to extract a plain text string from a
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * non-string result item. The resulting text value will typically be the
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * value that ends up being inserted into an input field or textarea when
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * the user of an autocomplete implementation selects a result.
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * </p>
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp *
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * <p>
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * By default, no locator is applied, and all results are assumed to be
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * plain text strings. If all results are already plain text strings, you
9cc2c5945426b2b79c0a258026d750be74795924Tripp * don't need to define a locator.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * The locator may be either a function (which will receive the raw result
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * as an argument and must return a string) or a string representing an
9cc2c5945426b2b79c0a258026d750be74795924Tripp * object path, such as "foo.bar.baz" (which would return the value of
9cc2c5945426b2b79c0a258026d750be74795924Tripp * <code>result.foo.bar.baz</code> if the result is an object).
9cc2c5945426b2b79c0a258026d750be74795924Tripp * </p>
9cc2c5945426b2b79c0a258026d750be74795924Tripp *
9cc2c5945426b2b79c0a258026d750be74795924Tripp * <p>
9cc2c5945426b2b79c0a258026d750be74795924Tripp * While <code>resultTextLocator</code> may be set to either a function or a
9cc2c5945426b2b79c0a258026d750be74795924Tripp * string, it will always be returned as a function that accepts a result
ed59119d8c00addb07c7ee6c8aefcd1d9cb876f1Tripp * argument and returns a string.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @attribute resultTextLocator
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * @type Function|String|null
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp */
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp resultTextLocator: {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp setter: '_setLocator'
828c58761d90445b8b9d20a82d85dc1479317f71Tripp },
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp /**
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <p>
9cc2c5945426b2b79c0a258026d750be74795924Tripp * Source for autocomplete results. The following source types are
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * supported:
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * <dl>
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * <dt>Array</dt>
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * <dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <i>Example:</i> <code>['first result', 'second result', 'etc']</code>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * <p>
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * The full array will be provided to any configured filters for each
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * query. This is an easy way to create a fully client-side autocomplete
9cc2c5945426b2b79c0a258026d750be74795924Tripp * implementation.
9cc2c5945426b2b79c0a258026d750be74795924Tripp * </p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dt>DataSource</dt>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * A <code>DataSource</code> instance or other object that provides a
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * DataSource-like <code>sendRequest</code> method. See the
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <code>DataSource</code> documentation for details.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * <dt>Function</dt>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <i>Example (synchronous):</i> <code>function (query) { return ['foo', 'bar']; }</code><br>
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp <i>Example (async):</i> <code>function (query, callback) { callback(['foo', 'bar']); }</code>
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * </p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * A function source will be called with the current query and a
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * callback function as parameters, and should either return an array of
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * results (for synchronous operation) or return nothing and pass an
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * array of results to the provided callback (for asynchronous
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * operation).
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * </p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </dd>
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dt>Object</dt>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <i>Example:</i> <code>{foo: ['foo result 1', 'foo result 2'], bar: ['bar result']}</code>
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * </p>
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp *
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * An object will be treated as a query hashmap. If a property on the
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * object matches the current query, the value of that property will be
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * used as the response.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </p>
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp *
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * <p>
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * The response is assumed to be an array of results by default. If the
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * response is not an array, provide a <code>resultListLocator</code> to
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * process the response and return an array.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </dl>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * If the optional <code>autocomplete-sources</code> module is loaded, then
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * the following additional source types will be supported as well:
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </p>
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dl>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dt>&lt;select&gt; Node</dt>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * You may provide a YUI Node instance wrapping a &lt;select&gt;
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * element, and the options in the list will be used as results. You
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * will also need to specify a <code>resultTextLocator</code> of 'text'
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * or 'value', depending on what you want to use as the text of the
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * result.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * </p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * Each result will be an object with the following properties:
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </p>
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp *
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * <dl>
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * <dt>html (String)</dt>
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * <dd>
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * <p>HTML content of the &lt;option&gt; element.</p>
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * </dd>
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dt>index (Number)</dt>
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * <dd>
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * <p>Index of the &lt;option&gt; element in the list.</p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dt>node (Y.Node)</dt>
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * <dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <p>Node instance referring to the original &lt;option&gt; element.</p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dt>selected (Boolean)</dt>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dd>
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * <p>Whether or not this item is currently selected in the
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * &lt;select&gt; list.</p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dt>text (String)</dt>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <p>Text content of the &lt;option&gt; element.</p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </dd>
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dt>value (String)</dt>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <p>Value of the &lt;option&gt; element.</p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </dd>
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * </dl>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dt>String (JSONP URL)</dt>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <i>Example:</i> <code>'http://example.com/search?q={query}&callback={callback}'</code>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * If a URL with a <code>{callback}</code> placeholder is provided, it
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * will be used to make a JSONP request. The <code>{query}</code>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * placeholder will be replaced with the current query, and the
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <code>{callback}</code> placeholder will be replaced with an
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * internally-generated JSONP callback name. Both placeholders must
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * appear in the URL, or the request will fail. An optional
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <code>{maxResults}</code> placeholder may also be provided, and will
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * be replaced with the value of the maxResults attribute (or 1000 if
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * the maxResults attribute is 0 or less).
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * The response is assumed to be an array of results by default. If the
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * response is not an array, provide a <code>resultListLocator</code> to
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * process the response and return an array.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <strong>The <code>jsonp</code> module must be loaded in order for
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * JSONP URL sources to work.</strong> If the <code>jsonp</code> module
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * is not already loaded, it will be loaded on demand if possible.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dt>String (XHR URL)</dt>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <i>Example:</i> <code>'http://example.com/search?q={query}'</code>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * If a URL without a <code>{callback}</code> placeholder is provided,
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * it will be used to make a same-origin XHR request. The
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <code>{query}</code> placeholder will be replaced with the current
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * query. An optional <code>{maxResults}</code> placeholder may also be
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * provided, and will be replaced with the value of the maxResults
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * attribute (or 1000 if the maxResults attribute is 0 or less).
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * The response is assumed to be a JSON array of results by default. If
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * the response is a JSON object and not an array, provide a
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <code>resultListLocator</code> to process the response and return an
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * array. If the response is in some form other than JSON, you will
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * need to use a custom DataSource instance as the source.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <strong>The <code>io-base</code> and <code>json-parse</code> modules
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * must be loaded in order for XHR URL sources to work.</strong> If
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * these modules are not already loaded, they will be loaded on demand
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * if possible.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dt>String (YQL query)</dt>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <dd>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <i>Example:</i> <code>'select * from search.suggest where query="{query}"'</code>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * </p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <p>
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * If a YQL query is provided, it will be used to make a YQL request.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * The <code>{query}</code> placeholder will be replaced with the
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * current autocomplete query. This placeholder must appear in the YQL
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * query, or the request will fail. An optional
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * <code>{maxResults}</code> placeholder may also be provided, and will
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * be replaced with the value of the maxResults attribute (or 1000 if
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * the maxResults attribute is 0 or less).
a89ad754cce3cfc8aee71760e10217b54020360dTripp * </p>
a89ad754cce3cfc8aee71760e10217b54020360dTripp *
a89ad754cce3cfc8aee71760e10217b54020360dTripp * <p>
a89ad754cce3cfc8aee71760e10217b54020360dTripp * <strong>The <code>yql</code> module must be loaded in order for YQL
a89ad754cce3cfc8aee71760e10217b54020360dTripp * sources to work.</strong> If the <code>yql</code> module is not
a89ad754cce3cfc8aee71760e10217b54020360dTripp * already loaded, it will be loaded on demand if possible.
a89ad754cce3cfc8aee71760e10217b54020360dTripp * </p>
a89ad754cce3cfc8aee71760e10217b54020360dTripp * </dd>
a89ad754cce3cfc8aee71760e10217b54020360dTripp * </dl>
a89ad754cce3cfc8aee71760e10217b54020360dTripp *
a89ad754cce3cfc8aee71760e10217b54020360dTripp * <p>
a89ad754cce3cfc8aee71760e10217b54020360dTripp * As an alternative to providing a source, you could simply listen for
aeee02c921674c7c98f1e3cbfdaa32b7da4a1ad5Tripp * <code>query</code> events and handle them any way you see fit. Providing
aeee02c921674c7c98f1e3cbfdaa32b7da4a1ad5Tripp * a source is optional, but will usually be simpler.
a89ad754cce3cfc8aee71760e10217b54020360dTripp * </p>
a89ad754cce3cfc8aee71760e10217b54020360dTripp *
a89ad754cce3cfc8aee71760e10217b54020360dTripp * @attribute source
a89ad754cce3cfc8aee71760e10217b54020360dTripp * @type Array|DataSource|Function|Node|Object|String|null
a89ad754cce3cfc8aee71760e10217b54020360dTripp */
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp source: {
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp setter: '_setSource'
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp },
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp /**
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * <p>
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * May be used to force a specific source type, overriding the automatic
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * source type detection. It should almost never be necessary to do this,
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * but as they taught us in the Boy Scouts, one should always be prepared,
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * so it's here if you need it. Be warned that if you set this attribute and
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * something breaks, it's your own fault.
a89ad754cce3cfc8aee71760e10217b54020360dTripp * </p>
a89ad754cce3cfc8aee71760e10217b54020360dTripp *
a89ad754cce3cfc8aee71760e10217b54020360dTripp * <p>
a89ad754cce3cfc8aee71760e10217b54020360dTripp * Supported <code>sourceType</code> values are: 'array', 'datasource',
a89ad754cce3cfc8aee71760e10217b54020360dTripp * 'function', and 'object'.
a89ad754cce3cfc8aee71760e10217b54020360dTripp * </p>
a89ad754cce3cfc8aee71760e10217b54020360dTripp *
a89ad754cce3cfc8aee71760e10217b54020360dTripp * <p>
a89ad754cce3cfc8aee71760e10217b54020360dTripp * If the <code>autocomplete-sources</code> module is loaded, the following
a89ad754cce3cfc8aee71760e10217b54020360dTripp * additional source types are supported: 'io', 'jsonp', 'select',
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * 'string', 'yql'
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * </p>
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp *
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * @attribute sourceType
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * @type String
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp */
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp sourceType: {
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp value: null
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp },
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp /**
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * If the <code>inputNode</code> specified at instantiation time has a
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * <code>node-tokeninput</code> plugin attached to it, this attribute will
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * be a reference to the <code>Y.Plugin.TokenInput</code> instance.
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp *
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * @attribute tokenInput
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * @type Plugin.TokenInput
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * @readonly
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp */
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp tokenInput: {
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp readOnly: true
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp },
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp /**
a89ad754cce3cfc8aee71760e10217b54020360dTripp * Current value of the input node.
a89ad754cce3cfc8aee71760e10217b54020360dTripp *
a89ad754cce3cfc8aee71760e10217b54020360dTripp * @attribute value
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * @type String
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * @default ''
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp */
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp value: {
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp // Why duplicate this._inputNode.get('value')? Because we need a
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp // reliable way to track the source of value changes. We want to perform
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp // completion when the user changes the value, but not when we change
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp // the value.
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp value: ''
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp }
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp};
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTrippAutoCompleteBase.CSS_PREFIX = 'ac';
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTrippAutoCompleteBase.UI_SRC = (Y.Widget && Y.Widget.UI_SRC) || 'ui';
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp/**
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * Mapping of built-in source types to their setter functions. DataSource
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * instances and DataSource-like objects are handled natively, so are not
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * mapped here.
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp *
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * @property SOURCE_TYPES
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * @type {Object}
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * @static
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp */
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTrippAutoCompleteBase.SOURCE_TYPES = {
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp array : '_createArraySource',
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp 'function': '_createFunctionSource',
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp object : '_createObjectSource'
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp};
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTrippAutoCompleteBase.prototype = {
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp // -- Public Prototype Methods ---------------------------------------------
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp /**
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * <p>
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * Sends a request to the configured source. If no source is configured,
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * this method won't do anything.
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * </p>
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp *
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * <p>
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp * Usually there's no reason to call this method manually; it will be
a89ad754cce3cfc8aee71760e10217b54020360dTripp * called automatically when user input causes a <code>query</code> event to
a89ad754cce3cfc8aee71760e10217b54020360dTripp * be fired. The only time you'll need to call this method manually is if
a89ad754cce3cfc8aee71760e10217b54020360dTripp * you want to force a request to be sent when no user input has occurred.
4ef2f7e4cb7c7d255be077c47d542199f7bf8607Tripp * </p>
a89ad754cce3cfc8aee71760e10217b54020360dTripp *
a89ad754cce3cfc8aee71760e10217b54020360dTripp * @method sendRequest
a89ad754cce3cfc8aee71760e10217b54020360dTripp * @param {String} query (optional) Query to send. If specified, the
a89ad754cce3cfc8aee71760e10217b54020360dTripp * <code>query</code> attribute will be set to this query. If not
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * specified, the current value of the <code>query</code> attribute will
a89ad754cce3cfc8aee71760e10217b54020360dTripp * be used.
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * @param {Function} requestTemplate (optional) Request template function.
a89ad754cce3cfc8aee71760e10217b54020360dTripp * If not specified, the current value of the <code>requestTemplate</code>
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * attribute will be used.
a89ad754cce3cfc8aee71760e10217b54020360dTripp * @chainable
a89ad754cce3cfc8aee71760e10217b54020360dTripp */
828c58761d90445b8b9d20a82d85dc1479317f71Tripp sendRequest: function (query, requestTemplate) {
5ecb8c8b041752f6b716054ff5cfc2c9992365c6Tripp var request,
828c58761d90445b8b9d20a82d85dc1479317f71Tripp source = this.get('source');
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp if (query || query === '') {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp this._set(QUERY, query);
828c58761d90445b8b9d20a82d85dc1479317f71Tripp } else {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp query = this.get(QUERY) || '';
c093c1aed867e18aa4778708592e1ceb45d18cffTripp }
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp if (source) {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp if (!requestTemplate) {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp requestTemplate = this.get(REQUEST_TEMPLATE);
828c58761d90445b8b9d20a82d85dc1479317f71Tripp }
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp request = requestTemplate ?
828c58761d90445b8b9d20a82d85dc1479317f71Tripp requestTemplate.call(this, query) : query;
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp Y.log('sendRequest: ' + request, 'info', 'autocomplete-base');
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp source.sendRequest({
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp query : query,
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp request: request,
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp callback: {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp success: Y.bind(this._onResponse, this, query)
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp }
828c58761d90445b8b9d20a82d85dc1479317f71Tripp });
828c58761d90445b8b9d20a82d85dc1479317f71Tripp }
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp return this;
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp },
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp // -- Protected Lifecycle Methods ------------------------------------------
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp /**
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp * Attaches event listeners and behaviors.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp *
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * @method _bindUIACBase
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp * @protected
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp */
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp _bindUIACBase: function () {
2ebe57b26e070070dacbe6e2b3351d5cefaee874Tripp var inputNode = this.get(INPUT_NODE),
828c58761d90445b8b9d20a82d85dc1479317f71Tripp tokenInput = inputNode && inputNode.tokenInput;
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp // If the inputNode has a node-tokeninput plugin attached, bind to the
66ca16dd76367c074fe4df1dcf7b555489a9bf85Tripp // plugin's inputNode instead.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp if (tokenInput) {
c093c1aed867e18aa4778708592e1ceb45d18cffTripp inputNode = tokenInput.get(INPUT_NODE);
828c58761d90445b8b9d20a82d85dc1479317f71Tripp this._set('tokenInput', tokenInput);
828c58761d90445b8b9d20a82d85dc1479317f71Tripp }
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp if (!inputNode) {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp Y.error('No inputNode specified.');
828c58761d90445b8b9d20a82d85dc1479317f71Tripp return;
828c58761d90445b8b9d20a82d85dc1479317f71Tripp }
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp this._inputNode = inputNode;
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp this._acBaseEvents = new Y.EventHandle([
828c58761d90445b8b9d20a82d85dc1479317f71Tripp // This is the valueChange event on the inputNode, provided by the
828c58761d90445b8b9d20a82d85dc1479317f71Tripp // event-valuechange module, not our own valueChange.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp inputNode.on(VALUE_CHANGE, this._onInputValueChange, this),
828c58761d90445b8b9d20a82d85dc1479317f71Tripp inputNode.on('blur', this._onInputBlur, this),
c093c1aed867e18aa4778708592e1ceb45d18cffTripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp this.after(ALLOW_BROWSER_AC + 'Change', this._syncBrowserAutocomplete),
828c58761d90445b8b9d20a82d85dc1479317f71Tripp this.after('sourceTypeChange', this._afterSourceTypeChange),
828c58761d90445b8b9d20a82d85dc1479317f71Tripp this.after(VALUE_CHANGE, this._afterValueChange)
828c58761d90445b8b9d20a82d85dc1479317f71Tripp ]);
828c58761d90445b8b9d20a82d85dc1479317f71Tripp },
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp /**
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * Detaches AutoCompleteBase event listeners.
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp *
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * @method _destructorACBase
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * @protected
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp */
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp _destructorACBase: function () {
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp this._acBaseEvents.detach();
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp },
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp /**
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * Synchronizes the UI state of the <code>inputNode</code>.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @method _syncUIACBase
e7c7565d9550eaa87043aef0df77125ada996deaTripp * @protected
e7c7565d9550eaa87043aef0df77125ada996deaTripp */
c093c1aed867e18aa4778708592e1ceb45d18cffTripp _syncUIACBase: function () {
e7c7565d9550eaa87043aef0df77125ada996deaTripp this._syncBrowserAutocomplete();
828c58761d90445b8b9d20a82d85dc1479317f71Tripp this.set(VALUE, this.get(INPUT_NODE).get(VALUE));
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp },
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp // -- Protected Prototype Methods ------------------------------------------
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp /**
e7c7565d9550eaa87043aef0df77125ada996deaTripp * Creates a DataSource-like object that simply returns the specified array
e7c7565d9550eaa87043aef0df77125ada996deaTripp * as a response. See the <code>source</code> attribute for more details.
c093c1aed867e18aa4778708592e1ceb45d18cffTripp *
e7c7565d9550eaa87043aef0df77125ada996deaTripp * @method _createArraySource
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @param {Array} source
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * @return {Object} DataSource-like object.
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp * @protected
c7ba96d16d58075a9ab8d5c1e46c6c83ce11cb4eTripp */
828c58761d90445b8b9d20a82d85dc1479317f71Tripp _createArraySource: function (source) {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp var that = this;
e7c7565d9550eaa87043aef0df77125ada996deaTripp
e7c7565d9550eaa87043aef0df77125ada996deaTripp return {
c093c1aed867e18aa4778708592e1ceb45d18cffTripp type: 'array',
e7c7565d9550eaa87043aef0df77125ada996deaTripp sendRequest: function (request) {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp that[_SOURCE_SUCCESS](source.concat(), request);
828c58761d90445b8b9d20a82d85dc1479317f71Tripp }
828c58761d90445b8b9d20a82d85dc1479317f71Tripp };
828c58761d90445b8b9d20a82d85dc1479317f71Tripp },
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp /**
e7c7565d9550eaa87043aef0df77125ada996deaTripp * Creates a DataSource-like object that passes the query to a
e7c7565d9550eaa87043aef0df77125ada996deaTripp * custom-defined function, which is expected to call the provided callback
c093c1aed867e18aa4778708592e1ceb45d18cffTripp * with an array of results. See the <code>source</code> attribute for more
e7c7565d9550eaa87043aef0df77125ada996deaTripp * details.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @method _createFunctionSource
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @param {Function} source Function that accepts a query and a callback as
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * parameters, and calls the callback with an array of results.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @return {Object} DataSource-like object.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @protected
828c58761d90445b8b9d20a82d85dc1479317f71Tripp */
828c58761d90445b8b9d20a82d85dc1479317f71Tripp _createFunctionSource: function (source) {
c093c1aed867e18aa4778708592e1ceb45d18cffTripp var that = this;
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp return {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp type: 'function',
828c58761d90445b8b9d20a82d85dc1479317f71Tripp sendRequest: function (request) {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp var value;
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp function afterResults(results) {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp that[_SOURCE_SUCCESS](results || [], request);
828c58761d90445b8b9d20a82d85dc1479317f71Tripp }
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp // Allow both synchronous and asynchronous functions. If we get
828c58761d90445b8b9d20a82d85dc1479317f71Tripp // a truthy return value, assume the function is synchronous.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp if ((value = source(request.query, afterResults))) {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp afterResults(value);
828c58761d90445b8b9d20a82d85dc1479317f71Tripp }
828c58761d90445b8b9d20a82d85dc1479317f71Tripp }
828c58761d90445b8b9d20a82d85dc1479317f71Tripp };
e7c7565d9550eaa87043aef0df77125ada996deaTripp },
e7c7565d9550eaa87043aef0df77125ada996deaTripp
e7c7565d9550eaa87043aef0df77125ada996deaTripp /**
e7c7565d9550eaa87043aef0df77125ada996deaTripp * Creates a DataSource-like object that looks up queries as properties on
e7c7565d9550eaa87043aef0df77125ada996deaTripp * the specified object, and returns the found value (if any) as a response.
e7c7565d9550eaa87043aef0df77125ada996deaTripp * See the <code>source</code> attribute for more details.
e7c7565d9550eaa87043aef0df77125ada996deaTripp *
e7c7565d9550eaa87043aef0df77125ada996deaTripp * @method _createObjectSource
e7c7565d9550eaa87043aef0df77125ada996deaTripp * @param {Object} source
e7c7565d9550eaa87043aef0df77125ada996deaTripp * @return {Object} DataSource-like object.
e7c7565d9550eaa87043aef0df77125ada996deaTripp * @protected
e7c7565d9550eaa87043aef0df77125ada996deaTripp */
e7c7565d9550eaa87043aef0df77125ada996deaTripp _createObjectSource: function (source) {
e7c7565d9550eaa87043aef0df77125ada996deaTripp var that = this;
e7c7565d9550eaa87043aef0df77125ada996deaTripp
e7c7565d9550eaa87043aef0df77125ada996deaTripp return {
e7c7565d9550eaa87043aef0df77125ada996deaTripp type: 'object',
e7c7565d9550eaa87043aef0df77125ada996deaTripp sendRequest: function (request) {
e7c7565d9550eaa87043aef0df77125ada996deaTripp var query = request.query;
e7c7565d9550eaa87043aef0df77125ada996deaTripp
e7c7565d9550eaa87043aef0df77125ada996deaTripp that[_SOURCE_SUCCESS](
828c58761d90445b8b9d20a82d85dc1479317f71Tripp YObject.owns(source, query) ? source[query] : [],
e7c7565d9550eaa87043aef0df77125ada996deaTripp request
828c58761d90445b8b9d20a82d85dc1479317f71Tripp );
c093c1aed867e18aa4778708592e1ceb45d18cffTripp }
828c58761d90445b8b9d20a82d85dc1479317f71Tripp };
828c58761d90445b8b9d20a82d85dc1479317f71Tripp },
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp /**
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * Returns <code>true</code> if <i>value</i> is either a function or
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * <code>null</code>.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @method _functionValidator
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @param {Function|null} value Value to validate.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @protected
828c58761d90445b8b9d20a82d85dc1479317f71Tripp */
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp _functionValidator: function (value) {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp return value === null || isFunction(value);
828c58761d90445b8b9d20a82d85dc1479317f71Tripp },
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp /**
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * Faster and safer alternative to Y.Object.getValue(). Doesn't bother
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * casting the path to an array (since we already know it's an array) and
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * doesn't throw an error if a value in the middle of the object hierarchy
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * is neither <code>undefined</code> nor an object.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @method _getObjectValue
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @param {Object} obj
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @param {Array} path
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @return {mixed} Located value, or <code>undefined</code> if the value was
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * not found at the specified path.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @protected
828c58761d90445b8b9d20a82d85dc1479317f71Tripp */
828c58761d90445b8b9d20a82d85dc1479317f71Tripp _getObjectValue: function (obj, path) {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp if (!obj) {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp return;
828c58761d90445b8b9d20a82d85dc1479317f71Tripp }
c093c1aed867e18aa4778708592e1ceb45d18cffTripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp for (var i = 0, len = path.length; obj && i < len; i++) {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp obj = obj[path[i]];
828c58761d90445b8b9d20a82d85dc1479317f71Tripp }
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp return obj;
828c58761d90445b8b9d20a82d85dc1479317f71Tripp },
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp /**
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * Parses result responses, performs filtering and highlighting, and fires
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * the <code>results</code> event.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp *
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @method _parseResponse
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @param {String} query Query that generated these results.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @param {Object} response Response containing results.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @param {Object} data Raw response data.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * @protected
828c58761d90445b8b9d20a82d85dc1479317f71Tripp */
c093c1aed867e18aa4778708592e1ceb45d18cffTripp _parseResponse: function (query, response, data) {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp var facade = {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp data : data,
828c58761d90445b8b9d20a82d85dc1479317f71Tripp query : query,
828c58761d90445b8b9d20a82d85dc1479317f71Tripp results: []
828c58761d90445b8b9d20a82d85dc1479317f71Tripp },
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp listLocator = this.get(RESULT_LIST_LOCATOR),
828c58761d90445b8b9d20a82d85dc1479317f71Tripp results = [],
828c58761d90445b8b9d20a82d85dc1479317f71Tripp unfiltered = response && response.results,
c093c1aed867e18aa4778708592e1ceb45d18cffTripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp filters,
828c58761d90445b8b9d20a82d85dc1479317f71Tripp formatted,
828c58761d90445b8b9d20a82d85dc1479317f71Tripp formatter,
828c58761d90445b8b9d20a82d85dc1479317f71Tripp highlighted,
828c58761d90445b8b9d20a82d85dc1479317f71Tripp highlighter,
828c58761d90445b8b9d20a82d85dc1479317f71Tripp i,
828c58761d90445b8b9d20a82d85dc1479317f71Tripp len,
828c58761d90445b8b9d20a82d85dc1479317f71Tripp maxResults,
828c58761d90445b8b9d20a82d85dc1479317f71Tripp result,
c093c1aed867e18aa4778708592e1ceb45d18cffTripp text,
828c58761d90445b8b9d20a82d85dc1479317f71Tripp textLocator;
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp if (unfiltered && listLocator) {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp unfiltered = listLocator.call(this, unfiltered);
828c58761d90445b8b9d20a82d85dc1479317f71Tripp }
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp if (unfiltered && unfiltered.length) {
828c58761d90445b8b9d20a82d85dc1479317f71Tripp filters = this.get('resultFilters');
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp textLocator = this.get('resultTextLocator');
828c58761d90445b8b9d20a82d85dc1479317f71Tripp
828c58761d90445b8b9d20a82d85dc1479317f71Tripp // Create a lightweight result object for each result to make them
828c58761d90445b8b9d20a82d85dc1479317f71Tripp // easier to work with. The various properties on the object
// represent different formats of the result, and will be populated
// as we go.
for (i = 0, len = unfiltered.length; i < len; ++i) {
result = unfiltered[i];
text = textLocator ?
textLocator.call(this, result) :
result.toString();
results.push({
display: Escape.html(text),
raw : result,
text : text
});
}
// Run the results through all configured result filters. Each
// filter returns an array of (potentially fewer) result objects,
// which is then passed to the next filter, and so on.
for (i = 0, len = filters.length; i < len; ++i) {
results = filters[i].call(this, query, results.concat());
if (!results) {
Y.log("Filter didn't return anything.", 'warn', 'autocomplete-base');
return;
}
if (!results.length) {
break;
}
}
if (results.length) {
formatter = this.get('resultFormatter');
highlighter = this.get('resultHighlighter');
maxResults = this.get('maxResults');
// If maxResults is set and greater than 0, limit the number of
// results.
if (maxResults && maxResults > 0 &&
results.length > maxResults) {
results.length = maxResults;
}
// Run the results through the configured highlighter (if any).
// The highlighter returns an array of highlighted strings (not
// an array of result objects), and these strings are then added
// to each result object.
if (highlighter) {
highlighted = highlighter.call(this, query,
results.concat());
if (!highlighted) {
Y.log("Highlighter didn't return anything.", 'warn', 'autocomplete-base');
return;
}
for (i = 0, len = highlighted.length; i < len; ++i) {
result = results[i];
result.highlighted = highlighted[i];
result.display = result.highlighted;
}
}
// Run the results through the configured formatter (if any) to
// produce the final formatted results. The formatter returns an
// array of strings or Node instances (not an array of result
// objects), and these strings/Nodes are then added to each
// result object.
if (formatter) {
formatted = formatter.call(this, query, results.concat());
if (!formatted) {
Y.log("Formatter didn't return anything.", 'warn', 'autocomplete-base');
return;
}
for (i = 0, len = formatted.length; i < len; ++i) {
results[i].display = formatted[i];
}
}
}
}
facade.results = results;
this.fire(EVT_RESULTS, facade);
},
/**
* <p>
* Returns the query portion of the specified input value, or
* <code>null</code> if there is no suitable query within the input value.
* </p>
*
* <p>
* If a query delimiter is defined, the query will be the last delimited
* part of of the string.
* </p>
*
* @method _parseValue
* @param {String} value Input value from which to extract the query.
* @return {String|null} query
* @protected
*/
_parseValue: function (value) {
var delim = this.get(QUERY_DELIMITER);
if (delim) {
value = value.split(delim);
value = value[value.length - 1];
}
return Lang.trimLeft(value);
},
/**
* Setter for locator attributes.
*
* @method _setLocator
* @param {Function|String|null} locator
* @return {Function|null}
* @protected
*/
_setLocator: function (locator) {
if (this[_FUNCTION_VALIDATOR](locator)) {
return locator;
}
var that = this;
locator = locator.toString().split('.');
return function (result) {
return result && that._getObjectValue(result, locator);
};
},
/**
* Setter for the <code>requestTemplate</code> attribute.
*
* @method _setRequestTemplate
* @param {Function|String|null} template
* @return {Function|null}
* @protected
*/
_setRequestTemplate: function (template) {
if (this[_FUNCTION_VALIDATOR](template)) {
return template;
}
template = template.toString();
return function (query) {
return Lang.sub(template, {query: encodeURIComponent(query)});
};
},
/**
* Setter for the <code>resultFilters</code> attribute.
*
* @method _setResultFilters
* @param {Array|Function|String|null} filters <code>null</code>, a filter
* function, an array of filter functions, or a string or array of strings
* representing the names of methods on
* <code>Y.AutoCompleteFilters</code>.
* @return {Array} Array of filter functions (empty if <i>filters</i> is
* <code>null</code>).
* @protected
*/
_setResultFilters: function (filters) {
var acFilters, getFilterFunction;
if (filters === null) {
return [];
}
acFilters = Y.AutoCompleteFilters;
getFilterFunction = function (filter) {
if (isFunction(filter)) {
return filter;
}
if (isString(filter) && acFilters &&
isFunction(acFilters[filter])) {
return acFilters[filter];
}
return false;
};
if (Lang.isArray(filters)) {
filters = YArray.map(filters, getFilterFunction);
return YArray.every(filters, function (f) { return !!f; }) ?
filters : INVALID_VALUE;
} else {
filters = getFilterFunction(filters);
return filters ? [filters] : INVALID_VALUE;
}
},
/**
* Setter for the <code>resultHighlighter</code> attribute.
*
* @method _setResultHighlighter
* @param {Function|String|null} highlighter <code>null</code>, a
* highlighter function, or a string representing the name of a method on
* <code>Y.AutoCompleteHighlighters</code>.
* @return {Function|null}
* @protected
*/
_setResultHighlighter: function (highlighter) {
var acHighlighters;
if (this._functionValidator(highlighter)) {
return highlighter;
}
acHighlighters = Y.AutoCompleteHighlighters;
if (isString(highlighter) && acHighlighters &&
isFunction(acHighlighters[highlighter])) {
return acHighlighters[highlighter];
}
return INVALID_VALUE;
},
/**
* Setter for the <code>source</code> attribute. Returns a DataSource or
* a DataSource-like object depending on the type of <i>source</i> and/or
* the value of the <code>sourceType</code> attribute.
*
* @method _setSource
* @param {mixed} source AutoComplete source. See the <code>source</code>
* attribute for details.
* @return {DataSource|Object}
* @protected
*/
_setSource: function (source) {
var sourceType = this.get('sourceType') || Lang.type(source),
sourceSetter;
if ((source && isFunction(source.sendRequest))
|| source === null
|| sourceType === 'datasource') {
// Quacks like a DataSource instance (or null). Make it so!
this._rawSource = source;
return source;
}
// See if there's a registered setter for this source type.
if ((sourceSetter = AutoCompleteBase.SOURCE_TYPES[sourceType])) {
this._rawSource = source;
return Lang.isString(sourceSetter) ?
this[sourceSetter](source) : sourceSetter(source);
}
Y.error("Unsupported source type '" + sourceType + "'. Maybe autocomplete-sources isn't loaded?");
return INVALID_VALUE;
},
/**
* Shared success callback for non-DataSource sources.
*
* @method _sourceSuccess
* @param {mixed} data Response data.
* @param {Object} request Request object.
* @protected
*/
_sourceSuccess: function (data, request) {
request.callback.success({
data: data,
response: {results: data}
});
},
/**
* Synchronizes the UI state of the <code>allowBrowserAutocomplete</code>
* attribute.
*
* @method _syncBrowserAutocomplete
* @protected
*/
_syncBrowserAutocomplete: function () {
var inputNode = this.get(INPUT_NODE);
if (inputNode.get('nodeName').toLowerCase() === 'input') {
inputNode.setAttribute('autocomplete',
this.get(ALLOW_BROWSER_AC) ? 'on' : 'off');
}
},
/**
* <p>
* Updates the query portion of the <code>value</code> attribute.
* </p>
*
* <p>
* If a query delimiter is defined, the last delimited portion of the input
* value will be replaced with the specified <i>value</i>.
* </p>
*
* @method _updateValue
* @param {String} newVal New value.
* @protected
*/
_updateValue: function (newVal) {
var delim = this.get(QUERY_DELIMITER),
insertDelim,
len,
prevVal;
newVal = Lang.trimLeft(newVal);
if (delim) {
insertDelim = trim(delim); // so we don't double up on spaces
prevVal = YArray.map(trim(this.get(VALUE)).split(delim), trim);
len = prevVal.length;
if (len > 1) {
prevVal[len - 1] = newVal;
newVal = prevVal.join(insertDelim + ' ');
}
newVal = newVal + insertDelim + ' ';
}
this.set(VALUE, newVal);
},
// -- Protected Event Handlers ---------------------------------------------
/**
* Updates the current <code>source</code> based on the new
* <code>sourceType</code> to ensure that the two attributes don't get out
* of sync when they're changed separately.
*
* @method _afterSourceTypeChange
* @param {EventFacade} e
* @protected
*/
_afterSourceTypeChange: function (e) {
if (this._rawSource) {
this.set('source', this._rawSource);
}
},
/**
* Handles change events for the <code>value</code> attribute.
*
* @method _afterValueChange
* @param {EventFacade} e
* @protected
*/
_afterValueChange: function (e) {
var delay,
fire,
minQueryLength,
newVal = e.newVal,
query,
that;
// Don't query on value changes that didn't come from the user.
if (e.src !== AutoCompleteBase.UI_SRC) {
this._inputNode.set(VALUE, newVal);
return;
}
Y.log('valueChange: new: "' + newVal + '"; old: "' + e.prevVal + '"', 'info', 'autocomplete-base');
minQueryLength = this.get('minQueryLength');
query = this._parseValue(newVal) || '';
if (minQueryLength >= 0 && query.length >= minQueryLength) {
delay = this.get('queryDelay');
that = this;
fire = function () {
that.fire(EVT_QUERY, {
inputValue: newVal,
query : query
});
};
if (delay) {
clearTimeout(this._delay);
this._delay = setTimeout(fire, delay);
} else {
fire();
}
} else {
clearTimeout(this._delay);
this.fire(EVT_CLEAR, {
prevVal: e.prevVal ? this._parseValue(e.prevVal) : null
});
}
},
/**
* Handles <code>blur</code> events on the input node.
*
* @method _onInputBlur
* @param {EventFacade} e
* @protected
*/
_onInputBlur: function (e) {
var delim = this.get(QUERY_DELIMITER),
delimPos,
newVal,
value;
// If a query delimiter is set and the input's value contains one or
// more trailing delimiters, strip them.
if (delim && !this.get('allowTrailingDelimiter')) {
delim = Lang.trimRight(delim);
value = newVal = this._inputNode.get(VALUE);
if (delim) {
while ((newVal = Lang.trimRight(newVal)) &&
(delimPos = newVal.length - delim.length) &&
newVal.lastIndexOf(delim) === delimPos) {
newVal = newVal.substring(0, delimPos);
}
} else {
// Delimiter is one or more space characters, so just trim the
// value.
newVal = Lang.trimRight(newVal);
}
if (newVal !== value) {
this.set(VALUE, newVal);
}
}
},
/**
* Handles <code>valueChange</code> events on the input node and fires a
* <code>query</code> event when the input value meets the configured
* criteria.
*
* @method _onInputValueChange
* @param {EventFacade} e
* @protected
*/
_onInputValueChange: function (e) {
var newVal = e.newVal;
// Don't query if the internal value is the same as the new value
// reported by valueChange.
if (newVal === this.get(VALUE)) {
return;
}
this.set(VALUE, newVal, {src: AutoCompleteBase.UI_SRC});
},
/**
* Handles source responses and fires the <code>results</code> event.
*
* @method _onResponse
* @param {EventFacade} e
* @protected
*/
_onResponse: function (query, e) {
// Ignore stale responses that aren't for the current query.
if (query === (this.get(QUERY) || '')) {
this._parseResponse(query || '', e.response, e.data);
}
},
// -- Protected Default Event Handlers -------------------------------------
/**
* Default <code>clear</code> event handler. Sets the <code>results</code>
* property to an empty array and <code>query</code> to null.
*
* @method _defClearFn
* @protected
*/
_defClearFn: function () {
this._set(QUERY, null);
this._set(RESULTS, []);
},
/**
* Default <code>query</code> event handler. Sets the <code>query</code>
* property and sends a request to the source if one is configured.
*
* @method _defQueryFn
* @param {EventFacade} e
* @protected
*/
_defQueryFn: function (e) {
var query = e.query;
Y.log('query: "' + query + '"; inputValue: "' + e.inputValue + '"', 'info', 'autocomplete-base');
this.sendRequest(query); // sendRequest will set the 'query' attribute
},
/**
* Default <code>results</code> event handler. Sets the <code>results</code>
* property to the latest results.
*
* @method _defResultsFn
* @param {EventFacade} e
* @protected
*/
_defResultsFn: function (e) {
Y.log('results: ' + Y.dump(e.results), 'info', 'autocomplete-base');
this._set(RESULTS, e[RESULTS]);
}
};
Y.AutoCompleteBase = AutoCompleteBase;
}, '@VERSION@' ,{optional:['autocomplete-sources'], requires:['array-extras', 'base-build', 'escape', 'event-valuechange', 'node-base']});