[Webinar] Learn how to a build a cloud-first strategyRegister Now


How do I add an event listener to an itemRenderer component class?

Posted on 2009-04-23
Medium Priority
Last Modified: 2012-05-06
Let's say this is the way a datagrid column is defined:

<mx:DataGridColumn itemEditor="MyTextInputComponent"/>

For my test, MyTextInputComponent is just a simple component subclassed from mx:TextInput.  How can I add a listener to listen for any event this component is capable of dispatching (e.g. focusOut, focusIn, change, etc)?
Question by:elepil
LVL 12

Expert Comment

ID: 24222422
Edit the component, add the events directly out there .. is that an option available for you?

Expert Comment

ID: 24225035
Below is a sample of how to listen to the focusOut event from within your component.

More information can be found here:

<?xml version="1.0"?>
<mx:TextInput xmlns:mx="http://www.adobe.com/2006/mxml" focusOut="handleFocusOutEvent(event);"> <!-- here is where you can listen for those events-->
            import flash.events.FocusEvent;
            // handle the events here
            public function handleFocusOutEvent(eventObj:FocusEvent):void 
                // Do something

Open in new window


Author Comment

ID: 24227062
Thank you for responding.

I was already aware I could add event listeners and create event handlers INSIDE the component, as both of you pointed out. But the reason why I don't like doing it that way is because the component no longer becomes as reusable.

For example (and this is totally hypothetical), I might want to listen to the focusIn event of my TextInput component so I can change the background color of the input field. This background color may differ from application to application. If I coded the event handler within the component, it now will be limited to a fixed color. In short, I'm always for loosely coupled components.

I wanted to know if there was a way to add an event listener to a component designated as an itemEditor so that I can communicate with it *outside* of the component. Is there?
NEW Veeam Agent for Microsoft Windows

Backup and recover physical and cloud-based servers and workstations, as well as endpoint devices that belong to remote users. Avoid downtime and data loss quickly and easily for Windows-based physical or public cloud-based workloads!

LVL 37

Expert Comment

ID: 24261707
you can set a function to call on eg. focusOut


inside your component:

private _focusOutFunction:Function;

public function setFocusOutFunction(f:Function) {
    _focusOutFunction = f;
    addEventListener(....FOCUS_OUT, function():void { _focusOutFunction.call(); });

This way you listen for focus out events, but what has to be done in that case is determined by the function you pass in

Author Comment

ID: 24264674
zzynx, thank you for your response.

When you said:


How do I get a reference to 'yourComponent' when it is declared as:

<mx:DataGridColumn headerText="Custom" itemRenderer="yourComponent"/>

See, that was the whole problem, I couldn't get the reference to my itemrenderer component. If I tried to instantiate my component in actionscript somewhere, that would not be the same component that the datagrid would create during runtime, right?
LVL 37

Expert Comment

ID: 24267481
>> I couldn't get the reference to my itemrenderer component.
I would expect this to work:

<mx:DataGridColumn id="dgc" headerText="Custom" itemRenderer="yourComponent"/>

var r:MyRenderer = dgc.itemRenderer;


Author Comment

ID: 24272735
Hi, zzynx. When I gry what you recommended, I am getting an error at:


ReferenceError: Error #1069: Property setFocusoutFunction not found on mx.core.ClassFactory and there is no default value.
      at FlexMain/init()[C:\Tomcat5\webapps\MyFlexSamples\src\FlexMain.mxml:63]
      at FlexMain/___FlexMain_Application1_creationComplete()[C:\Tomcat5\webapps\MyFlexSamples\src\FlexMain.mxml:3]
      at flash.events::EventDispatcher/dispatchEventFunction()
      at flash.events::EventDispatcher/dispatchEvent()
      at mx.core::UIComponent/dispatchEvent()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:9298]
      at mx.core::UIComponent/set initialized()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:1169]
      at mx.managers::LayoutManager/doPhasedInstantiation()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\managers\LayoutManager.as:718]
      at Function/http://adobe.com/AS3/2006/builtin::apply()
      at mx.core::UIComponent/callLaterDispatcher2()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:8628]
      at mx.core::UIComponent/callLaterDispatcher()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:8568]

This statement:

var r:MyRenderer = dgc.itemRenderer;

makes the variable 'r' of type mx.core.ClassFactory. When I try to cast it to my itemrenderer class, 'r' just ends up being a null.

If you are able to make it work on your side, can you attach a sample MXML document doing this? It shouldn't be very long if you can make a Datagrid with just one column, and your itemrenderer is subclassed from mx:TextInput, and simply see if you can add an event listener to the "click" event of your item renderer.

LVL 37

Expert Comment

ID: 24278272
Something I only remark now is that the text of your question reads:

<mx:DataGridColumn itemEditor="MyTextInputComponent"/>

So, you set the item*Editor* not the item*Renderer*

So if you write:
<mx:DataGridColumn id="dgc" headerText="Custom" itemEditor="YourComponent"/>

I would expect this line:

var r:MyEditor = dgc.itemEditor;

to make r an instance of YourComponent
LVL 37

Accepted Solution

zzynx earned 2000 total points
ID: 24278428
Consider my previous comment as a side remark.

Try this:

var myRenderer:ClassFactory = new ClassFactory(YourComponent);
myRenderer.properties = { focusOutFunction : yourFunction };
dgc.itemRenderer = myRenderer;


<mx:DataGridColumn id="dgc" headerText="Custom" />

Your custom renderer class "YourComponent" has the following variable & methods:

    private var _focusOutFunction:Function;

    public function set focusOutFunction(f:Function) {
        _focusOutFunction = f;
        addEventListener(....FOCUS_OUT, function():void { _focusOutFunction.call(); });
    public function get focusOutFunction():Function {
        return _focusOutFunction;

Reference: http://livedocs.adobe.com/flex/3/langref/mx/core/ClassFactory.html

Author Closing Comment

ID: 31574106
I thought it was very clever to create a Function property in the itemrenderer component and pass the function reference for the component to call from within. :)

That works, and thank you for your help.
LVL 37

Expert Comment

ID: 24285705
>> That works,
Glad to hear
>> and thank you for your help.
You're welcome.
Thanx 4 axxepting

Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

First things first - Preparation We need all the part for this install and it's much nicer to have them all on hand when you need them so here's what's required. Download Eclipse 3.5 32 bit (I like the Classic flavour) from here. (http://www.e…
I came across an unsolved Outlook issue and here is my solution.
Integration Management Part 2
Is your data getting by on basic protection measures? In today’s climate of debilitating malware and ransomware—like WannaCry—that may not be enough. You need to establish more than basics, like a recovery plan that protects both data and endpoints.…
Suggested Courses

868 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question