We already have a working contact list on the left-hand side of our
application. What we need now is to add a single contact view, so that the
user can see the details of any contact in the list when he or she clicks
on a contact’s name.
When we were working in Flash Catalyst, we defined a
contactView state. The code in
Main.mxml works, but it’s a little simplistic for
what we want to do, so let’s modify it slightly.
Start by cutting out all the
<fx:DesignLayer> and
<s:RichText> elements that are being used to show
the contact’s name on the right-hand side of our display: we’re going to
create a new component for this purpose.
Right-click on /src/components in your Package Explorer
pane in Flash Builder, and create a new MXML component. Call it
ContactItem and fill in the details in the dialog as
per Figure 1, “The ContactItem Component”.
Flash Builder will generate the component structure for us. Next, we
want to drop in the code to display the contact item’s details. First,
insert the following code inside the Group element, which adds a public variable so
the component can be passed a Contact value
object:
<fx:Script>
<![CDATA[
import valueObjects.Contact;
[Bindable]
public var contactData : Contact;
]]>
</fx:Script> note: Don’t Forget the Metadata!
Don’t forget the [Bindable] metadata—without
it, the component won’t pick up changes to our selections at runtime.
You’ll recall that, in article two of the series, Flash Builder
generated the valueObjects/Contact.as class for
us, and we can use this as the expected type.
Now let’s add a slightly cleaned-up version of the generated
Catalyst code, from which we’ve simply removed the Catalyst-specific items
and stripped out the includeIn attribute. The code
should look like this:
<s:BitmapImage source="@Embed('assets/images/mockup/at.png')"/>
<s:RichText color="0xFFFFFF" fontSize="18" kerning="on" lineHeight="120%" whiteSpaceCollapse="preserve">
<s:content><s:p whiteSpaceCollapse="collapse"><s:span>Toby Tremayne</s:span></s:p></s:content>
</s:RichText>
<s:RichText color="0xFFFFFF" kerning="on" lineHeight="120%" whiteSpaceCollapse="preserve">
<s:content><s:p whiteSpaceCollapse="collapse"><s:span>9999 999 999</s:span></s:p></s:content>
</s:RichText>
<s:RichText color="0xFFFFFF" kerning="on" lineHeight="120%" whiteSpaceCollapse="preserve">
<s:content><s:p whiteSpaceCollapse="collapse"><s:span>toby@magicindustries.net</s:span></s:p></s:content>
</s:RichText>
<s:RichText color="0xFFFFFF" kerning="on" lineHeight="120%" whiteSpaceCollapse="preserve">
<s:content><s:p whiteSpaceCollapse="collapse"><s:span>21b Baker Street</s:span></s:p></s:content>
</s:RichText>
<s:RichText color="0xFFFFFF" kerning="on" lineHeight="120%" whiteSpaceCollapse="preserve">
<s:content><s:p whiteSpaceCollapse="collapse"><s:span>London</s:span></s:p></s:content>
</s:RichText>Finally, we want to make sure the ContactItem
component is picking up the actual data that’s passed to it, so we replace
the hard-coded values with references to our value
object:
<s:RichText color="0xFFFFFF" fontSize="18" kerning="on" lineHeight="120%" whiteSpaceCollapse="preserve">
<s:content><s:p whiteSpaceCollapse="collapse"><s:span>{contactData.first_name}</s:span></s:p></s:content>
</s:RichText>
<s:RichText color="0xFFFFFF" kerning="on" lineHeight="120%" whiteSpaceCollapse="preserve">
<s:content><s:p whiteSpaceCollapse="collapse"><s:span>{contactData.phone}</s:span></s:p></s:content>
</s:RichText>
<s:RichText color="0xFFFFFF" kerning="on" lineHeight="120%" whiteSpaceCollapse="preserve">
<s:content><s:p whiteSpaceCollapse="collapse"><s:span>{contactData.email}</s:span></s:p></s:content>
</s:RichText>
<s:RichText color="0xFFFFFF" kerning="on" lineHeight="120%" whiteSpaceCollapse="preserve">
<s:content><s:p whiteSpaceCollapse="collapse"><s:span>{contactData.address1}</s:span></s:p></s:content>
</s:RichText>
<s:RichText color="0xFFFFFF" kerning="on" lineHeight="120%" whiteSpaceCollapse="preserve">
<s:content><s:p whiteSpaceCollapse="collapse"><s:span>{contactData.city}</s:span></s:p></s:content>
</s:RichText>Now, move back to Main.mxml. First, check that
the Application tag’s currentState
attribute is set to listView:
<s:Application
xmlns:fc="http://ns.adobe.com/flashcatalyst/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:flm="http://ns.adobe.com/flame/2008"
xmlns:lib="assets.graphics.mockup.*"
xmlns:d="http://ns.adobe.com/fxg/2008/dt"
xmlns:ai="http://ns.adobe.com/ai/2009"
xmlns:ATE="http://ns.adobe.com/ate/2009"
xmlns:contactservice1="services.contactservice1.*"
height="600" width="800"
backgroundColor="#FFFFFF"
preloaderChromeColor="#FFFFFF"
currentState="listView">
Next, go to the section of the code from which we stripped out the
elements we put into ContactItem.mxml, and drop in a
call to our new component, like so:
<components:ContactItem
id="contactPane"
contactData="{contactList.selectedItem}"
includeIn="contactView"
x="450" y="125" />If you type this using the code insight in Flash Builder (IE type
the opening left angle bracket and wait for the little popup, you can
navigate to your components:ContactItem and when you
select it, the IDE will automatically add an xmlns attribute to your <Application> tag. If not, you will need to make
sure the following is added to the <Application> tag:
xmlns:components="components.*"
The list component was automatically assigned an id when we used the Flash Builder code
generation tools to hook it up to our PHP service call, but it’s a very
non-descriptive list1. Change the
id to contactList to make your code a little
clearer.
note: Setting Names and Properties in Catalyst
You can, of course, set id names and properties
for your components in Flash Catalyst using the
Properties pane in the Catalyst IDE prior to
porting the project to Flash Builder.
Now we want to make the contact pane appear on the right hand side
when the user selects an item from the contact list. Add this function to
Main.mxml’s script block:
protected function list_changeHandler():void
{
currentState='contactView';
}And then add a change handler on the contact list itself, like
so:
<s:List id="contactList"
skinClass="components.TobyTremayneDataList"
x="157" y="163"
change="list_changeHandler()"
creationComplete="list_creationCompleteHandler(event)"
labelField="address1"
itemRenderer="components.RepeatedItem1">
<s:AsyncListView list="{getAllContactResult.lastResult}"/>
</s:List>If you followed the last article and made your own adjustments,
Flash Catalyst created transitions using parallels to simultaneously fade
each element (first name, last name etc). We have replaced those
individual elements with a single component, so we need to modify the
transition code. Change it instead to have a simple Fade for each
transition, targeting our new ContactItem component. The new set of
transitions should look like this:
Flash Catalyst created transitions that used
parallels to simultaneously fade each
element (first name, last name etc.). However, we’ve replaced those
individual elements with a single component, so we need to modify the
transition code. Change it instead to have a simple
Fade for each transition, which will
target our new ContactItem component:
<s:transitions>
<s:Transition fromState="contactView" toState="listView" autoReverse="true">
<s:Fade duration="200" target="{contactPane}" />
</s:Transition>
<s:Transition fromState="listView" toState="contactView" autoReverse="true">
<s:Fade duration="200" target="{contactPane}" />
</s:Transition>
</s:transitions>Now, if you save and compile your Flash Builder project, you’ll see
that when you click in the contact list, the selected contact’s data
appears on the right-hand side of the display.