Saturday, July 9, 2011

Creating custom components in Flex: Part 3

Today we will create custom events for our component.

In this tutorial I will be modifying the CustomList component that was made in the second part of the tutorial series. I also assume you have read my tutorials about creating custom events using AS3.

In this tutorial we will create a new event class, so that we can later dispatch it from the component, and listen to it from the main file. Specifically, we are going to make it possible to listen to the event that occurs when a user selects an item in the list.

Firstly, we need to create this custom event. If you are using FlashDevelop, it can be done with a few clicks - select the directory where you want to create the event (I am going to put it in the myComponents folder), then right click and select "Add > New Event". It asks you for a name (I'll call it CustomEvent) and generates the code for you. The code is ready to go, but lacks event types. I will add a new event type and call it SELECT_ITEM, with a string value "selectItem". I'll also remove the clone() and toString() functions to simplify the code, as I won't need those:

package myComponents 
{
import flash.events.Event;

public class CustomEvent extends Event 
{
public static const SELECT_ITEM:String = "selectItem";

public function CustomEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false) 
{ 
super(type, bubbles, cancelable);
} 
}

}

}

In Flex, you need to define an Event so that Flex recognizes it, before you use it. This can be done by creating a new Metadata Event tag. Add this to the CustomList.mxml:

<fx:Metadata>
[Event(name="selectItem", type="myComponents.CustomEvent")]
</fx:Metadata>

Now, let's add an event listener for the actual change of the List selection. We listen to the 'change' event and create a new event handler called onChange(). Also, let's add an id for the List, so that we can refer to it later. Let's call it myList.

<s:List dataProvider="{dataProvider}" width="{listWidth}" height="{listHeight}" change="onChange();" id="myList" />

The function onChange() will dispatch our custom event, which we will then be able to listen to from the main file.

private function onChange(evt:Event):void{
dispatchEvent(new CustomEvent(CustomEvent.SELECT_ITEM));
}

The full code of the CustomList.mxml is:

<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
xmlns:s="library://ns.adobe.com/flex/spark" 
xmlns:mx="library://ns.adobe.com/flex/mx">

<fx:Metadata>
[Event(name="selectItem", type="myComponents.CustomEvent")]
</fx:Metadata>

<fx:Script>
<![CDATA[
[Bindable]
public var title:String;
[Bindable]
public var titleSize:int = 18;
[Bindable]
public var dataProvider:Object;
[Bindable]
public var listWidth:int = 200;
[Bindable]
public var listHeight:int = 200;

private function onChange():void{
dispatchEvent(new CustomEvent(CustomEvent.SELECT_ITEM));
}

]]>
</fx:Script>

<s:layout>
<s:VerticalLayout />
</s:layout>

<s:Label fontSize="{titleSize}" text="{title}" width="{listWidth}" />

<s:List dataProvider="{dataProvider}" width="{listWidth}" height="{listHeight}" change="onChange()" id="myList" />

</s:Group>

Now, in our main mxml file, let's add a listener to the function in the CustomList object, using the selectItem property. Also, we will add a new Label object and give it an id of "myLabel".

<s:VGroup>
<custom:CustomList title="This is a custom list!" dataProvider="{myData}" listWidth="170" listHeight="100" selectItem="onItemSelect(event)" />
<s:Label id="myLabel" />
</s:VGroup>

When an item is selected, the onItemSelect() function is called in the main mxml. Let's display the item that was selected in the Label:

<fx:Script>
<![CDATA[
import myComponents.CustomEvent;

private function onItemSelect(evt:CustomEvent):void{
myLabel.text = "Item selected: " + evt.target.myList.selectedItem;
}
]]>
</fx:Script>

The full code:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/mx"
   xmlns:custom="myComponents.*"
   width="180" height="160">
   
<fx:Declarations>
<mx:ArrayCollection id="myData">
<fx:String>John</fx:String>
<fx:String>Tom</fx:String>
<fx:String>Bob</fx:String>
<fx:String>Walter</fx:String>
<fx:String>Steve</fx:String>
</mx:ArrayCollection>
</fx:Declarations>

<fx:Script>
<![CDATA[
import myComponents.CustomEvent;

private function onItemSelect(evt:CustomEvent):void{
myLabel.text = "Item selected: " + evt.target.myList.selectedItem;
}
]]>
</fx:Script>

<s:VGroup>
<custom:CustomList title="This is a custom list!" dataProvider="{myData}" listWidth="170" listHeight="100" selectItem="onItemSelect(event)" />
<s:Label id="myLabel" />
</s:VGroup>

</s:Application>

And the result:


Thanks for reading!

Related:

Creating custom components in Flex: Part 1
Creating custom components in Flex: Part 2

No comments:

Post a Comment