# inputEx-library

### inputEx 0.5.1

inputEx-library > inputEx > AutoComplete.js (source view)
Search:
Filters Show Private Show Protected Show Deprecated

    (function() {

       var lang = YAHOO.lang, Event = YAHOO.util.Event, Dom = YAHOO.util.Dom;

    /**
     * An autocomplete field that wraps the YUI autocompleter
     * @class inputEx.AutoComplete
     * @constructor
     * @extends inputEx.StringField
     * @param {Object} options Added options for Autocompleter
     * <ul>
     *  <li>datasource: the datasource</li>
     *  <li>autoComp: autocompleter options</li>
     *   <li>returnValue: function to format the returned value (optional)</li>
     * </ul>
     */
    inputEx.AutoComplete = function(options) {
       inputEx.AutoComplete.superclass.constructor.call(this, options);

    };

    lang.extend(inputEx.AutoComplete, inputEx.StringField, {

       /**
        * Adds autocomplete options
        * @param {Object} options Options object as passed to the constructor
        */
       setOptions: function(options) {
          inputEx.AutoComplete.superclass.setOptions.call(this, options);

          // Overwrite options
          this.options.className = options.className ? options.className : 'inputEx-Field inputEx-AutoComplete';

          // Added options
          this.options.datasource = options.datasource;
          this.options.autoComp = options.autoComp;
          this.options.returnValue = options.returnValue;
          this.options.generateRequest = options.generateRequest;
          this.options.datasourceParameters = options.datasourceParameters;
       },

       /**
        * Custom event init
        * <ul>
        *   <li>listen to autocompleter textboxBlurEvent instead of this.el "blur" event</li>
        *   <li>listener to autocompleter textboxBlurEvent added in buildAutocomplete method</li>
        * </ul>
        */
       initEvents: function() {
          inputEx.AutoComplete.superclass.initEvents.call(this);

          // remove standard blur listener
       },

       /**
        * Render the hidden list element
        */
       renderComponent: function() {

          // This element wraps the input node in a float: none div
          this.wrapEl = inputEx.cn('div', {className: 'inputEx-StringField-wrapper'});

          // Attributes of the input field
          var attributes = {
             type: 'text',
             id: YAHOO.util.Dom.generateId()
          };
          if(this.options.size) attributes.size = this.options.size;
          if(this.options.readonly) attributes.readonly = 'readonly';
          if(this.options.maxLength) attributes.maxLength = this.options.maxLength;

          // Create the node
          this.el = inputEx.cn('input', attributes);

          // Create the hidden input
          var hiddenAttrs = {
             type: 'hidden',
             value: ''
          };
          if(this.options.name) hiddenAttrs.name = this.options.name;
          this.hiddenEl = inputEx.cn('input', hiddenAttrs);

          // Append it to the main element
          this.wrapEl.appendChild(this.el);
          this.wrapEl.appendChild(this.hiddenEl);
          this.fieldContainer.appendChild(this.wrapEl);

          // Render the list :
          this.listEl = inputEx.cn('div', {id: Dom.generateId() });
          this.fieldContainer.appendChild(this.listEl);

          Event.onAvailable([this.el, this.listEl], this.buildAutocomplete, this, true);
       },

       /**
        * Build the YUI autocompleter
        */
       buildAutocomplete: function() {
          // Call this function only when this.el AND this.listEl are available
          if(!this._nElementsReady) { this._nElementsReady = 0; }
          this._nElementsReady++;
          if(this._nElementsReady != 2) return;

          if(!lang.isUndefined(this.options.datasourceParameters))
          {
             for (param in this.options.datasourceParameters)
             {
                this.options.datasource[param] = this.options.datasourceParameters[param];
             }
          }

          // Instantiate AutoComplete
          this.oAutoComp = new YAHOO.widget.AutoComplete(this.el.id, this.listEl.id, this.options.datasource, this.options.autoComp);
          if(!lang.isUndefined(this.options.generateRequest))
          {
              this.oAutoComp.generateRequest = this.options.generateRequest;
          }
          // subscribe to the itemSelect event
          this.oAutoComp.itemSelectEvent.subscribe(this.itemSelectHandler, this, true);

          // subscribe to the textboxBlur event (instead of "blur" event on this.el)
          //                                    |-------------- autocompleter ----------|
          //    -> order : "blur" on this.el -> internal callback -> textboxBlur event -> this.onBlur callback
          //    -> so fired after autocomp internal "blur" callback (which would erase typeInvite...)
          this.oAutoComp.textboxBlurEvent.subscribe(this.onBlur, this, true);
       },

       /**
        * itemSelect handler
        * @param {} sType
        * @param {} aArgs
        */
       itemSelectHandler: function(sType, aArgs) {
          var aData = aArgs[2];
          this.setValue( this.options.returnValue ? this.options.returnValue(aData) : aData[0] );
       },

       onBlur: function(e){
    	 if (this.hiddenEl.value != this.el.value && this.el.value != this.options.typeInvite) this.el.value = this.hiddenEl.value;
    	   if(this.el.value == '' && this.options.typeInvite) {
    	         Dom.addClass(this.divEl, "inputEx-typeInvite");
    			 if (this.el.value == '') this.el.value = this.options.typeInvite;
         }
    },
       /**
        * onChange event handler
        * @param {Event} e The original 'change' event
        */
       onChange: function(e) {
          this.setClassFromState();
          // Clear the field when no value
    	 if (this.hiddenEl.value != this.el.value) this.hiddenEl.value = this.el.value;
          lang.later(50, this, function() {
             if(this.el.value == "") {
                this.setValue("");
             }
          });
       },

       /**
        * Set the value
        * @param {Any} value Value to set
        * @param {boolean} [sendUpdatedEvt] (optional) Wether this setValue should fire the updatedEvt or not (default is true, pass false to NOT send the event)
        */
       setValue: function(value, sendUpdatedEvt) {
          this.hiddenEl.value = value || "";
          this.el.value  =  value || "";
          // "inherited" from inputex.Field :
          //    (can't inherit of inputex.StringField because would set this.el.value...)
          //
       // set corresponding style
       this.setClassFromState();

       if(sendUpdatedEvt !== false) {
          // fire update event
             this.fireUpdatedEvt();
          }
       },

       /**
        * Return the hidden value (stored in a hidden input)
        */
       getValue: function() {
          return this.hiddenEl.value;
       }

    });

    // Register this class as "autocomplete" type
    inputEx.registerType("autocomplete", inputEx.AutoComplete);

    })();

Copyright © 2010 Eric Abouaf All rights reserved.