By way of example here is a sample class I have created. The killMe method is
an attempt to make the GC want to take out the trash.

package Classes.Input
{
        import flash.events.DataEvent;
        import flash.events.Event;
        import flash.events.FocusEvent;
        import flash.events.KeyboardEvent;
        import flash.events.MouseEvent;
        import flash.ui.Keyboard;
        import flash.utils.Dictionary;
        
        import mx.controls.ComboBox;
        import mx.events.ListEvent;
        
        /**
         * postValidate Code to execute after validateData method completes.
         * 
         **/

        [Event(name="postValidate", type="flash.events.DataEvent")]
        
        /**
         * Create an extended version of the ComboBox that allows the 
definition of
invalid indexes and
         * multiple keystroke selection.
         * 
         * <pre>
         * The developer defines one or more invalid indexes in a comma 
separated
list using the property badIndexes.
         * Most commonly the developer would specify "0" which is the first 
element
in the list.
         * 
         * New properties are;
         * badIndexes - A string that allows the developer to define a comma
separated list of invalid indexes.
         * isVald - A boolean that defines whether the field is valid.
         * 
         * New Methods are;
         * validateData() - This method checks if the data is valid and returns
true if valid, false if invalid.
         * 
         * Enhanced Properties;
         * value - When the property value is set, the combobox will attempt to
find the appropriate value in the 
         * dataprovider, and set the selectedIndex to that item. It will set the
value to -1 if not found.
         * 
         * </pre>
         */
        public class ValidatedComboBox extends ComboBox
        {
                /** Bad indexes - A comma separated list of invalid indexes. */
                private var _badIndexes:String = "";
                
                /** Bad Data - A comma separated list of invalid Data. */
                private var _badData:String = "";
                
                /** Has this field passed validation */
                private var _isValid:Boolean = true;
                
                /** value */
                private var _value:Object;
                
                /** should we validate data */
                private var _doValidateData:Boolean = true;
                
                /** promptLabel */
                private var _promptLabel:String;
                
                
                /** dataType */
                private var _dataType:String = "string";
                
                /** dataField */
                private var _dataField:String = "DATA";
                
                /** toolTipField */
                private var _toolTipField:String = "";
                
                /** Default value A literal that represents the value that will 
replace
the "value"
                 * property when the method setDefault is executed */
                private var _defaultValue:String = "";
                
                private var _eventHandler:Function = this["checkData"];
                
                private var _tabOut:Function = null;
                
                private var _focusOutTab:Boolean = false;

                private var _typedText:String = "";
                
                public function ValidatedComboBox()
                {
                        //TODO: implement function
                        super();
                        
this.addEventListener(Event.CHANGE,_eventHandler,false,0,true)
                }
            override protected function createChildren():void
            {
                super.createChildren();
                        
                        if(this.textInput)
                        { // Use ValidatedTextInput instead of TextInput and 
Setup various fields 
                                textInput["id"] = "vti" + this.id;
//                              textInput.parentDrawsFocus = true;
                        }
            }
                
                /**
                 * badIndexes- A comma seperated list of indexes that will be 
considered
invalid. 
                 * 
                 * @return the specified bad indexes
                 */
                [Inspectable( type="String" , defaultValue="" )]
                public function get badIndexes():String 
                {
                        return this._badIndexes;
                } 
                /**
                 * Sets the the specified bad indexes
                 */
                public function set badIndexes( badIndexes:String ):void 
                {
                        this._badIndexes = badIndexes;
                        if (_badIndexes.length < 1)
                        {
                                errorString = "";
                                _isValid = true;
                        }
                }
                
                /**
                 * badData- A comma seperated list of Data that will be 
considered
invalid. 
                 * 
                 * @return the specified bad Data
                 */
                [Inspectable( type="String" , defaultValue="" )]
                public function get badData():String 
                {
                        return this._badData;
                } 
                /**
                 * Sets the the specified bad Data
                 */
                public function set badData( badData:String ):void 
                {
                        this._badData = badData;
                        if (_badData.length < 1)
                        {
                                errorString = "";
                                _isValid = true;
                        }
                }
                
                /**
                 * promptLabel - Specify a human readable label for the field.
                 * 
                 * @return the specified promptLabel
                 */

                [Inspectable( type="String" , defaultValue="" )]
                public function get promptLabel():String 
                {
                        return this._promptLabel;
                } 
                /**
                 * Sets the the specified promptLabel
                 */
                public function set promptLabel( promptLabel:String ):void 
                {
                        this._promptLabel = promptLabel;
                }
                
                /**
                 * dataType - specify whether to use numeric or string matching 
when
setting
                 * the value of this field.
                 * 
                 * <p>
                 * Use this field when the drop down's data is a number. 
Particularly
useful if 
                 * the current field in the database is string and can contain 
leading
zeroes.
                 * </p>  
                 * 
                 * @return the specified validate data flag.
                 */
                [Inspectable( type="String" , defaultValue=false,
enumeration="string,number" )]
                public function get dataType():String
                {
                        return this._dataType;
                }
                
                /**
                 * Sets the specified validate data flag.
                 */
                public function set dataType( dataType:String ):void 
                {
                        this._dataType = dataType;
                }
                
                /**
                 * doValidateData - specify the whether this field should be 
validated.
Default is true. 
                 * 
                 * @return the specified validate data flag.
                 */
                [Inspectable( type="Boolean" , defaultValue=false,
enumeration="true,false" )]
                public function get doValidateData():Boolean 
                {
                        return this._doValidateData;
                }
                
                /**
                 * Sets the specified validate data flag.
                 */
                public function set doValidateData( doValidateData:Boolean 
):void 
                {
                        this._doValidateData = doValidateData;
                }
                
                /**
                 * toolTipField - Specify a field in the dataProvider whose 
value will be
used as the
                 * to populate the toolTip. 
                 * 
                 * @return the specified toolTipField
                 */
                [Inspectable( type="String" , defaultValue="" )]
                public function get toolTipField():String 
                {
                        return this._toolTipField;
                } 
                /**
                 * Sets the the specified toolTipField
                 */
                public function set toolTipField( toolTipField:String ):void 
                {
                        this._toolTipField = toolTipField;
                }
                
                /**
                 * defaultValue - allows the specification of a default value 
for a field.
                 * To set the current text/value properties use the the 
setDefault()
method.
                 * 
                 * @return the specified defaultValue value
                 */
                [Inspectable( type="String" , defaultValue="" )]
                public function get defaultValue():String 
                {
                        return this._defaultValue;
                } 
                /**
                 * Sets the specified Default value
                 */
                public function set defaultValue( defaultValue:String ):void 
                {
                        this._defaultValue = defaultValue;
                        var event:Event;
                }
                
                /**
                 * dataField - the field to be used as the data field from the
dataProvider.
                 * 
                 * The value of the field defined here is what the value is set 
to based 
                 * on the selection.  
                 * 
                 * @return the specified dataFiel
                 */
                [Inspectable( type="String" , defaultValue="DATA" )]
                public function get dataField():String 
                {
                        return this._dataField;
                } 
                /**
                 * Sets the the specified dataField
                 */
                public function set dataField( dataField:String ):void 
                {
                        this._dataField = dataField;
                }
                
                /**
                 * tabOut - A function to execute if the tabkey is pressed..
                 * 
                 * @return the specified tabOut Function
                 */
                [Inspectable( type="Function" , defaultValue="" )]
                public function get tabOut():Function 
                {
                        return this._tabOut;
                } 
                /**
                 * Sets the the specified tabOut
                 */
                public function set tabOut( tabOut:Function ):void 
                {
                        this._tabOut = tabOut;
                }
                
                /**
                 * focusOutTab - A boolean defining if the last focus out was a 
tab.
                 * 
                 * @return  focusOutTab
                 */
                public function get focusOutTab():Boolean
                {
                        return this._focusOutTab;
                } 
                /**
                 * Sets the the specified focusOutTab
                 */
                public function set focusOutTab( focusOutTab:Boolean ):void 
                {
                        this._focusOutTab = focusOutTab;
                }

                /**
                 * isValid - Returns a boolean that defines whether the current 
value is
valid.
                 */

                public function get isValid():Boolean 
                {
                        return _isValid;
                }
                
                override public function get value():Object
                {
                        return _value;
                }
                
                override public function set dataProvider(dpValue:Object):void
                {
                        var objCurrentValue:Object = _value;
                        super.dataProvider = dpValue;
                        if (this.hasOwnProperty("dropdown"))
                                if (this.dropdown != 
null)this.dropdown.dataProvider = dpValue;
                        _value = objCurrentValue;
                        if (dpValue != null)
                        {
                                if (dpValue.length > 0)
                                {
                                        if (_value != null) 
                                        {
                                                if(_value.toString().length > 
0) setSelectedItem(_value);
                                        }
                                        else
                                        {
                                                if (this.selectedItem != null) 
_value = this.selectedItem[dataField];
                                        }
                                        if (this.selectedIndex == -1)
                                        {
                                                this.selectedIndex = 0;
                                                _value = 
this.selectedItem[dataField];
                                                if (this.selectedItem != null)
                                                        if 
(this.selectedItem.hasOwnProperty(dataField))
                                                        {
                                                                _value = 
this.selectedItem[dataField];
                                                                dispatchEvent( 
new ListEvent( ListEvent.CHANGE ) );
                                                        } 
                                        }
                                }
                        }
                        dpValue = null;
                        objCurrentValue = null;
                }
                
                override public function set selectedIndex(intValue:int):void
                {
//                      if (this.hasOwnProperty("id")) trace("id=" + this.id + 
" set intValue="
+ intValue);
                        super.selectedIndex = intValue;
                        if (intValue > -1)
                        {
                                if (this.selectedItem != null)
                                {
                                        if 
(this.selectedItem.hasOwnProperty(dataField))
                                        {
                                                 _value = 
this.selectedItem[dataField];
                                        }
                                }
                        }
                }
                
                /**
                 * Sets the the specified value based on the item selected.
                 */
                
                public function set value(value:Object): void
                {
//                      if (this.hasOwnProperty("id")) trace("id=" + this.id + 
" set value=" +
value);
//                      trace("ValidatedComboBox-" + this.id + "Set value=" + 
value);
                        this.selectedIndex = 0;
                        if (value != null)
                        {
                                setSelectedItem(value);
                                _value = value;
                        }
                        else
                        {
                                _value = "";
                        }
                        if (this.selectedIndex > -1)
                        {
                                if (this.selectedItem != null)
                                        if 
(this.selectedItem.hasOwnProperty(dataField))
                                        {
                                                 _value = 
this.selectedItem[dataField];
                                        }
                        }
                }

                private function checkData(event:Event):void
                {
                        this.removeEventListener(Event.CHANGE,_eventHandler)
                        if (this.selectedItem)
                        {
                                this.
                                _value = this.selectedItem[dataField];
                                validateData();
                        }
                        
this.addEventListener(Event.CHANGE,_eventHandler,false,0,true)
                }

                /**
                 * setDefault - Method that will replace the value of the value 
property
with the 
                 * value of the defaultValue property.
                 */
                 
                public function setDefault():void
                {
                        _value = _defaultValue;
                        setSelectedItem(_value);
                }
                
                /**
                 * getDefault - Method that will return the value of the 
defaultValue
property.
                 * 
                 * This method returns the defaultValue it exists to provide a 
consistenet
api
                 * between all "validated" components.
                 */
                 
                public function getDefault():String
                {
                        return _defaultValue;
                }

                /**
                 * validateData - Method that will validate the data that has 
been
entered.
                 */

                public function validateData():Boolean
                {
                        if (_badIndexes.length == 0 && _badData.length == 0) 
                        {
                                this.dispatchEvent(new 
DataEvent("postValidate"));
                                return true;
                        }
                        var aryIndexesTemp:Array = _badIndexes.split(",");
                        if (_doValidateData)
                        {
                                _isValid = 
((aryIndexesTemp.indexOf(this.selectedIndex.toString()) ==
-1) &&
                                                        (this.selectedIndex > 
-1));
                                if (_isValid && _badData.length > 0)
                                {
                                        var aryDataTemp:Array = 
_badData.split(",");
                                        if (this.selectedIndex > -1) _isValid =
(aryDataTemp.indexOf(this.dataProvider[this.selectedIndex][dataField].toString())
== -1);
                                }
                                if (!_isValid) 
                                {
                                        this.errorString = '"' + 
this.selectedLabel + '" is an invalid choice.
' + 
                                                                                
         this.selectedLabel.toString();
                                }
                                else
                                {
                                        this.errorString = "";
                                }
                        }
                        this.dispatchEvent(new DataEvent("postValidate"));
                        return _isValid;
                }


                private function setSelectedItem(strFindItem:Object):void
                {
                        var strDataItem:String = "";
                        if (this.dataProvider != null)
                        {
                                this.selectedIndex = -1;
                                if (_dataType == "number")
                                {
                                        strFindItem = 
String(parseInt(strFindItem.toString(),10));
                                } 
                                for (var i:int=0;i<this.dataProvider.length;i++)
                                {
                                        if (this.dataProvider[i] != null)
                                        {
                                                if (_dataType == 
&quot;number&quot;)
                                                {
                                                        strDataItem =
String(parseInt(this.dataProvider[i][dataField].toString(),10));
                                                } 
                                                else
                                                {
                                                        strDataItem = 
this.dataProvider[i][dataField].toString();
                                                }
                                                if (strDataItem == strFindItem 
&amp;&amp; strDataItem.length ==
strFindItem.toString().length)
                                                {
                                                        this.selectedIndex = i;
                                                        if 
(_toolTipField.length > 0)
                                                        {
                                                                this.toolTip = 
this.dataProvider[i][_toolTipField]
                                                        }
//                                                      dispatchEvent( new 
ListEvent( ListEvent.CHANGE ) );
                                                        break;
                                                }
                                        }
                                }
                        }
                }
                
                override protected function 
focusOutHandler(event:FocusEvent):void
                {
                        super.focusOutHandler(event);
                        _typedText = "";
                        validateData()
                }
                
                override protected function 
focusInHandler(event:FocusEvent):void
                {
                        
this.removeEventListener(KeyboardEvent.KEY_DOWN,this.keyDownHandler);
                        super.focusInHandler(event);
                        _typedText = "";
                        _focusOutTab = false;
                
this.addEventListener(KeyboardEvent.KEY_DOWN,this.keyDownHandler,false,0,true);
                }

                override protected function 
textInput_changeHandler(event:Event):void
                {
                        _typedText += this.textInput.text;
//                      trace('_typedText=' + _typedText);
                        if (!findFirstItem(_typedText))
                        {
                                _typedText = 
_typedText.substr(0,_typedText.length -1);
                                findFirstItem(_typedText);
                        }
//                      this.dispatchEvent(new Event(Event.CHANGE,true));
                }
                override protected function 
keyDownHandler(event:KeyboardEvent):void
                {
//                      trace("event="+event.toString());
                        
this.removeEventListener(KeyboardEvent.KEY_DOWN,this.keyDownHandler);
                        event.preventDefault();
                        if (event.keyCode == Keyboard.TAB)_focusOutTab = true;
                        if ((event.keyCode == Keyboard.TAB && _tabOut == null) 
|| event.keyCode
== Keyboard.ENTER) return;
                        if (event.keyCode == Keyboard.TAB)
                        {
                                _tabOut();
                        }
                    if(!event.ctrlKey)
                        {
                                if (event.keyCode == Keyboard.BACKSPACE || 
event.keyCode ==
Keyboard.DELETE)
                                {
                                        _typedText = 
_typedText.substr(0,_typedText.length -1);
                                        findFirstItem(_typedText);
                                }
                                if (event.keyCode == Keyboard.DOWN || 
event.keyCode == Keyboard.RIGHT)
                                {
                                        _typedText = "";
                                        if (this.dropdown.selectedIndex < 
this.dataProvider.length - 1)
                                        {
                                                this.selectedIndex++;
                                                this.dropdown.selectedIndex++;
                                                
this.dropdown.scrollToIndex(this.dropdown.selectedIndex);
                                                _value = 
this.selectedItem[dataField];
                                        }
                                }
                                if (event.keyCode == Keyboard.UP || 
event.keyCode == Keyboard.LEFT)
                                {
                                        _typedText = "";
                                        if (this.dropdown.selectedIndex > 0)
                                        {
                                                this.selectedIndex--;
                                                this.dropdown.selectedIndex--;
                                                
this.dropdown.scrollToIndex(this.dropdown.selectedIndex);
                                                _value = 
this.selectedItem[dataField];
                                        }
                                }
                                if ((event.charCode > 31) && (event.charCode < 
128))
                                {
                                        _typedText += 
String.fromCharCode(event.charCode);
                                        if (!findFirstItem(_typedText))
                                        {
                                                _typedText = 
_typedText.substr(0,_typedText.length -1);
                                        }
                                }
                        }
//                      trace("_typedText=" + _typedText);
                
this.addEventListener(KeyboardEvent.KEY_DOWN,this.keyDownHandler,false,0,true);
//                  super.keyDownHandler(event);
                }
                
                private function findFirstItem(strFindItem:String):Boolean
                {
                        if (this.dataProvider != null)
                        {
                                if (strFindItem.length == 0)
                                {
                                        this.selectedIndex = 0;
                                        this.dropdown.selectedIndex = 0;
                                        this.dropdown.scrollToIndex(0);
                                        _value = this.selectedItem[dataField];
                                        dispatchEvent( new ListEvent( 
ListEvent.CHANGE ) );
                                        return true;
                                }
                                this.dispatchEvent(new MouseEvent("mouseOut"));
                                for (var i:int=0;i<this.dataProvider.length;i++)
                                {
                                        if
(this.dataProvider[i][this.labelField].toString().substr(0,strFindItem.length).toUpperCase()
== strFindItem.toUpperCase())
                                        {
                                                this.selectedIndex = i;
                                                this.dropdown.selectedIndex = i;
                                                this.dropdown.scrollToIndex(i);
                                                _value = 
this.selectedItem[dataField];
                                                if (_toolTipField.length > 0)
                                                {
                                                        this.toolTip = 
this.dataProvider[i][_toolTipField]
                                                        this.dispatchEvent(new 
MouseEvent("mouseOver"));
                                                }
                                                dispatchEvent( new ListEvent( 
ListEvent.CHANGE ) );
                                                return true;
                                        }
                                }
                        }
                        return false;
                }
                
                public function killMe():void
                {
                        trace('unloading='+this.id);
                        this.dataProvider = null;
                        this.dropdown.dataProvider = null;
                        this.selectedIndex = -1;
                        this.selectedItem = null;
                        this.value = null;
                        callLater(clearEvents);
                }
                
                protected var dctListeners:Dictionary = new Dictionary(); // 
added
05/22/2018
                protected var bolInClearEvents:Boolean = false;
                
                override public function addEventListener(type:String, 
listener:Function,
useCapture:Boolean = false, priority:int =
                                                                                
                  0, useWeakReference:Boolean = true):void
                {
                        if (bolInClearEvents == false)
                        {
                                var key:Object = {type: type, useCapture: 
useCapture};
                                if (dctListeners[key])
                                {
                                        removeEventListener(type, 
dctListeners[key], useCapture);
                                        dctListeners[key] = null;
                                }
                                dctListeners[key] = listener;
                                super.addEventListener(type, listener, 
useCapture, priority,
useWeakReference);
                        }
                }
                
                public function clearEvents():void
                {
                        bolInClearEvents = true;
                        try
                        {
                                for (var key:Object in dctListeners)
                                {
                                        removeEventListener(key.type, 
dctListeners[key], key.useCapture);
                                        dctListeners[key] = null;
                                }
                        }
                        catch (e:Error)
                        {
                                trace('TestBig-clearEvents error='+e.message);
                        }
                        dctListeners = null;
                }
        

        }
}



--
Sent from: http://apache-flex-users.2333346.n4.nabble.com/

Reply via email to