views:

1834

answers:

2

I have a custom component made up of a selectable control (radio button) and a text input. I want to perform some logic in response to the change events from both of those controls, but after that I want anything that is registered on the composite component's change handler to have a change to handle the events as well. The problem is, when I re-dispatch the events the event target has changed to my custom component, losing the originating event's target.

Here's my custom component:

<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" label="{listItem.@text}" data="{[email protected]()}">

    <mx:Script>
        <![CDATA[
            import mx.controls.RadioButtonGroup;
            [Bindable]
            public var selected: Boolean;
            [Bindable]
            public var text: String;
            [Bindable]
            public var listItem: XML;
            [Bindable]
            public var group: RadioButtonGroup;

            private function onSelectionChange(event: Event): void {
                selected = event.target.selected;
                dispatchEvent(event);
            }

            private function onTextChange(event: Event): void {
                text = event.target.text;
                dispatchEvent(event);
            }
        ]]>
    </mx:Script>

    <mx:RadioButton group="{group}" label="{label}" selected="{selected}" change="onSelectionChange(event)"/>
    <mx:TextInput width="100%"
                  maxChars="{listItem.specify.@entryLength}"
                  enabled="{selected}"
                  visible="{listItem.hasOwnProperty('specify')}"
                  includeInLayout="{visible}"
                  change="onTextChange(event)"/>
</mx:HBox>

In the event handler that receives change events from this component, I see that event.target is an instance of SpecifyRadioButton, not the TextInput or RadioButton, as I'd expect. How should I propagate the event to get what I want here?

Getting event [Event type="change" bubbles=false cancelable=false eventPhase=2] 
from question0.tabSurvey.questionForm.questionContainer.Single94.VBox95.SpecifyRadioButton111
+2  A: 

Instead of re-dispatching the original event, create a new event and pass the original event as a origEvent property. The new event which the SpecifyRadioButton dispatches can either be a custom event class which extends Event, or you can be lazy and just use mx.events.DynamicEvent.

Example:

import mx.events.DynamicEvent;

private function onSelectionChange(event: Event): void {
    selected = event.target.selected;
    var newEvent:DynamicEvent = new DynamicEvent(Event.CHANGE);
    newEvent.origEvent = event;
    dispatchEvent(newEvent);
}

Then, in your handlers for the SpecifyRadioButton.change event, reference the event.origEvent property.

N Rohler
+1  A: 

It makes sense that the target of the event would be SpecifyRadioButton, because that's what is dispatching the event.

The TextInput component's "change" event is set to not bubble up, meaning that it can be listened to by listeners in the same component as it, but nowhere else. If you want the change event to bubble up, you're going to have to extend the TextInput class (or use something nifty like Mate).

package {

    import flash.events.Event;
    import mx.controls.TextInput;

    public class CarbonatedTextInput extends TextInput {
        public function CarbonatedTextInput () {
            super();
            addEventListener(Event.CHANGE, forceBubbles);
        }

        /* 
           We have to remove the event listener before we
           dispatch the new event (with bubbles!) because
           otherwise our listener in the constructor would
           catch us and put us in an endless loop...
           resulting in a **STACK OVERFLOW** 
        */
        protected function forceBubbles(e:Event):void {
            removeEventListener(Event.CHANGE, forceBubbles);
            dispatchEvent(new Event(Event.CHANGE, true));
            addEventListener(Event.CHANGE, forceBubbles);
        }
    }
}
I Never Finish Anythi