PageRenderTime 113ms CodeModel.GetById 60ms app.highlight 40ms RepoModel.GetById 1ms app.codeStats 1ms

/src/main/resources/org/apache/struts2/static/autocomplete/autocomplete-debug.js

http://struts2yuiplugin.googlecode.com/
JavaScript | 2908 lines | 1343 code | 279 blank | 1286 comment | 372 complexity | 4c9f18b74e0a2ac25136d6e9e77ad62b MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/*
   2Copyright (c) 2009, Yahoo! Inc. All rights reserved.
   3Code licensed under the BSD License:
   4http://developer.yahoo.net/yui/license.txt
   5version: 2.7.0
   6*/
   7/////////////////////////////////////////////////////////////////////////////
   8//
   9// YAHOO.widget.DataSource Backwards Compatibility
  10//
  11/////////////////////////////////////////////////////////////////////////////
  12
  13YAHOO.widget.DS_JSArray = YAHOO.util.LocalDataSource;
  14
  15YAHOO.widget.DS_JSFunction = YAHOO.util.FunctionDataSource;
  16
  17YAHOO.widget.DS_XHR = function(sScriptURI, aSchema, oConfigs) {
  18    var DS = new YAHOO.util.XHRDataSource(sScriptURI, oConfigs);
  19    DS._aDeprecatedSchema = aSchema;
  20    return DS;
  21};
  22
  23YAHOO.widget.DS_ScriptNode = function(sScriptURI, aSchema, oConfigs) {
  24    var DS = new YAHOO.util.ScriptNodeDataSource(sScriptURI, oConfigs);
  25    DS._aDeprecatedSchema = aSchema;
  26    return DS;
  27};
  28
  29YAHOO.widget.DS_XHR.TYPE_JSON = YAHOO.util.DataSourceBase.TYPE_JSON;
  30YAHOO.widget.DS_XHR.TYPE_XML = YAHOO.util.DataSourceBase.TYPE_XML;
  31YAHOO.widget.DS_XHR.TYPE_FLAT = YAHOO.util.DataSourceBase.TYPE_TEXT;
  32
  33// TODO: widget.DS_ScriptNode.scriptCallbackParam
  34
  35
  36
  37 /**
  38 * The AutoComplete control provides the front-end logic for text-entry suggestion and
  39 * completion functionality.
  40 *
  41 * @module autocomplete
  42 * @requires yahoo, dom, event, datasource
  43 * @optional animation
  44 * @namespace YAHOO.widget
  45 * @title AutoComplete Widget
  46 */
  47
  48/****************************************************************************/
  49/****************************************************************************/
  50/****************************************************************************/
  51
  52/**
  53 * The AutoComplete class provides the customizable functionality of a plug-and-play DHTML
  54 * auto completion widget.  Some key features:
  55 * <ul>
  56 * <li>Navigate with up/down arrow keys and/or mouse to pick a selection</li>
  57 * <li>The drop down container can "roll down" or "fly out" via configurable
  58 * animation</li>
  59 * <li>UI look-and-feel customizable through CSS, including container
  60 * attributes, borders, position, fonts, etc</li>
  61 * </ul>
  62 *
  63 * @class AutoComplete
  64 * @constructor
  65 * @param elInput {HTMLElement} DOM element reference of an input field.
  66 * @param elInput {String} String ID of an input field.
  67 * @param elContainer {HTMLElement} DOM element reference of an existing DIV.
  68 * @param elContainer {String} String ID of an existing DIV.
  69 * @param oDataSource {YAHOO.widget.DataSource} DataSource instance.
  70 * @param oConfigs {Object} (optional) Object literal of configuration params.
  71 */
  72YAHOO.widget.AutoComplete = function(elInput,elContainer,oDataSource,oConfigs) {
  73    if(elInput && elContainer && oDataSource) {
  74        // Validate DataSource
  75        if(oDataSource instanceof YAHOO.util.DataSourceBase) {
  76            this.dataSource = oDataSource;
  77        }
  78        else {
  79            YAHOO.log("Could not instantiate AutoComplete due to an invalid DataSource", "error", this.toString());
  80            return;
  81        }
  82
  83        // YAHOO.widget.DataSource schema backwards compatibility
  84        // Converted deprecated schema into supported schema
  85        // First assume key data is held in position 0 of results array
  86        this.key = 0;
  87        var schema = oDataSource.responseSchema;
  88        // An old school schema has been defined in the deprecated DataSource constructor
  89        if(oDataSource._aDeprecatedSchema) {
  90            var aDeprecatedSchema = oDataSource._aDeprecatedSchema;
  91            if(YAHOO.lang.isArray(aDeprecatedSchema)) {
  92                
  93                if((oDataSource.responseType === YAHOO.util.DataSourceBase.TYPE_JSON) || 
  94                (oDataSource.responseType === YAHOO.util.DataSourceBase.TYPE_UNKNOWN)) { // Used to default to unknown
  95                    // Store the resultsList
  96                    schema.resultsList = aDeprecatedSchema[0];
  97                    // Store the key
  98                    this.key = aDeprecatedSchema[1];
  99                    // Only resultsList and key are defined, so grab all the data
 100                    schema.fields = (aDeprecatedSchema.length < 3) ? null : aDeprecatedSchema.slice(1);
 101                }
 102                else if(oDataSource.responseType === YAHOO.util.DataSourceBase.TYPE_XML) {
 103                    schema.resultNode = aDeprecatedSchema[0];
 104                    this.key = aDeprecatedSchema[1];
 105                    schema.fields = aDeprecatedSchema.slice(1);
 106                }                
 107                else if(oDataSource.responseType === YAHOO.util.DataSourceBase.TYPE_TEXT) {
 108                    schema.recordDelim = aDeprecatedSchema[0];
 109                    schema.fieldDelim = aDeprecatedSchema[1];
 110                }                
 111                oDataSource.responseSchema = schema;
 112            }
 113        }
 114        
 115        // Validate input element
 116        if(YAHOO.util.Dom.inDocument(elInput)) {
 117            if(YAHOO.lang.isString(elInput)) {
 118                    this._sName = "instance" + YAHOO.widget.AutoComplete._nIndex + " " + elInput;
 119                    this._elTextbox = document.getElementById(elInput);
 120            }
 121            else {
 122                this._sName = (elInput.id) ?
 123                    "instance" + YAHOO.widget.AutoComplete._nIndex + " " + elInput.id:
 124                    "instance" + YAHOO.widget.AutoComplete._nIndex;
 125                this._elTextbox = elInput;
 126            }
 127            YAHOO.util.Dom.addClass(this._elTextbox, "yui-ac-input");
 128        }
 129        else {
 130            YAHOO.log("Could not instantiate AutoComplete due to an invalid input element", "error", this.toString());
 131            return;
 132        }
 133
 134        // Validate container element
 135        if(YAHOO.util.Dom.inDocument(elContainer)) {
 136            if(YAHOO.lang.isString(elContainer)) {
 137                    this._elContainer = document.getElementById(elContainer);
 138            }
 139            else {
 140                this._elContainer = elContainer;
 141            }
 142            if(this._elContainer.style.display == "none") {
 143                YAHOO.log("The container may not display properly if display is set to \"none\" in CSS", "warn", this.toString());
 144            }
 145            
 146            // For skinning
 147            var elParent = this._elContainer.parentNode;
 148            var elTag = elParent.tagName.toLowerCase();
 149            if(elTag == "div") {
 150                YAHOO.util.Dom.addClass(elParent, "yui-ac");
 151            }
 152            else {
 153                YAHOO.log("Could not find the wrapper element for skinning", "warn", this.toString());
 154            }
 155        }
 156        else {
 157            YAHOO.log("Could not instantiate AutoComplete due to an invalid container element", "error", this.toString());
 158            return;
 159        }
 160
 161        // Default applyLocalFilter setting is to enable for local sources
 162        if(this.dataSource.dataType === YAHOO.util.DataSourceBase.TYPE_LOCAL) {
 163            this.applyLocalFilter = true;
 164        }
 165        
 166        // Set any config params passed in to override defaults
 167        if(oConfigs && (oConfigs.constructor == Object)) {
 168            for(var sConfig in oConfigs) {
 169                if(sConfig) {
 170                    this[sConfig] = oConfigs[sConfig];
 171                }
 172            }
 173        }
 174
 175        // Initialization sequence
 176        this._initContainerEl();
 177        this._initProps();
 178        this._initListEl();
 179        this._initContainerHelperEls();
 180
 181        // Set up events
 182        var oSelf = this;
 183        var elTextbox = this._elTextbox;
 184
 185        // Dom events
 186        YAHOO.util.Event.addListener(elTextbox,"keyup",oSelf._onTextboxKeyUp,oSelf);
 187        YAHOO.util.Event.addListener(elTextbox,"keydown",oSelf._onTextboxKeyDown,oSelf);
 188        YAHOO.util.Event.addListener(elTextbox,"focus",oSelf._onTextboxFocus,oSelf);
 189        YAHOO.util.Event.addListener(elTextbox,"blur",oSelf._onTextboxBlur,oSelf);
 190        YAHOO.util.Event.addListener(elContainer,"mouseover",oSelf._onContainerMouseover,oSelf);
 191        YAHOO.util.Event.addListener(elContainer,"mouseout",oSelf._onContainerMouseout,oSelf);
 192        YAHOO.util.Event.addListener(elContainer,"click",oSelf._onContainerClick,oSelf);
 193        YAHOO.util.Event.addListener(elContainer,"scroll",oSelf._onContainerScroll,oSelf);
 194        YAHOO.util.Event.addListener(elContainer,"resize",oSelf._onContainerResize,oSelf);
 195        YAHOO.util.Event.addListener(elTextbox,"keypress",oSelf._onTextboxKeyPress,oSelf);
 196        YAHOO.util.Event.addListener(window,"unload",oSelf._onWindowUnload,oSelf);
 197
 198        // Custom events
 199        this.textboxFocusEvent = new YAHOO.util.CustomEvent("textboxFocus", this);
 200        this.textboxKeyEvent = new YAHOO.util.CustomEvent("textboxKey", this);
 201        this.dataRequestEvent = new YAHOO.util.CustomEvent("dataRequest", this);
 202        this.dataReturnEvent = new YAHOO.util.CustomEvent("dataReturn", this);
 203        this.dataErrorEvent = new YAHOO.util.CustomEvent("dataError", this);
 204        this.containerPopulateEvent = new YAHOO.util.CustomEvent("containerPopulate", this);
 205        this.containerExpandEvent = new YAHOO.util.CustomEvent("containerExpand", this);
 206        this.typeAheadEvent = new YAHOO.util.CustomEvent("typeAhead", this);
 207        this.itemMouseOverEvent = new YAHOO.util.CustomEvent("itemMouseOver", this);
 208        this.itemMouseOutEvent = new YAHOO.util.CustomEvent("itemMouseOut", this);
 209        this.itemArrowToEvent = new YAHOO.util.CustomEvent("itemArrowTo", this);
 210        this.itemArrowFromEvent = new YAHOO.util.CustomEvent("itemArrowFrom", this);
 211        this.itemSelectEvent = new YAHOO.util.CustomEvent("itemSelect", this);
 212        this.unmatchedItemSelectEvent = new YAHOO.util.CustomEvent("unmatchedItemSelect", this);
 213        this.selectionEnforceEvent = new YAHOO.util.CustomEvent("selectionEnforce", this);
 214        this.containerCollapseEvent = new YAHOO.util.CustomEvent("containerCollapse", this);
 215        this.textboxBlurEvent = new YAHOO.util.CustomEvent("textboxBlur", this);
 216        this.textboxChangeEvent = new YAHOO.util.CustomEvent("textboxChange", this);
 217        
 218        // Finish up
 219        elTextbox.setAttribute("autocomplete","off");
 220        YAHOO.widget.AutoComplete._nIndex++;
 221        YAHOO.log("AutoComplete initialized","info",this.toString());
 222    }
 223    // Required arguments were not found
 224    else {
 225        YAHOO.log("Could not instantiate AutoComplete due invalid arguments", "error", this.toString());
 226    }
 227};
 228
 229/////////////////////////////////////////////////////////////////////////////
 230//
 231// Public member variables
 232//
 233/////////////////////////////////////////////////////////////////////////////
 234
 235/**
 236 * The DataSource object that encapsulates the data used for auto completion.
 237 * This object should be an inherited object from YAHOO.widget.DataSource.
 238 *
 239 * @property dataSource
 240 * @type YAHOO.widget.DataSource
 241 */
 242YAHOO.widget.AutoComplete.prototype.dataSource = null;
 243
 244/**
 245 * By default, results from local DataSources will pass through the filterResults
 246 * method to apply a client-side matching algorithm. 
 247 * 
 248 * @property applyLocalFilter
 249 * @type Boolean
 250 * @default true for local arrays and json, otherwise false
 251 */
 252YAHOO.widget.AutoComplete.prototype.applyLocalFilter = null;
 253
 254/**
 255 * When applyLocalFilter is true, the local filtering algorthim can have case sensitivity
 256 * enabled. 
 257 * 
 258 * @property queryMatchCase
 259 * @type Boolean
 260 * @default false
 261 */
 262YAHOO.widget.AutoComplete.prototype.queryMatchCase = false;
 263
 264/**
 265 * When applyLocalFilter is true, results can  be locally filtered to return
 266 * matching strings that "contain" the query string rather than simply "start with"
 267 * the query string.
 268 * 
 269 * @property queryMatchContains
 270 * @type Boolean
 271 * @default false
 272 */
 273YAHOO.widget.AutoComplete.prototype.queryMatchContains = false;
 274
 275/**
 276 * Enables query subset matching. When the DataSource's cache is enabled and queryMatchSubset is
 277 * true, substrings of queries will return matching cached results. For
 278 * instance, if the first query is for "abc" susequent queries that start with
 279 * "abc", like "abcd", will be queried against the cache, and not the live data
 280 * source. Recommended only for DataSources that return comprehensive results
 281 * for queries with very few characters.
 282 *
 283 * @property queryMatchSubset
 284 * @type Boolean
 285 * @default false
 286 *
 287 */
 288YAHOO.widget.AutoComplete.prototype.queryMatchSubset = false;
 289
 290/**
 291 * Number of characters that must be entered before querying for results. A negative value
 292 * effectively turns off the widget. A value of 0 allows queries of null or empty string
 293 * values.
 294 *
 295 * @property minQueryLength
 296 * @type Number
 297 * @default 1
 298 */
 299YAHOO.widget.AutoComplete.prototype.minQueryLength = 1;
 300
 301/**
 302 * Maximum number of results to display in results container.
 303 *
 304 * @property maxResultsDisplayed
 305 * @type Number
 306 * @default 10
 307 */
 308YAHOO.widget.AutoComplete.prototype.maxResultsDisplayed = 10;
 309
 310/**
 311 * Number of seconds to delay before submitting a query request.  If a query
 312 * request is received before a previous one has completed its delay, the
 313 * previous request is cancelled and the new request is set to the delay. If 
 314 * typeAhead is also enabled, this value must always be less than the typeAheadDelay
 315 * in order to avoid certain race conditions. 
 316 *
 317 * @property queryDelay
 318 * @type Number
 319 * @default 0.2
 320 */
 321YAHOO.widget.AutoComplete.prototype.queryDelay = 0.2;
 322
 323/**
 324 * If typeAhead is true, number of seconds to delay before updating input with
 325 * typeAhead value. In order to prevent certain race conditions, this value must
 326 * always be greater than the queryDelay.
 327 *
 328 * @property typeAheadDelay
 329 * @type Number
 330 * @default 0.5
 331 */
 332YAHOO.widget.AutoComplete.prototype.typeAheadDelay = 0.5;
 333
 334/**
 335 * When IME usage is detected, AutoComplete will switch to querying the input
 336 * value at the given interval rather than per key event.
 337 *
 338 * @property queryInterval
 339 * @type Number
 340 * @default 500
 341 */
 342YAHOO.widget.AutoComplete.prototype.queryInterval = 500;
 343
 344/**
 345 * Class name of a highlighted item within results container.
 346 *
 347 * @property highlightClassName
 348 * @type String
 349 * @default "yui-ac-highlight"
 350 */
 351YAHOO.widget.AutoComplete.prototype.highlightClassName = "yui-ac-highlight";
 352
 353/**
 354 * Class name of a pre-highlighted item within results container.
 355 *
 356 * @property prehighlightClassName
 357 * @type String
 358 */
 359YAHOO.widget.AutoComplete.prototype.prehighlightClassName = null;
 360
 361/**
 362 * Query delimiter. A single character separator for multiple delimited
 363 * selections. Multiple delimiter characteres may be defined as an array of
 364 * strings. A null value or empty string indicates that query results cannot
 365 * be delimited. This feature is not recommended if you need forceSelection to
 366 * be true.
 367 *
 368 * @property delimChar
 369 * @type String | String[]
 370 */
 371YAHOO.widget.AutoComplete.prototype.delimChar = null;
 372
 373/**
 374 * Whether or not the first item in results container should be automatically highlighted
 375 * on expand.
 376 *
 377 * @property autoHighlight
 378 * @type Boolean
 379 * @default true
 380 */
 381YAHOO.widget.AutoComplete.prototype.autoHighlight = true;
 382
 383/**
 384 * If autohighlight is enabled, whether or not the input field should be automatically updated
 385 * with the first query result as the user types, auto-selecting the substring portion
 386 * of the first result that the user has not yet typed.
 387 *
 388 * @property typeAhead
 389 * @type Boolean
 390 * @default false
 391 */
 392YAHOO.widget.AutoComplete.prototype.typeAhead = false;
 393
 394/**
 395 * Whether or not to animate the expansion/collapse of the results container in the
 396 * horizontal direction.
 397 *
 398 * @property animHoriz
 399 * @type Boolean
 400 * @default false
 401 */
 402YAHOO.widget.AutoComplete.prototype.animHoriz = false;
 403
 404/**
 405 * Whether or not to animate the expansion/collapse of the results container in the
 406 * vertical direction.
 407 *
 408 * @property animVert
 409 * @type Boolean
 410 * @default true
 411 */
 412YAHOO.widget.AutoComplete.prototype.animVert = true;
 413
 414/**
 415 * Speed of container expand/collapse animation, in seconds..
 416 *
 417 * @property animSpeed
 418 * @type Number
 419 * @default 0.3
 420 */
 421YAHOO.widget.AutoComplete.prototype.animSpeed = 0.3;
 422
 423/**
 424 * Whether or not to force the user's selection to match one of the query
 425 * results. Enabling this feature essentially transforms the input field into a
 426 * &lt;select&gt; field. This feature is not recommended with delimiter character(s)
 427 * defined.
 428 *
 429 * @property forceSelection
 430 * @type Boolean
 431 * @default false
 432 */
 433YAHOO.widget.AutoComplete.prototype.forceSelection = false;
 434
 435/**
 436 * Whether or not to allow browsers to cache user-typed input in the input
 437 * field. Disabling this feature will prevent the widget from setting the
 438 * autocomplete="off" on the input field. When autocomplete="off"
 439 * and users click the back button after form submission, user-typed input can
 440 * be prefilled by the browser from its cache. This caching of user input may
 441 * not be desired for sensitive data, such as credit card numbers, in which
 442 * case, implementers should consider setting allowBrowserAutocomplete to false.
 443 *
 444 * @property allowBrowserAutocomplete
 445 * @type Boolean
 446 * @default true
 447 */
 448YAHOO.widget.AutoComplete.prototype.allowBrowserAutocomplete = true;
 449
 450/**
 451 * Enabling this feature prevents the toggling of the container to a collapsed state.
 452 * Setting to true does not automatically trigger the opening of the container.
 453 * Implementers are advised to pre-load the container with an explicit "sendQuery()" call.   
 454 *
 455 * @property alwaysShowContainer
 456 * @type Boolean
 457 * @default false
 458 */
 459YAHOO.widget.AutoComplete.prototype.alwaysShowContainer = false;
 460
 461/**
 462 * Whether or not to use an iFrame to layer over Windows form elements in
 463 * IE. Set to true only when the results container will be on top of a
 464 * &lt;select&gt; field in IE and thus exposed to the IE z-index bug (i.e.,
 465 * 5.5 < IE < 7).
 466 *
 467 * @property useIFrame
 468 * @type Boolean
 469 * @default false
 470 */
 471YAHOO.widget.AutoComplete.prototype.useIFrame = false;
 472
 473/**
 474 * Whether or not the results container should have a shadow.
 475 *
 476 * @property useShadow
 477 * @type Boolean
 478 * @default false
 479 */
 480YAHOO.widget.AutoComplete.prototype.useShadow = false;
 481
 482/**
 483 * Whether or not the input field should be updated with selections.
 484 *
 485 * @property suppressInputUpdate
 486 * @type Boolean
 487 * @default false
 488 */
 489YAHOO.widget.AutoComplete.prototype.suppressInputUpdate = false;
 490
 491/**
 492 * For backward compatibility to pre-2.6.0 formatResults() signatures, setting
 493 * resultsTypeList to true will take each object literal result returned by
 494 * DataSource and flatten into an array.  
 495 *
 496 * @property resultTypeList
 497 * @type Boolean
 498 * @default true
 499 */
 500YAHOO.widget.AutoComplete.prototype.resultTypeList = true;
 501
 502/**
 503 * For XHR DataSources, AutoComplete will automatically insert a "?" between the server URI and 
 504 * the "query" param/value pair. To prevent this behavior, implementers should
 505 * set this value to false. To more fully customize the query syntax, implementers
 506 * should override the generateRequest() method. 
 507 *
 508 * @property queryQuestionMark
 509 * @type Boolean
 510 * @default true
 511 */
 512YAHOO.widget.AutoComplete.prototype.queryQuestionMark = true;
 513
 514/////////////////////////////////////////////////////////////////////////////
 515//
 516// Public methods
 517//
 518/////////////////////////////////////////////////////////////////////////////
 519
 520 /**
 521 * Public accessor to the unique name of the AutoComplete instance.
 522 *
 523 * @method toString
 524 * @return {String} Unique name of the AutoComplete instance.
 525 */
 526YAHOO.widget.AutoComplete.prototype.toString = function() {
 527    return "AutoComplete " + this._sName;
 528};
 529
 530 /**
 531 * Returns DOM reference to input element.
 532 *
 533 * @method getInputEl
 534 * @return {HTMLELement} DOM reference to input element.
 535 */
 536YAHOO.widget.AutoComplete.prototype.getInputEl = function() {
 537    return this._elTextbox;
 538};
 539
 540 /**
 541 * Returns DOM reference to container element.
 542 *
 543 * @method getContainerEl
 544 * @return {HTMLELement} DOM reference to container element.
 545 */
 546YAHOO.widget.AutoComplete.prototype.getContainerEl = function() {
 547    return this._elContainer;
 548};
 549
 550 /**
 551 * Returns true if widget instance is currently focused.
 552 *
 553 * @method isFocused
 554 * @return {Boolean} Returns true if widget instance is currently focused.
 555 */
 556YAHOO.widget.AutoComplete.prototype.isFocused = function() {
 557    return (this._bFocused === null) ? false : this._bFocused;
 558};
 559
 560 /**
 561 * Returns true if container is in an expanded state, false otherwise.
 562 *
 563 * @method isContainerOpen
 564 * @return {Boolean} Returns true if container is in an expanded state, false otherwise.
 565 */
 566YAHOO.widget.AutoComplete.prototype.isContainerOpen = function() {
 567    return this._bContainerOpen;
 568};
 569
 570/**
 571 * Public accessor to the &lt;ul&gt; element that displays query results within the results container.
 572 *
 573 * @method getListEl
 574 * @return {HTMLElement[]} Reference to &lt;ul&gt; element within the results container.
 575 */
 576YAHOO.widget.AutoComplete.prototype.getListEl = function() {
 577    return this._elList;
 578};
 579
 580/**
 581 * Public accessor to the matching string associated with a given &lt;li&gt; result.
 582 *
 583 * @method getListItemMatch
 584 * @param elListItem {HTMLElement} Reference to &lt;LI&gt; element.
 585 * @return {String} Matching string.
 586 */
 587YAHOO.widget.AutoComplete.prototype.getListItemMatch = function(elListItem) {
 588    if(elListItem._sResultMatch) {
 589        return elListItem._sResultMatch;
 590    }
 591    else {
 592        return null;
 593    }
 594};
 595
 596/**
 597 * Public accessor to the result data associated with a given &lt;li&gt; result.
 598 *
 599 * @method getListItemData
 600 * @param elListItem {HTMLElement} Reference to &lt;LI&gt; element.
 601 * @return {Object} Result data.
 602 */
 603YAHOO.widget.AutoComplete.prototype.getListItemData = function(elListItem) {
 604    if(elListItem._oResultData) {
 605        return elListItem._oResultData;
 606    }
 607    else {
 608        return null;
 609    }
 610};
 611
 612/**
 613 * Public accessor to the index of the associated with a given &lt;li&gt; result.
 614 *
 615 * @method getListItemIndex
 616 * @param elListItem {HTMLElement} Reference to &lt;LI&gt; element.
 617 * @return {Number} Index.
 618 */
 619YAHOO.widget.AutoComplete.prototype.getListItemIndex = function(elListItem) {
 620    if(YAHOO.lang.isNumber(elListItem._nItemIndex)) {
 621        return elListItem._nItemIndex;
 622    }
 623    else {
 624        return null;
 625    }
 626};
 627
 628/**
 629 * Sets HTML markup for the results container header. This markup will be
 630 * inserted within a &lt;div&gt; tag with a class of "yui-ac-hd".
 631 *
 632 * @method setHeader
 633 * @param sHeader {String} HTML markup for results container header.
 634 */
 635YAHOO.widget.AutoComplete.prototype.setHeader = function(sHeader) {
 636    if(this._elHeader) {
 637        var elHeader = this._elHeader;
 638        if(sHeader) {
 639            elHeader.innerHTML = sHeader;
 640            elHeader.style.display = "block";
 641        }
 642        else {
 643            elHeader.innerHTML = "";
 644            elHeader.style.display = "none";
 645        }
 646    }
 647};
 648
 649/**
 650 * Sets HTML markup for the results container footer. This markup will be
 651 * inserted within a &lt;div&gt; tag with a class of "yui-ac-ft".
 652 *
 653 * @method setFooter
 654 * @param sFooter {String} HTML markup for results container footer.
 655 */
 656YAHOO.widget.AutoComplete.prototype.setFooter = function(sFooter) {
 657    if(this._elFooter) {
 658        var elFooter = this._elFooter;
 659        if(sFooter) {
 660                elFooter.innerHTML = sFooter;
 661                elFooter.style.display = "block";
 662        }
 663        else {
 664            elFooter.innerHTML = "";
 665            elFooter.style.display = "none";
 666        }
 667    }
 668};
 669
 670/**
 671 * Sets HTML markup for the results container body. This markup will be
 672 * inserted within a &lt;div&gt; tag with a class of "yui-ac-bd".
 673 *
 674 * @method setBody
 675 * @param sBody {String} HTML markup for results container body.
 676 */
 677YAHOO.widget.AutoComplete.prototype.setBody = function(sBody) {
 678    if(this._elBody) {
 679        var elBody = this._elBody;
 680        YAHOO.util.Event.purgeElement(elBody, true);
 681        if(sBody) {
 682            elBody.innerHTML = sBody;
 683            elBody.style.display = "block";
 684        }
 685        else {
 686            elBody.innerHTML = "";
 687            elBody.style.display = "none";
 688        }
 689        this._elList = null;
 690    }
 691};
 692
 693/**
 694* A function that converts an AutoComplete query into a request value which is then
 695* passed to the DataSource's sendRequest method in order to retrieve data for 
 696* the query. By default, returns a String with the syntax: "query={query}"
 697* Implementers can customize this method for custom request syntaxes.
 698* 
 699* @method generateRequest
 700* @param sQuery {String} Query string
 701* @return {MIXED} Request
 702*/
 703YAHOO.widget.AutoComplete.prototype.generateRequest = function(sQuery) {
 704    var dataType = this.dataSource.dataType;
 705    
 706    // Transform query string in to a request for remote data
 707    // By default, local data doesn't need a transformation, just passes along the query as is.
 708    if(dataType === YAHOO.util.DataSourceBase.TYPE_XHR) {
 709        // By default, XHR GET requests look like "{scriptURI}?{scriptQueryParam}={sQuery}&{scriptQueryAppend}"
 710        if(!this.dataSource.connMethodPost) {
 711            sQuery = (this.queryQuestionMark ? "?" : "") + (this.dataSource.scriptQueryParam || "query") + "=" + sQuery + 
 712                (this.dataSource.scriptQueryAppend ? ("&" + this.dataSource.scriptQueryAppend) : "");        
 713        }
 714        // By default, XHR POST bodies are sent to the {scriptURI} like "{scriptQueryParam}={sQuery}&{scriptQueryAppend}"
 715        else {
 716            sQuery = (this.dataSource.scriptQueryParam || "query") + "=" + sQuery + 
 717                (this.dataSource.scriptQueryAppend ? ("&" + this.dataSource.scriptQueryAppend) : "");
 718        }
 719    }
 720    // By default, remote script node requests look like "{scriptURI}&{scriptCallbackParam}={callbackString}&{scriptQueryParam}={sQuery}&{scriptQueryAppend}"
 721    else if(dataType === YAHOO.util.DataSourceBase.TYPE_SCRIPTNODE) {
 722        sQuery = "&" + (this.dataSource.scriptQueryParam || "query") + "=" + sQuery + 
 723            (this.dataSource.scriptQueryAppend ? ("&" + this.dataSource.scriptQueryAppend) : "");    
 724    }
 725    
 726    return sQuery;
 727};
 728
 729/**
 730 * Makes query request to the DataSource.
 731 *
 732 * @method sendQuery
 733 * @param sQuery {String} Query string.
 734 */
 735YAHOO.widget.AutoComplete.prototype.sendQuery = function(sQuery) {
 736    // Reset focus for a new interaction
 737    this._bFocused = null;
 738    
 739    // Adjust programatically sent queries to look like they were input by user
 740    // when delimiters are enabled
 741    var newQuery = (this.delimChar) ? this._elTextbox.value + sQuery : sQuery;
 742    this._sendQuery(newQuery);
 743};
 744
 745/**
 746 * Collapses container.
 747 *
 748 * @method collapseContainer
 749 */
 750YAHOO.widget.AutoComplete.prototype.collapseContainer = function() {
 751    this._toggleContainer(false);
 752};
 753
 754/**
 755 * Handles subset matching for when queryMatchSubset is enabled.
 756 *
 757 * @method getSubsetMatches
 758 * @param sQuery {String} Query string.
 759 * @return {Object} oParsedResponse or null. 
 760 */
 761YAHOO.widget.AutoComplete.prototype.getSubsetMatches = function(sQuery) {
 762    var subQuery, oCachedResponse, subRequest;
 763    // Loop through substrings of each cached element's query property...
 764    for(var i = sQuery.length; i >= this.minQueryLength ; i--) {
 765        subRequest = this.generateRequest(sQuery.substr(0,i));
 766        this.dataRequestEvent.fire(this, subQuery, subRequest);
 767        YAHOO.log("Searching for query subset \"" + subQuery + "\" in cache", "info", this.toString());
 768        
 769        // If a substring of the query is found in the cache
 770        oCachedResponse = this.dataSource.getCachedResponse(subRequest);
 771        if(oCachedResponse) {
 772            YAHOO.log("Found match for query subset \"" + subQuery + "\": " + YAHOO.lang.dump(oCachedResponse), "info", this.toString());
 773            return this.filterResults.apply(this.dataSource, [sQuery, oCachedResponse, oCachedResponse, {scope:this}]);
 774        }
 775    }
 776    YAHOO.log("Did not find subset match for query subset \"" + sQuery + "\"" , "info", this.toString());
 777    return null;
 778};
 779
 780/**
 781 * Executed by DataSource (within DataSource scope via doBeforeParseData()) to
 782 * handle responseStripAfter cleanup.
 783 *
 784 * @method preparseRawResponse
 785 * @param sQuery {String} Query string.
 786 * @return {Object} oParsedResponse or null. 
 787 */
 788YAHOO.widget.AutoComplete.prototype.preparseRawResponse = function(oRequest, oFullResponse, oCallback) {
 789    var nEnd = ((this.responseStripAfter !== "") && (oFullResponse.indexOf)) ?
 790        oFullResponse.indexOf(this.responseStripAfter) : -1;
 791    if(nEnd != -1) {
 792        oFullResponse = oFullResponse.substring(0,nEnd);
 793    }
 794    return oFullResponse;
 795};
 796
 797/**
 798 * Executed by DataSource (within DataSource scope via doBeforeCallback()) to
 799 * filter results through a simple client-side matching algorithm. 
 800 *
 801 * @method filterResults
 802 * @param sQuery {String} Original request.
 803 * @param oFullResponse {Object} Full response object.
 804 * @param oParsedResponse {Object} Parsed response object.
 805 * @param oCallback {Object} Callback object. 
 806 * @return {Object} Filtered response object.
 807 */
 808
 809YAHOO.widget.AutoComplete.prototype.filterResults = function(sQuery, oFullResponse, oParsedResponse, oCallback) {
 810    // If AC has passed a query string value back to itself, grab it
 811    if(oCallback && oCallback.argument && oCallback.argument.query) {
 812        sQuery = oCallback.argument.query;
 813    }
 814
 815    // Only if a query string is available to match against
 816    if(sQuery && sQuery !== "") {
 817        // First make a copy of the oParseResponse
 818        oParsedResponse = YAHOO.widget.AutoComplete._cloneObject(oParsedResponse);
 819        
 820        var oAC = oCallback.scope,
 821            oDS = this,
 822            allResults = oParsedResponse.results, // the array of results
 823            filteredResults = [], // container for filtered results
 824            bMatchFound = false,
 825            bMatchCase = (oDS.queryMatchCase || oAC.queryMatchCase), // backward compat
 826            bMatchContains = (oDS.queryMatchContains || oAC.queryMatchContains); // backward compat
 827            
 828        // Loop through each result object...
 829        for(var i = allResults.length-1; i >= 0; i--) {
 830            var oResult = allResults[i];
 831
 832            // Grab the data to match against from the result object...
 833            var sResult = null;
 834            
 835            // Result object is a simple string already
 836            if(YAHOO.lang.isString(oResult)) {
 837                sResult = oResult;
 838            }
 839            // Result object is an array of strings
 840            else if(YAHOO.lang.isArray(oResult)) {
 841                sResult = oResult[0];
 842            
 843            }
 844            // Result object is an object literal of strings
 845            else if(this.responseSchema.fields) {
 846                var key = this.responseSchema.fields[0].key || this.responseSchema.fields[0];
 847                sResult = oResult[key];
 848            }
 849            // Backwards compatibility
 850            else if(this.key) {
 851                sResult = oResult[this.key];
 852            }
 853            
 854            if(YAHOO.lang.isString(sResult)) {
 855                
 856                var sKeyIndex = (bMatchCase) ?
 857                sResult.indexOf(decodeURIComponent(sQuery)) :
 858                sResult.toLowerCase().indexOf(decodeURIComponent(sQuery).toLowerCase());
 859
 860                // A STARTSWITH match is when the query is found at the beginning of the key string...
 861                if((!bMatchContains && (sKeyIndex === 0)) ||
 862                // A CONTAINS match is when the query is found anywhere within the key string...
 863                (bMatchContains && (sKeyIndex > -1))) {
 864                    // Stash the match
 865                    filteredResults.unshift(oResult);
 866                }
 867            }
 868        }
 869        oParsedResponse.results = filteredResults;
 870        YAHOO.log("Filtered " + filteredResults.length + " results against query \""  + sQuery + "\": " + YAHOO.lang.dump(filteredResults), "info", this.toString());
 871    }
 872    else {
 873        YAHOO.log("Did not filter results against query", "info", this.toString());
 874    }
 875    
 876    return oParsedResponse;
 877};
 878
 879/**
 880 * Handles response for display. This is the callback function method passed to
 881 * YAHOO.util.DataSourceBase#sendRequest so results from the DataSource are
 882 * returned to the AutoComplete instance.
 883 *
 884 * @method handleResponse
 885 * @param sQuery {String} Original request.
 886 * @param oResponse {Object} Response object.
 887 * @param oPayload {MIXED} (optional) Additional argument(s)
 888 */
 889YAHOO.widget.AutoComplete.prototype.handleResponse = function(sQuery, oResponse, oPayload) {
 890    if((this instanceof YAHOO.widget.AutoComplete) && this._sName) {
 891        this._populateList(sQuery, oResponse, oPayload);
 892    }
 893};
 894
 895/**
 896 * Overridable method called before container is loaded with result data.
 897 *
 898 * @method doBeforeLoadData
 899 * @param sQuery {String} Original request.
 900 * @param oResponse {Object} Response object.
 901 * @param oPayload {MIXED} (optional) Additional argument(s)
 902 * @return {Boolean} Return true to continue loading data, false to cancel.
 903 */
 904YAHOO.widget.AutoComplete.prototype.doBeforeLoadData = function(sQuery, oResponse, oPayload) {
 905    return true;
 906};
 907
 908/**
 909 * Overridable method that returns HTML markup for one result to be populated
 910 * as innerHTML of an &lt;LI&gt; element. 
 911 *
 912 * @method formatResult
 913 * @param oResultData {Object} Result data object.
 914 * @param sQuery {String} The corresponding query string.
 915 * @param sResultMatch {HTMLElement} The current query string. 
 916 * @return {String} HTML markup of formatted result data.
 917 */
 918YAHOO.widget.AutoComplete.prototype.formatResult = function(oResultData, sQuery, sResultMatch) {
 919    var sMarkup = (sResultMatch) ? sResultMatch : "";
 920    return sMarkup;
 921};
 922
 923/**
 924 * Overridable method called before container expands allows implementers to access data
 925 * and DOM elements.
 926 *
 927 * @method doBeforeExpandContainer
 928 * @param elTextbox {HTMLElement} The text input box.
 929 * @param elContainer {HTMLElement} The container element.
 930 * @param sQuery {String} The query string.
 931 * @param aResults {Object[]}  An array of query results.
 932 * @return {Boolean} Return true to continue expanding container, false to cancel the expand.
 933 */
 934YAHOO.widget.AutoComplete.prototype.doBeforeExpandContainer = function(elTextbox, elContainer, sQuery, aResults) {
 935    return true;
 936};
 937
 938
 939/**
 940 * Nulls out the entire AutoComplete instance and related objects, removes attached
 941 * event listeners, and clears out DOM elements inside the container. After
 942 * calling this method, the instance reference should be expliclitly nulled by
 943 * implementer, as in myAutoComplete = null. Use with caution!
 944 *
 945 * @method destroy
 946 */
 947YAHOO.widget.AutoComplete.prototype.destroy = function() {
 948    var instanceName = this.toString();
 949    var elInput = this._elTextbox;
 950    var elContainer = this._elContainer;
 951
 952    // Unhook custom events
 953    this.textboxFocusEvent.unsubscribeAll();
 954    this.textboxKeyEvent.unsubscribeAll();
 955    this.dataRequestEvent.unsubscribeAll();
 956    this.dataReturnEvent.unsubscribeAll();
 957    this.dataErrorEvent.unsubscribeAll();
 958    this.containerPopulateEvent.unsubscribeAll();
 959    this.containerExpandEvent.unsubscribeAll();
 960    this.typeAheadEvent.unsubscribeAll();
 961    this.itemMouseOverEvent.unsubscribeAll();
 962    this.itemMouseOutEvent.unsubscribeAll();
 963    this.itemArrowToEvent.unsubscribeAll();
 964    this.itemArrowFromEvent.unsubscribeAll();
 965    this.itemSelectEvent.unsubscribeAll();
 966    this.unmatchedItemSelectEvent.unsubscribeAll();
 967    this.selectionEnforceEvent.unsubscribeAll();
 968    this.containerCollapseEvent.unsubscribeAll();
 969    this.textboxBlurEvent.unsubscribeAll();
 970    this.textboxChangeEvent.unsubscribeAll();
 971
 972    // Unhook DOM events
 973    YAHOO.util.Event.purgeElement(elInput, true);
 974    YAHOO.util.Event.purgeElement(elContainer, true);
 975
 976    // Remove DOM elements
 977    elContainer.innerHTML = "";
 978
 979    // Null out objects
 980    for(var key in this) {
 981        if(YAHOO.lang.hasOwnProperty(this, key)) {
 982            this[key] = null;
 983        }
 984    }
 985
 986    YAHOO.log("AutoComplete instance destroyed: " + instanceName);
 987};
 988
 989/////////////////////////////////////////////////////////////////////////////
 990//
 991// Public events
 992//
 993/////////////////////////////////////////////////////////////////////////////
 994
 995/**
 996 * Fired when the input field receives focus.
 997 *
 998 * @event textboxFocusEvent
 999 * @param oSelf {YAHOO.widget.AutoComplete} The AutoComplete instance.
1000 */
1001YAHOO.widget.AutoComplete.prototype.textboxFocusEvent = null;
1002
1003/**
1004 * Fired when the input field receives key input.
1005 *
1006 * @event textboxKeyEvent
1007 * @param oSelf {YAHOO.widget.AutoComplete} The AutoComplete instance.
1008 * @param nKeycode {Number} The keycode number.
1009 */
1010YAHOO.widget.AutoComplete.prototype.textboxKeyEvent = null;
1011
1012/**
1013 * Fired when the AutoComplete instance makes a request to the DataSource.
1014 * 
1015 * @event dataRequestEvent
1016 * @param oSelf {YAHOO.widget.AutoComplete} The AutoComplete instance.
1017 * @param sQuery {String} The query string. 
1018 * @param oRequest {Object} The request.
1019 */
1020YAHOO.widget.AutoComplete.prototype.dataRequestEvent = null;
1021
1022/**
1023 * Fired when the AutoComplete instance receives query results from the data
1024 * source.
1025 *
1026 * @event dataReturnEvent
1027 * @param oSelf {YAHOO.widget.AutoComplete} The AutoComplete instance.
1028 * @param sQuery {String} The query string.
1029 * @param aResults {Object[]} Results array.
1030 */
1031YAHOO.widget.AutoComplete.prototype.dataReturnEvent = null;
1032
1033/**
1034 * Fired when the AutoComplete instance does not receive query results from the
1035 * DataSource due to an error.
1036 *
1037 * @event dataErrorEvent
1038 * @param oSelf {YAHOO.widget.AutoComplete} The AutoComplete instance.
1039 * @param sQuery {String} The query string.
1040 */
1041YAHOO.widget.AutoComplete.prototype.dataErrorEvent = null;
1042
1043/**
1044 * Fired when the results container is populated.
1045 *
1046 * @event containerPopulateEvent
1047 * @param oSelf {YAHOO.widget.AutoComplete} The AutoComplete instance.
1048 */
1049YAHOO.widget.AutoComplete.prototype.containerPopulateEvent = null;
1050
1051/**
1052 * Fired when the results container is expanded.
1053 *
1054 * @event containerExpandEvent
1055 * @param oSelf {YAHOO.widget.AutoComplete} The AutoComplete instance.
1056 */
1057YAHOO.widget.AutoComplete.prototype.containerExpandEvent = null;
1058
1059/**
1060 * Fired when the input field has been prefilled by the type-ahead
1061 * feature. 
1062 *
1063 * @event typeAheadEvent
1064 * @param oSelf {YAHOO.widget.AutoComplete} The AutoComplete instance.
1065 * @param sQuery {String} The query string.
1066 * @param sPrefill {String} The prefill string.
1067 */
1068YAHOO.widget.AutoComplete.prototype.typeAheadEvent = null;
1069
1070/**
1071 * Fired when result item has been moused over.
1072 *
1073 * @event itemMouseOverEvent
1074 * @param oSelf {YAHOO.widget.AutoComplete} The AutoComplete instance.
1075 * @param elItem {HTMLElement} The &lt;li&gt element item moused to.
1076 */
1077YAHOO.widget.AutoComplete.prototype.itemMouseOverEvent = null;
1078
1079/**
1080 * Fired when result item has been moused out.
1081 *
1082 * @event itemMouseOutEvent
1083 * @param oSelf {YAHOO.widget.AutoComplete} The AutoComplete instance.
1084 * @param elItem {HTMLElement} The &lt;li&gt; element item moused from.
1085 */
1086YAHOO.widget.AutoComplete.prototype.itemMouseOutEvent = null;
1087
1088/**
1089 * Fired when result item has been arrowed to. 
1090 *
1091 * @event itemArrowToEvent
1092 * @param oSelf {YAHOO.widget.AutoComplete} The AutoComplete instance.
1093 * @param elItem {HTMLElement} The &lt;li&gt; element item arrowed to.
1094 */
1095YAHOO.widget.AutoComplete.prototype.itemArrowToEvent = null;
1096
1097/**
1098 * Fired when result item has been arrowed away from.
1099 *
1100 * @event itemArrowFromEvent
1101 * @param oSelf {YAHOO.widget.AutoComplete} The AutoComplete instance.
1102 * @param elItem {HTMLElement} The &lt;li&gt; element item arrowed from.
1103 */
1104YAHOO.widget.AutoComplete.prototype.itemArrowFromEvent = null;
1105
1106/**
1107 * Fired when an item is selected via mouse click, ENTER key, or TAB key.
1108 *
1109 * @event itemSelectEvent
1110 * @param oSelf {YAHOO.widget.AutoComplete} The AutoComplete instance.
1111 * @param elItem {HTMLElement} The selected &lt;li&gt; element item.
1112 * @param oData {Object} The data returned for the item, either as an object,
1113 * or mapped from the schema into an array.
1114 */
1115YAHOO.widget.AutoComplete.prototype.itemSelectEvent = null;
1116
1117/**
1118 * Fired when a user selection does not match any of the displayed result items.
1119 *
1120 * @event unmatchedItemSelectEvent
1121 * @param oSelf {YAHOO.widget.AutoComplete} The AutoComplete instance.
1122 * @param sSelection {String} The selected string.  
1123 */
1124YAHOO.widget.AutoComplete.prototype.unmatchedItemSelectEvent = null;
1125
1126/**
1127 * Fired if forceSelection is enabled and the user's input has been cleared
1128 * because it did not match one of the returned query results.
1129 *
1130 * @event selectionEnforceEvent
1131 * @param oSelf {YAHOO.widget.AutoComplete} The AutoComplete instance.
1132 * @param sClearedValue {String} The cleared value (including delimiters if applicable). 
1133 */
1134YAHOO.widget.AutoComplete.prototype.selectionEnforceEvent = null;
1135
1136/**
1137 * Fired when the results container is collapsed.
1138 *
1139 * @event containerCollapseEvent
1140 * @param oSelf {YAHOO.widget.AutoComplete} The AutoComplete instance.
1141 */
1142YAHOO.widget.AutoComplete.prototype.containerCollapseEvent = null;
1143
1144/**
1145 * Fired when the input field loses focus.
1146 *
1147 * @event textboxBlurEvent
1148 * @param oSelf {YAHOO.widget.AutoComplete} The AutoComplete instance.
1149 */
1150YAHOO.widget.AutoComplete.prototype.textboxBlurEvent = null;
1151
1152/**
1153 * Fired when the input field value has changed when it loses focus.
1154 *
1155 * @event textboxChangeEvent
1156 * @param oSelf {YAHOO.widget.AutoComplete} The AutoComplete instance.
1157 */
1158YAHOO.widget.AutoComplete.prototype.textboxChangeEvent = null;
1159
1160/////////////////////////////////////////////////////////////////////////////
1161//
1162// Private member variables
1163//
1164/////////////////////////////////////////////////////////////////////////////
1165
1166/**
1167 * Internal class variable to index multiple AutoComplete instances.
1168 *
1169 * @property _nIndex
1170 * @type Number
1171 * @default 0
1172 * @private
1173 */
1174YAHOO.widget.AutoComplete._nIndex = 0;
1175
1176/**
1177 * Name of AutoComplete instance.
1178 *
1179 * @property _sName
1180 * @type String
1181 * @private
1182 */
1183YAHOO.widget.AutoComplete.prototype._sName = null;
1184
1185/**
1186 * Text input field DOM element.
1187 *
1188 * @property _elTextbox
1189 * @type HTMLElement
1190 * @private
1191 */
1192YAHOO.widget.AutoComplete.prototype._elTextbox = null;
1193
1194/**
1195 * Container DOM element.
1196 *
1197 * @property _elContainer
1198 * @type HTMLElement
1199 * @private
1200 */
1201YAHOO.widget.AutoComplete.prototype._elContainer = null;
1202
1203/**
1204 * Reference to content element within container element.
1205 *
1206 * @property _elContent
1207 * @type HTMLElement
1208 * @private
1209 */
1210YAHOO.widget.AutoComplete.prototype._elContent = null;
1211
1212/**
1213 * Reference to header element within content element.
1214 *
1215 * @property _elHeader
1216 * @type HTMLElement
1217 * @private
1218 */
1219YAHOO.widget.AutoComplete.prototype._elHeader = null;
1220
1221/**
1222 * Reference to body element within content element.
1223 *
1224 * @property _elBody
1225 * @type HTMLElement
1226 * @private
1227 */
1228YAHOO.widget.AutoComplete.prototype._elBody = null;
1229
1230/**
1231 * Reference to footer element within content element.
1232 *
1233 * @property _elFooter
1234 * @type HTMLElement
1235 * @private
1236 */
1237YAHOO.widget.AutoComplete.prototype._elFooter = null;
1238
1239/**
1240 * Reference to shadow element within container element.
1241 *
1242 * @property _elShadow
1243 * @type HTMLElement
1244 * @private
1245 */
1246YAHOO.widget.AutoComplete.prototype._elShadow = null;
1247
1248/**
1249 * Reference to iframe element within container element.
1250 *
1251 * @property _elIFrame
1252 * @type HTMLElement
1253 * @private
1254 */
1255YAHOO.widget.AutoComplete.prototype._elIFrame = null;
1256
1257/**
1258 * Whether or not the input field is currently in focus. If query results come back
1259 * but the user has already moved on, do not proceed with auto complete behavior.
1260 *
1261 * @property _bFocused
1262 * @type Boolean
1263 * @private
1264 */
1265YAHOO.widget.AutoComplete.prototype._bFocused = null;
1266
1267/**
1268 * Animation instance for container expand/collapse.
1269 *
1270 * @property _oAnim
1271 * @type Boolean
1272 * @private
1273 */
1274YAHOO.widget.AutoComplete.prototype._oAnim = null;
1275
1276/**
1277 * Whether or not the results container is currently open.
1278 *
1279 * @property _bContainerOpen
1280 * @type Boolean
1281 * @private
1282 */
1283YAHOO.widget.AutoComplete.prototype._bContainerOpen = false;
1284
1285/**
1286 * Whether or not the mouse is currently over the results
1287 * container. This is necessary in order to prevent clicks on container items
1288 * from being text input field blur events.
1289 *
1290 * @property _bOverContainer
1291 * @type Boolean
1292 * @private
1293 */
1294YAHOO.widget.AutoComplete.prototype._bOverContainer = false;
1295
1296/**
1297 * Internal reference to &lt;ul&gt; elements that contains query results within the
1298 * results container.
1299 *
1300 * @property _elList
1301 * @type HTMLElement
1302 * @private
1303 */
1304YAHOO.widget.AutoComplete.prototype._elList = null;
1305
1306/*
1307 * Array of &lt;li&gt; elements references that contain query results within the
1308 * results container.
1309 *
1310 * @property _aListItemEls
1311 * @type HTMLElement[]
1312 * @private
1313 */
1314//YAHOO.widget.AutoComplete.prototype._aListItemEls = null;
1315
1316/**
1317 * Number of &lt;li&gt; elements currently displayed in results container.
1318 *
1319 * @property _nDisplayedItems
1320 * @type Number
1321 * @private
1322 */
1323YAHOO.widget.AutoComplete.prototype._nDisplayedItems = 0;
1324
1325/*
1326 * Internal count of &lt;li&gt; elements displayed and hidden in results container.
1327 *
1328 * @property _maxResultsDisplayed
1329 * @type Number
1330 * @private
1331 */
1332//YAHOO.widget.AutoComplete.prototype._maxResultsDisplayed = 0;
1333
1334/**
1335 * Current query string
1336 *
1337 * @property _sCurQuery
1338 * @type String
1339 * @private
1340 */
1341YAHOO.widget.AutoComplete.prototype._sCurQuery = null;
1342
1343/**
1344 * Selections from previous queries (for saving delimited queries).
1345 *
1346 * @property _sPastSelections
1347 * @type String
1348 * @default "" 
1349 * @private
1350 */
1351YAHOO.widget.AutoComplete.prototype._sPastSelections = "";
1352
1353/**
1354 * Stores initial input value used to determine if textboxChangeEvent should be fired.
1355 *
1356 * @property _sInitInputValue
1357 * @type String
1358 * @private
1359 */
1360YAHOO.widget.AutoComplete.prototype._sInitInputValue = null;
1361
1362/**
1363 * Pointer to the currently highlighted &lt;li&gt; element in the container.
1364 *
1365 * @property _elCurListItem
1366 * @type HTMLElement
1367 * @private
1368 */
1369YAHOO.widget.AutoComplete.prototype._elCurListItem = null;
1370
1371/**
1372 * Whether or not an item has been selected since the container was populated
1373 * with results. Reset to false by _populateList, and set to true when item is
1374 * selected.
1375 *
1376 * @property _bItemSelected
1377 * @type Boolean
1378 * @private
1379 */
1380YAHOO.widget.AutoComplete.prototype._bItemSelected = false;
1381
1382/**
1383 * Key code of the last key pressed in textbox.
1384 *
1385 * @property _nKeyCode
1386 * @type Number
1387 * @private
1388 */
1389YAHOO.widget.AutoComplete.prototype._nKeyCode = null;
1390
1391/**
1392 * Delay timeout ID.
1393 *
1394 * @property _nDelayID
1395 * @type Number
1396 * @private
1397 */
1398YAHOO.widget.AutoComplete.prototype._nDelayID = -1;
1399
1400/**
1401 * TypeAhead delay timeout ID.
1402 *
1403 * @property _nTypeAheadDelayID
1404 * @type Number
1405 * @private
1406 */
1407YAHOO.widget.AutoComplete.prototype._nTypeAheadDelayID = -1;
1408
1409/**
1410 * Src to iFrame used when useIFrame = true. Supports implementations over SSL
1411 * as well.
1412 *
1413 * @property _iFrameSrc
1414 * @type String
1415 * @private
1416 */
1417YAHOO.widget.AutoComplete.prototype._iFrameSrc = "javascript:false;";
1418
1419/**
1420 * For users typing via certain IMEs, queries must be triggered by intervals,
1421 * since key events yet supported across all browsers for all IMEs.
1422 *
1423 * @property _queryInterval
1424 * @type Object
1425 * @private
1426 */
1427YAHOO.widget.AutoComplete.prototype._queryInterval = null;
1428
1429/**
1430 * Internal tracker to last known textbox value, used to determine whether or not
1431 * to trigger a query via interval for certain IME users.
1432 *
1433 * @event _sLastTextboxValue
1434 * @type String
1435 * @private
1436 */
1437YAHOO.widget.AutoComplete.prototype._sLastTextboxValue = null;
1438
1439/////////////////////////////////////////////////////////////////////////////
1440//
1441// Private methods
1442//
1443/////////////////////////////////////////////////////////////////////////////
1444
1445/**
1446 * Updates and validates latest public config properties.
1447 *
1448 * @method __initProps
1449 * @private
1450 */
1451YAHOO.widget.AutoComplete.prototype._initProps = function() {
1452    // Correct any invalid values
1453    var minQueryLength = this.minQueryLength;
1454    if(!YAHOO.lang.isNumber(minQueryLength)) {
1455        this.minQueryLength = 1;
1456    }
1457    var maxResultsDisplayed = this.maxResultsDisplayed;
1458    if(!YAHOO.lang.isNumber(maxResultsDisplayed) || (maxResultsDisplayed < 1)) {
1459        this.maxResultsDisplayed = 10;
1460    }
1461    var queryDelay = this.queryDelay;
1462    if(!YAHOO.lang.isNumber(queryDelay) || (queryDelay < 0)) {
1463        this.queryDelay = 0.2;
1464    }
1465    var typeAheadDelay = this.typeAheadDelay;
1466    if(!YAHOO.lang.isNumber(typeAheadDelay) || (typeAheadDelay < 0)) {
1467        this.typeAheadDelay = 0.2;
1468    }
1469    var delimChar = this.delimChar;
1470    if(YAHOO.lang.isString(delimChar) && (delimChar.length > 0)) {
1471        this.delimChar = [delimChar];
1472    }
1473    else if(!YAHOO.lang.isArray(delimChar)) {
1474        this.delimChar = null;
1475    }
1476    var animSpeed = this.animSpeed;
1477    if((this.animHoriz || this.animVert) && YAHOO.util.Anim) {
1478        if(!YAHOO.lang.isNumber(animSpeed) || (animSpeed < 0)) {
1479            this.animSpeed = 0.3;
1480        }
1481        if(!this._oAnim ) {
1482            this._oAnim = new YAHOO.util.Anim(this._elContent, {}, this.animSpeed);
1483        }
1484        else {
1485            this._oAnim.duration = this.animSpeed;
1486        }
1487    }
1488    if(this.forceSelection && delimChar) {
1489        YAHOO.log("The forceSelection feature has been enabled with delimChar defined.","warn", this.toString());
1490    }
1491};
1492
1493/**
1494 * Initializes the results container helpers if they are enabled and do
1495 * not exist
1496 *
1497 * @method _initContainerHelperEls
1498 * @private
1499 */
1500YAHOO.widget.AutoComplete.prototype._initContainerHelperEls = function() {
1501    if(this.useShadow && !this._elShadow) {
1502        var elShadow = document.createElement("div");
1503        elShadow.className = "yui-ac-shadow";
1504        elShadow.style.width = 0;
1505        elShadow.style.height = 0;
1506        this._elShadow = this._elContainer.appendChild(elShadow);
1507    }
1508    if(this.useIFrame && !this._elIFrame) {
1509        var elIFrame = document.createElement("iframe");
1510        elIFrame.src = this._iFrameSrc;
1511        elIFrame.fra

Large files files are truncated, but you can click here to view the full file