I found a little more information. This "undesireable feature", aka bug manifests itself only if you make the combobox "editable."
I removed the editable="true" and the problem goes away. Paul --- In [email protected], "aceoohay" <[EMAIL PROTECTED]> wrote: > > Since creating a test case would be challenging I am posting the > component ValidatedComboBox.as. The problem I am having is that it > appears to call the keyDownHandler(event:KeyboardEvent):void function > twice for each keystroke. I have commented out most of that > function's code, as it used to handle all input there but now I only > handle the backspace there this is a patch to get it to function > somewhat. > > > package Classes.Input > { > import flash.events.Event; > import mx.controls.ComboBox; > import flash.events.KeyboardEvent; > import flash.ui.Keyboard; > import flash.events.FocusEvent; > import flash.events.MouseEvent; > > /** > * Create an extended version of the ComboBox that allows the > definition of invalid indexes. > * > * 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. > * > */ > public class ValidatedComboBox extends ComboBox > { > /** Bad indexes - A comma separated list of invalid > indexes. */ > private var _badIndexes: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; > > /** 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 _typedText:String = ""; > > public function ValidatedComboBox() > { > //TODO: implement function > super(); > this.addEventListener > (Event.CHANGE,_eventHandler) > } > > /** > * Add a new inspectable property so the user can > enter the Bad Indexesn > * at authortime via the properties panel. > * > * @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; > } > > /** > * Add a new inspectable property so the user can > enter the promptLabel for the field > * at authortime via the properties panel. > * > * @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; > } > > /** > * Add a new inspectable property so the user can > specify the whether this field should be validated > * via the properties panel. > * > * @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; > } > > /** > * Add a new inspectable property so the user can > enter the tool Tip Field for the field > * at authortime via the properties panel. > * > * @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; > } > > /** > * Add a new inspectable property so the user can > enter a Default value > * at authortime via the properties panel. > * > * @return the specified Maximum 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; > } > > public function get isValid():Boolean > { > return _isValid; > } > > override public function get value():Object > { > return _value; > } > > public function set value(value:Object): void > { > this.selectedIndex = 0; > if (value != null) > { > setSelectedItem(value); > } > else > { > _value = ""; > } > if (this.selectedIndex > -1) > { > _value = this.selectedItem["DATA"]; > } > } > > private function checkData(event:Event):void > { > if (this.selectedItem) > { > _value = this.selectedItem["DATA"]; > validateData(); > } > } > > public function setDefault():void > { > this.value = _defaultValue; > } > > public function validateData():Boolean > { > var aryTemp:Array = _badIndexes.split(","); > if (_doValidateData) > { > _isValid = ((aryTemp.indexOf > (this.selectedIndex.toString()) == -1) && > > (this.selectedIndex > -1)); > trace("id=" + this.id + "|_isValid=" > + _isValid); > if (!_isValid) > { > this.errorString = '"' + > this.selectedLabel + '" is an invalid choice. ' + > > this.selectedIndex.toString(); > } > else > { > this.errorString = ""; > } > } > return _isValid; > } > > private function setSelectedItem > (strFindItem:Object):void > { > if (this.dataProvider != null) > { > this.selectedIndex = -1; > for (var > i:int=0;i<this.dataProvider.length;i++) > { > if (this.dataProvider[i].DATA > == strFindItem) > { > this.selectedIndex = > i; > break; > } > } > } > } > > override protected function focusOutHandler > (event:FocusEvent):void > { > super.focusOutHandler(event); > _typedText = ""; > validateData() > } > > override protected function focusInHandler > (event:FocusEvent):void > { > super.focusInHandler(event); > _typedText = ""; > } > > override protected function textInput_changeHandler > (event:Event):void > { > _typedText += this.textInput.text; > if (!findFirstItem(_typedText)) > { > _typedText = _typedText.substr > (0,_typedText.length -1); > findFirstItem(_typedText); > } > } > override protected function keyDownHandler > (event:KeyboardEvent):void > { > // trace("event="+event.toString()); > // this.removeEventListener > (KeyboardEvent.KEY_DOWN,this.keyDownHandler); > event.preventDefault(); > if(!event.ctrlKey) > { > if (event.keyCode == > Keyboard.BACKSPACE || event.keyCode == Keyboard.DELETE) > { > _typedText = _typedText.substr > (0,_typedText.length -1); > findFirstItem(_typedText); > } > // 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); > // super.keyDownHandler(event); > } > > private function findFirstItem > (strFindItem:String):Boolean > { > trace('strFindItem=' + strFindItem); > if (this.dataProvider != null) > { > if (strFindItem.length == 0) > { > this.selectedIndex = 0; > this.dropdown.selectedIndex = > 0; > this.dropdown.scrollToIndex > (0); > _value = this.selectedItem > ["DATA"]; > 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["DATA"]; > if > (_toolTipField.length > 0) > { > this.toolTip > = this.dataProvider[i][_toolTipField] > > this.dispatchEvent(new MouseEvent("mouseOver")); > } > return true; > } > } > } > return false; > } > > > } > } >

