PageRenderTime 65ms CodeModel.GetById 15ms app.highlight 38ms RepoModel.GetById 1ms app.codeStats 1ms

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

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

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