<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Web Designer - Defining the internet through beautiful design &#187; Adobe AIR</title>
	<atom:link href="http://www.webdesignermag.co.uk/category/tutorials/adobe-air-tutorials/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.webdesignermag.co.uk</link>
	<description>Web Design for real people</description>
	<lastBuildDate>Mon, 26 Jul 2010 11:20:08 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Develop an AIR Contact app in Flex Part 2</title>
		<link>http://www.webdesignermag.co.uk/blog/develop-an-air-contact-app-in-flex-part-2/</link>
		<comments>http://www.webdesignermag.co.uk/blog/develop-an-air-contact-app-in-flex-part-2/#comments</comments>
		<pubDate>Tue, 11 Aug 2009 10:02:11 +0000</pubDate>
		<dc:creator>Steve Jenkins</dc:creator>
				<category><![CDATA[Adobe AIR]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.webdesignermag.co.uk/?p=2846</guid>
		<description><![CDATA[
STORE ALL YOUR FRIENDS&#8217; AND FAMILY&#8217;S CONTACT INFORMATION IN A USEFUL AIR APPLICATION. LEARN HOW TO ADD, EDIT AND DELETE DATA IN AN SQLITE DATABASE IN PART 2 OF THIS TUTORIAL
In Part 1 we began coding an AIR contact manager with Flex and realised that the sheer amount of code meant we’d have to split it over two parts. So if you’re encountering this from scratch you’ll need to bear a couple of things in mind. Step 1 is in fact Step 16 in the overall tutorial. Find the code ...]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.webdesignermag.co.uk/wp-content/uploads/2009/08/final.jpg"><img class="alignnone size-full wp-image-2852" title="final" src="http://www.webdesignermag.co.uk/wp-content/uploads/2009/08/final.jpg" alt="final" width="500" height="387" /></a></p>
<p>STORE ALL YOUR FRIENDS&#8217; AND FAMILY&#8217;S CONTACT INFORMATION IN A USEFUL AIR APPLICATION. LEARN HOW TO ADD, EDIT AND DELETE DATA IN AN SQLITE DATABASE IN PART 2 OF THIS TUTORIAL</p>
<p>In Part 1 we began coding an AIR contact manager with Flex and realised that the sheer amount of code meant we’d have to split it over two parts. So if you’re encountering this from scratch you’ll need to bear a couple of things in mind. Step 1 is in fact Step 16 in the overall tutorial. Find the code for <a href="http://www.webdesignermag.co.uk/tutorial-files/issue-146-tutorial-files/" target="_self">Part 2 here</a> and <a href="http://www.webdesignermag.co.uk/tutorial-files/issue-145-tutorial-files/" target="_self">Part 1 here</a></p>
<p><em><strong>Author: Simon Bailey | Originally appeared in Issue 146</strong></em><a href="http://www.webdesignermag.co.uk/tutorial-files/issue-145-tutorial-files/" target="_self"></a></p>
<p><strong>1 Instantiate SQLQueries</strong><br />
In ContactManager, navigate to the onOpen() method and enter the text below to create a new instance of the SQLQueries class. Using the instance of the LConnector class, parse the SQLConnection in the SQLQueries constructor and add an OnContacts method to the CONTACTS_ARR event, dispatching the ArrayCollection of contacts.</p>
<p><em>private function onOpen( e:Event ):void<br />
sqliteQueries = new SQLQueries( sqliteConnector.connection );<br />
sqliteQueries.addEventListener( SQLQueries.CONTACTS_ARR, onContacts );<br />
}<br />
private function onContacts( e:AllContactsEvent ):void<br />
{<br />
}</em></p>
<p><strong>2 Load contacts into wrapper</strong><br />
We need to parse the ArrayCollection of contacts to the ContactsWrapper. Enter the code below. Assign the contacts as the ContactList data grid’s data provider. In the onContacts() method in ContactManager, parse the contacts to  setContacts().</p>
<p><em>public function setContacts( contacts:ArrayCollection ):void{<br />
c_list.contact_dg.dataProvider = contacts;}<br />
private function onContacts( e:AllContactsEvent ):void{<br />
contactWrapper.setContacts( e.contacts );}</em></p>
<p><strong>3 Display contact<br />
</strong>In ContactWrapper, add a listener to the Select event on the ContactList component, calling a method named displayContact. The Contact variable is populated from the selectedContact reference assigned through mx:Binding in ContactList.</p>
<p><em>private function displayContact():void{<br />
c_details.add = false;<br />
c_details.edit = false;<br />
c_details.contact = c_list.selectedContact;<br />
}</em><strong></strong></p>
<p><strong>4 Add, edit, delete<br />
</strong>Still in the ContactWrapper class, enter the onClick() method. A switch statement analyses the eventName parsed and acts accordingly. Edit has two modes: edit, which transitions ContactDetails state, and save to retrieve edited contact details and saveContact().</p>
<p><em>private function onClick( eventName:String ):void<br />
{<br />
switch ( eventName )<br />
{<br />
case ‘edit’:<br />
if( !c_details.edit ){<br />
c_details.edit = true;<br />
}<br />
else<br />
{<br />
var contact:ContactVO = c_details.saveContact();<br />
( contact.firstName != “” ) ? saveContact( contact ) : c_details.clear();<br />
c_details.edit = false;<br />
}<br />
break;<br />
case ‘add’:<br />
c_details.edit = true;<br />
c_details.add = true;<br />
c_details.newContact();<br />
c_list.deSelect();<br />
break;<br />
case ‘delete’:<br />
if( c_list.contact_dg.selectedIndex != -1 ){<br />
c_list.deSelect();<br />
c_details.clear();</em><strong><br />
</strong><em>}<br />
break;<br />
}}</em><strong></strong></p>
<p><strong>5 saveContact<br />
</strong>If the contact has been edited, saveContact() is fired. This method expects a contact value object as its parameter and uses a custom event to dispatch the contact for storage. Add/edit is determined by the ContactDetails’ add Boolean.<strong></strong></p>
<p><strong></strong><em>private function saveContact( contact:ContactVO ):void{<br />
if( !c_details.add ){<br />
}<br />
else<br />
{<br />
}<br />
}</em><strong><br />
</strong></p>
<p><strong>6 Creating custom events</strong><br />
We will create transparent background divs, with position: absolute set so they sit behind the content. Create the following class .background in the style sheet:<strong></strong></p>
<p><strong></strong><em>package events<br />
{<br />
import flash.events.Event;<br />
import vo.ContactVO;<br />
public class ContactEvent extends Event{<br />
public var contact:ContactVO;<br />
public function ContactEvent( _contact:ContactVO, type:String, bubbles:<br />
Boolean=false )<br />
{<br />
super( type, bubbles );<br />
this.contact = _contact;<br />
}<br />
public override function clone():Event<br />
{<br />
return new ContactEvent( contact, type, bubbles );<br />
}}}</em><strong></strong></p>
<p><strong>7 Overlaying content<br />
</strong>Create two new ActionScript classes that extend Event in the events directory named ‘ContactEvent’ and ‘AllContactsEvent’. These custom events will be used to dispatch a contact value object around our application and an ArrayCollection of contacts.</p>
<p><em>&lt;!&#8211; Dispatched Events &#8211;&gt;<br />
&lt;mx:Metadata&gt;<br />
[Event(name=”closeWin”, type=”flash.events.Event”)]<br />
[Event(name=”contactDelete”, type=”events.ContactEvent”)]<br />
[Event(name=”contactEdit”, type=”events.ContactEvent”)]<br />
[Event(name=”contactAdd”, type=”events.ContactEvent”)]<br />
&lt;/mx:Metadata&gt;<br />
// Dispatched events to add, edit and delete<br />
private static const CONTACT_DELETE:String = ‘contactDelete’;<br />
private static const CONTACT_EDIT:String = ‘contactEdit’;<br />
private static const CONTACT_ADD:String = ‘contactAdd’;<br />
case ‘delete’:<br />
if( c_list.contact_dg.selectedIndex != -1 ){<br />
var e:ContactEvent = new ContactEvent( c_list.selectedContact as ContactVO, CONTACT_<br />
DELETE, true );<br />
dispatchEvent( e );</em><strong><br />
</strong><em>c_list.deSelect();<br />
c_details.clear();<br />
}<br />
break;<br />
var e:ContactEvent;<br />
if( !c_details.add )<br />
{<br />
e = new ContactEvent( c_details.contact as ContactVO, CONTACT_EDIT, true );<br />
}<br />
else<br />
{<br />
e = new ContactEvent( c_details.contact as ContactVO, CONTACT_ADD, true );<br />
}<br />
dispatchEvent( e );</em><strong></strong></p>
<p><strong>8 Listen for custom events<br />
</strong>Edit the ContactWrapper component to listen for the dispatched custom events for Add,Edit and Delete. Create the three methods to handle the events and call the appropriate method in SQLQueries, parsing the contact value object stored in our custom event.<strong></strong></p>
<p><strong>/</strong><em>/ Add contact<br />
private function addContact( e:ContactEvent ):void<br />
{<br />
sqliteQueries.addContact( e.contact );<br />
}<br />
// Edit contact<br />
private function editContact( e:ContactEvent ):void<br />
{<br />
sqliteQueries.editContact( e.contact );<br />
}<br />
// Delete contact<br />
private function deleteContact( e:ContactEvent ):void<br />
{<br />
sqliteQueries.deleteContact( e.contact );<br />
}<br />
&lt;!&#8211; Contact Manager wrapper &#8211;&gt;<br />
&lt;view:ContactWrapper id=”contactWrapper”<br />
width=”100%” height=”100%” x=”0” y=”0”<br />
closeWin=”closeWindow( event )”<br />
contactDelete=”deleteContact( event )”<br />
contactAdd=”addContact( event )”<br />
contactEdit=”editContact( event )” /&gt;</em><strong></strong></p>
<p><strong>9 Modification queries<br />
</strong>Add your final three methods to add, edit and delete data from our SQLite database.<strong></strong></p>
<p><strong></strong>// Edit a contact<br />
public function editContact( _contact:ContactVO ):void<br />
{<br />
var _sql:String = “UPDATE records SET firstName=:firstName, “ +<br />
“lastName=:lastName, “ +<br />
“email=:email, “ +<br />
“mobileTel=:mobileTel, “ +<br />
“homeTel=:homeTel, “ +<br />
“address=:address “ +<br />
“WHERE contactID=:contactID”;<br />
execute( _sql, contactResult, _contact, EDIT );<br />
}// Add a contact<br />
public function addContact( _contact:ContactVO ):void<br />
{<br />
var _sql:String = “INSERT INTO records (firstName, lastName, email, mobileTel,<br />
homeTel, address) “ +<br />
“VALUES (:firstName, :lastName, :email, :mobileTel, :homeTel, :address)”;<br />
execute( _sql, contactResult, _contact );<br />
}// Delete a contact<br />
public function deleteContact( _contact:ContactVO ):void{<br />
var _sql:String = “DELETE FROM records WHERE contactID=:contactID”;<br />
execute( _sql, contactResult, _contact, DELETE );}<br />
private function contactResult( e:SQLEvent ):void<br />
{<br />
getContacts();}}}<strong></strong></p>
<p><strong>10 Drag window<br />
</strong>Add a mouseDown Event Listener to the ContactWrapper instance, calling an onDrag() method. Within onDrag, call the startMove method on the NativeWindow class.<strong></strong></p>
<p><strong></strong><em>mouseDown=”onDrag( event )”<br />
// Enable drag of app<br />
private function onDrag(e:MouseEvent):void<br />
{<br />
stage.nativeWindow.startMove();<br />
}</em><strong></strong></p>
<p><strong>11 XML descriptor file<br />
</strong>Here you outline the application identifier, file name, description and window settings for display purposes.<strong><br />
</strong><em><br />
&lt;?xml version=”1.0” encoding=”UTF-8”?&gt;<br />
&lt;application xmlns=”http://ns.adobe.com/air/application/1.0”&gt;<br />
&lt;id&gt;ContactManager&lt;/id&gt;<br />
&lt;filename&gt;ContactManager&lt;/filename&gt;<br />
&lt;name&gt;Contact Manager&lt;/name&gt;<br />
&lt;version&gt;v1&lt;/version&gt;<br />
&lt;description&gt;Contact Manager application for managing all your friends and family<br />
contact information.&lt;/description&gt;<br />
&lt;initialWindow&gt;<br />
&lt;content&gt;[This value will be overwritten by Flex Builder in the<br />
output app.xml]&lt;/content&gt;<br />
&lt;title&gt;Contact Manager&lt;/title&gt;<br />
&lt;systemChrome&gt;none&lt;/systemChrome&gt;<br />
&lt;transparent&gt;false&lt;/transparent&gt;<br />
&lt;/initialWindow&gt;<br />
&lt;/application&gt;</em><strong></strong></p>
<p><strong>12 Test your app<br />
</strong>Click Run&gt;Run ContactManager, then click Add and add some contact information into the details panel. Click Save, test, edit and delete. Now click Project&gt;Export Release Build. Click Next&gt;Create to build a new digital certificate. Click Next and ensure the XML file, contacts database and SWF file are selected, then click Finish. Finally, double-click your newly created AIR file. Select Install, keep the next window’s defaults and select Continue.<strong></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.webdesignermag.co.uk/blog/develop-an-air-contact-app-in-flex-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Develop an AIR Contact app in Flex Part 1</title>
		<link>http://www.webdesignermag.co.uk/blog/develop-an-air-contact-app-in-flex-part-1/</link>
		<comments>http://www.webdesignermag.co.uk/blog/develop-an-air-contact-app-in-flex-part-1/#comments</comments>
		<pubDate>Fri, 31 Jul 2009 09:57:03 +0000</pubDate>
		<dc:creator>Steve Jenkins</dc:creator>
				<category><![CDATA[Adobe AIR]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Contact Manager]]></category>
		<category><![CDATA[Flex Builder 3]]></category>

		<guid isPermaLink="false">http://www.webdesignermag.co.uk/?p=2826</guid>
		<description><![CDATA[
STORE ALL YOUR CONTACTS IN A USEFUL AIR APPLICATION BY LEARNING ADD, EDIT AND DELETE DATA TECHNIQUES WITHIN AN SQLITE DATABASE.
Developers can now take their RIA concepts out of the browser and onto the desktop. There are so many concepts feasible in an AIR application and with the ability to store data in a local database, programs we have long been familiar with can now be rebuilt with your own added flair. This tutorial will show you how to build a simplified version of Apple’s Address Book using SQLite to ...]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.webdesignermag.co.uk/wp-content/uploads/2009/07/final.jpg"><img class="alignnone size-full wp-image-2830" title="final" src="http://www.webdesignermag.co.uk/wp-content/uploads/2009/07/final.jpg" alt="final" width="500" height="385" /></a><br />
STORE ALL YOUR CONTACTS IN A USEFUL AIR APPLICATION BY LEARNING ADD, EDIT AND DELETE DATA TECHNIQUES WITHIN AN SQLITE DATABASE.</p>
<p>Developers can now take their RIA concepts out of the browser and onto the desktop. There are so many concepts feasible in an AIR application and with the ability to store data in a local database, programs we have long been familiar with can now be rebuilt with your own added flair. This tutorial will show you how to build a simplified version of Apple’s Address Book using SQLite to store contact information. The UI will be created using MXML components with ActionScript classes to control all functionality. We urposely aimed to use a variety of techniques in the code to handle states, communicate data, etc, so we would recommend studying the source for further insight. To complete this tutorial, you will need to use the source files to access all of the code; certain scripts are covered in each step. In addition, the guide is split over two parts with next month’s final text including the PDF pages and final files from here.</p>
<p><em><strong>Author: Simon Bailey | Originally appeared in Issue 146</strong></em></p>
<p><strong>01 Download required software</strong><br />
<a href="http://www.webdesignermag.co.uk/wp-content/uploads/2009/07/step1.jpg"><img class="alignnone size-full wp-image-2831" title="step1" src="http://www.webdesignermag.co.uk/wp-content/uploads/2009/07/step1.jpg" alt="step1" width="500" height="313" /></a><br />
Download the latest AIR runtime from http://get.adobe.com/air/ and follow the installation instructions provided by Adobe. If you do not have Flex Builder 3 installed, visit www.adobe.com/products/flex/ to download the 60-day free trial and install as instructed. Now we are ready to start setting up our project.</p>
<p><strong>02 New Flex project</strong><br />
<a href="http://www.webdesignermag.co.uk/wp-content/uploads/2009/07/step2.jpg"><img class="alignnone size-full wp-image-2829" title="step2" src="http://www.webdesignermag.co.uk/wp-content/uploads/2009/07/step2.jpg" alt="step2" width="500" height="448" /></a><br />
To fire up Flex, select File&gt;New&gt;Flex Project. Enter ‘ContactManager’ as the project name, check Default Location and check the Desktop application (runs in Adobe AIR). Ensure Application Server Type is set to None and click Next. Keep the default output folder and click Next, once again keeping all the defaults. Click Finish.</p>
<p><strong>03 Construct main component</strong><br />
Within the opening WindowedApplication tag in ContactManager.mxml, enter the code as below. Enter the second set of text above to set some basic styling for the contact manager. Create four new folders in the SRC directory: ‘components’, ‘events’, ‘SQLite’ and ‘VO’. Add the provided contacts database from the CD to the SRC folder.</p>
<p><em>&lt;mx:WindowedApplication xmlns:mx=”http://www.adobe.com/2006/mxml”<br />
layout=”absolute”<br />
width=”450”<br />
height=”360”<br />
showFlexChrome=”false”<br />
verticalScrollPolicy=”off”<br />
horizontalScrollPolicy=”off”&gt;<br />
&lt;mx:Style&gt;<br />
TitleWindow<br />
{<br />
cornerRadius: 0;<br />
roundedBottomCorners: false;<br />
headerColors: #ffffff, #999999;<br />
footerColors: #cccccc, #999999;<br />
borderThicknessLeft: 0;<br />
borderThicknessTop: 0;<br />
borderThicknessBottom: 0;<br />
borderThicknessRight: 0;<br />
headerHeight: 34;<br />
shadowDistance: 0;<br />
dropShadowColor: #333333;<br />
titleStyleName: “contactTitle”;}<br />
.contactTitle<br />
{<br />
color: #333333;<br />
fontFamily: Verdana;<br />
fontSize: 12;<br />
fontWeight: bold;}<br />
&lt;/mx:Style&gt;</em></p>
<p><strong>04 Contact value object</strong><br />
Right-click the VO folder and create a new ActionScript class named ‘ContactVO’ and uncheck Generate constructor from superclass. Enter the code below. This custom value object will ensure correct data typing of contact details is used throughout this. The [Bindable] meta-data tag assigns instances of this class to MXML components.<br />
<em><br />
package vo<br />
{<br />
[Bindable]<br />
public class ContactVO<br />
{<br />
public var contactID:int;<br />
public var firstName:String;<br />
public var lastName:String;<br />
public var email:String;<br />
public var mobileTel:String;<br />
public var homeTel:String;<br />
public var address:String;<br />
public function ContactVO(){}<br />
}<br />
}</em></p>
<p><strong>05 Build a UI wrapper</strong><br />
Right-click the components folder, select New&gt;MXML Component. Set the file name as ‘ContactWrapper’ and base it on a TitleWindow. Clear width and height values and define layout as absolute. Within the opening TitleWindow tag, ensure the code is as below. Within the opening and closing TitleWindow tags, create a new &lt;mx:Script&gt; tag.</p>
<p><em>&lt;mx:TitleWindow xmlns:mx=”http://www.adobe.com/2006/mxml”<br />
xmlns:view=”components.*”<br />
layout=”absolute”<br />
title=”AIR Contact Manager”<br />
showCloseButton=”true”&gt;</em></p>
<p><strong>06 Add the wrapper</strong><br />
In ContactManager.mxml, ensure the code now looks like above. The main two changes here are a new XMLNS reference to our component’s directory so we can add the ContactWrapper component, which is near the bottom of the script. Next, we added an onCreationComplete method initApp() that runs when the component is fully created.</p>
<p><em>&lt;&lt;mx:WindowedApplication xmlns:mx=”http://www.adobe.com/2006/mxml”<br />
xmlns:view=”components.*” layout=”absolute”<br />
width=”450” height=”360”<br />
showFlexChrome=”false” verticalScrollPolicy=”off”<br />
horizontalScrollPolicy=”off”<br />
creationComplete=”initApp()”&gt;<br />
&lt;mx:Script&gt;<br />
&lt;![CDATA[private function initApp():void{}]]&gt;<br />
&lt;/mx:Script&gt;<br />
&lt;view:ContactWrapper id=”contactWrapper”<br />
width=”100%” height=”100%” x=”0” y=”0” /&gt;</em></p>
<p><strong>07 Contact list</strong><br />
In the components folder, create a new MXML component extending Canvas named ‘ContactList’, adding the below code. This component will act as a simple list of all the contacts stored in our database. setName() concatenates the first and last name strings for display. &lt;mx:Binding&gt; binds items in the data grid to the variable selectedContact.</p>
<p><em>&lt;&lt;?xml version=”1.0” encoding=”utf-8”?&gt;<br />
&lt;mx:Canvas xmlns:mx=”http://www.adobe.com/2006/mxml”&gt;<br />
&lt;mx:Metadata&gt;<br />
[Event(name=”select”, type=”flash.events.Event”)]<br />
&lt;/mx:Metadata&gt;<br />
&lt;mx:Script&gt;<br />
&lt;![CDATA[<br />
import mx.controls.dataGridClasses.DataGridColumn;<br />
import vo.ContactVO;<br />
public static const SELECT:String = ‘select’;<br />
[Bindable] public var selectedContact:ContactVO;<br />
private function setName( item:Object, column:DataGridColumn ):String<br />
{<br />
return String( item.firstName +” “+ item.lastName );}<br />
public function deSelect():void{<br />
contact_dg.selectedIndex = -1;}]]&gt;<br />
&lt;/mx:Script&gt;<br />
&lt;mx:Binding source=”contact_dg.selectedItem as ContactVO” destina<br />
tion=”selectedContact”/&gt;<br />
&lt;mx:DataGrid id=”contact_dg” width=”100%” height=”100%”<br />
click=”if ( contact_dg.selectedIndex != -1) dispatchEvent(<br />
new Event( SELECT, true ) );”&gt;<br />
&lt;mx:columns&gt;<br />
&lt;mx:DataGridColumn labelFunction=”setName” headerText=”Name” /&gt;<br />
&lt;/mx:columns&gt;&lt;/mx:DataGrid&gt;&lt;/mx:Canvas&gt;</em><br />
<strong><br />
08 Contact details</strong><br />
In the components folder, create a new MXML component extending Canvas named ‘ContactDetails’, adding the below code. This displays all the contact data when selected in the ContactList. This component has two visual states, one to view the data and one to edit the data. State change is controlled by the Boolean variable ‘edit’.</p>
<p><em>i&lt;?xml version=”1.0” encoding=”utf-8”?&gt;<br />
&lt;mx:Canvas xmlns:mx=”http://www.adobe.com/2006/mxml”<br />
verticalScrollPolicy=”off”<br />
horizontalScrollPolicy=”off”<br />
currentState=”{ ( edit ) ? ‘edit_view’ : ‘’ }”&gt;<br />
&lt;mx:states&gt;<br />
&lt;mx:State name=”edit_view”&gt;<br />
&lt;mx:RemoveChild target=”{ first_txt }” /&gt;<br />
&lt;mx:RemoveChild target=”{ last_txt }” /&gt;<br />
&lt;mx:RemoveChild target=”{ email_txt }” /&gt;<br />
&lt;mx:RemoveChild target=”{ mobile_txt }” /&gt;<br />
&lt;mx:RemoveChild target=”{ home_txt }” /&gt;<br />
&lt;mx:AddChild position=”lastChild”&gt;<br />
&lt;mx:TextInput id=”first_in” text=”{ contact.firstName }” width=”95”<br />
x=”69” y=”10” /&gt;<br />
&lt;/mx:AddChild&gt;&lt;mx:AddChild position=”lastChild”&gt;<br />
&lt;mx:TextInput id=”last_in” text=”{ contact.lastName }” width=”95”<br />
x=”174” y=”10” /&gt;<br />
&lt;/mx:AddChild&gt;&lt;mx:AddChild position=”lastChild”&gt;<br />
&lt;mx:TextInput id=”email_in” text=”{ contact.email }” width=”200”<br />
x=”69” y=”50” /&gt;<br />
&lt;/mx:AddChild&gt;&lt;mx:AddChild position=”lastChild”&gt;<br />
&lt;mx:TextInput id=”mobile_in” text=”{ contact.mobileTel }” width=”200”<br />
x=”69” y=”90” /&gt;<br />
&lt;/mx:AddChild&gt;&lt;mx:AddChild position=”lastChild”&gt;<br />
&lt;mx:TextInput id=”home_in” text=”{ contact.homeTel }” width=”200”<br />
x=”69” y=”130” /&gt;<br />
&lt;/mx:AddChild&gt;&lt;/mx:State&gt;&lt;/mx:states&gt;<br />
&lt;!&#8211; Transition for the screen &#8211;&gt;<br />
&lt;mx:transitions&gt;<br />
&lt;mx:Transition id=”fadeTransition” fromState=”*” toState=”*”&gt;<br />
&lt;mx:Parallel target=”{ this }”&gt;<br />
&lt;mx:Dissolve duration=”600”/&gt;<br />
&lt;/mx:Parallel&gt;&lt;/mx:Transition&gt;<br />
&lt;/mx:transitions&gt;<br />
&lt;!&#8211; First name &#8211;&gt;<br />
&lt;mx:Text id=”first_txt”<br />
text=”{ contact.firstName }” fontWeight=”bold”<br />
fontSize=”14” x=”66” y=”10”/&gt;<br />
&lt;!&#8211; Last name &#8211;&gt;<br />
&lt;mx:Text id=”last_txt”<br />
text=”{ contact.lastName }” fontWeight=”bold”<br />
fontSize=”14” x=”{ first_txt.x + first_txt.width + 3 }”<br />
y=”10”/&gt;<br />
&lt;!&#8211; Label = email &#8211;&gt;<br />
&lt;mx:Label text=”email”<br />
color=”#666666” fontSize=”12” x=”23” y=”50”/&gt;<br />
&lt;!&#8211; Label = mobile &#8211;&gt;<br />
&lt;mx:Label text=”mobile”<br />
color=”#666666” fontSize=”12”<br />
x=”15” y=”90”/&gt;<br />
&lt;!&#8211; Label = home &#8211;&gt;<br />
&lt;mx:Label text=”home”<br />
color=”#666666” fontSize=”12”<br />
x=”21” y=”130”/&gt;<br />
&lt;!&#8211; Label = address &#8211;&gt;</em></p>
<p><em></em><strong>09 Populating contact details</strong><br />
Still in ContactDetails, enter the below code. Data will be parsed into this component as a custom contact value object, with each visual component referencing the object for data to display. To save the contact-edited information, the entered text in each TextInput component is assigned to its corresponding variable in the value object.<em></em></p>
<p><em>&lt;mx:Script&gt;<br />
&lt;![CDATA[<br />
import vo.ContactVO;<br />
[Bindable] public var contact:ContactVO;<br />
[Bindable] public var edit:Boolean = false;<br />
public var add:Boolean;<br />
public function newContact():void{<br />
contact = new ContactVO();<br />
}<br />
public function saveContact():ContactVO<br />
{<br />
contact.firstName = first_in.text;<br />
contact.lastName = last_in.text;<br />
contact.email = email_in.text;<br />
contact.mobileTel = mobile_in.text;<br />
contact.homeTel = home_in.text;<br />
contact.address = address_txt.text;<br />
return contact;<br />
}<br />
public function clear():void<br />
{<br />
newContact();<br />
edit = false;<br />
}]]&gt;&lt;/mx:Script&gt;<br />
&lt;mx:Label text=”address”<br />
color=”#666666” fontSize=”12”<br />
x=”5” y=”170”/&gt;<br />
&lt;!&#8211; Email &#8211;&gt;<br />
&lt;mx:Text id=”email_txt”<br />
text=”{ contact.email }” color=”#000000”<br />
fontSize=”11” x=”66” y=”50”/&gt;<br />
&lt;!&#8211; Mobile &#8211;&gt;<br />
&lt;mx:Text id=”mobile_txt”<br />
text=”{ contact.mobileTel }”<br />
color=”#000000” fontSize=”11” x=”69” y=”91”/&gt;<br />
&lt;!&#8211; Home &#8211;&gt;<br />
&lt;mx:Text id=”home_txt”<br />
text=”{ contact.homeTel }” color=”#000000”<br />
fontSize=”11” x=”69” y=”131”/&gt;<br />
&lt;!&#8211; Address &#8211;&gt;<br />
&lt;mx:TextArea id=”address_txt”<br />
text=”{ contact.address }”<br />
color=”#000000” fontSize=”11” right=”40” left=”69”<br />
height=”90” borderThickness=”{ ( edit ) ? 1 : 0 }”<br />
wordWrap=”true” editable=”{ edit }” y=”171”/&gt;<br />
&lt;/mx:Canvas&gt;</em></p>
<p><strong>10 Add components to wrapper</strong><br />
Return to ContactWrapper and add the code below. Here we use the HDividedBox component to display our list and details custom components. This enables us to mimic Address Book and adjust the width of each component accordingly. A ControlBar is added to hold the buttons controlling the application’s add/edit and delete functionality.</p>
<p><em>&lt;!&#8211; Contact components container &#8211;&gt;<br />
&lt;mx:HDividedBox id=”contactContainer” x=”0” y=”0”<br />
width=”100%” height=”100%”&gt;<br />
&lt;view:ContactList id=”c_list” width=”30%” height=”100%” select=”displa<br />
yContact()” /&gt;<br />
&lt;view:ContactDetails id=”c_details” width=”70%” height=”100%” /&gt;<br />
&lt;/mx:HDividedBox&gt;<br />
&lt;mx:ControlBar id=”c_controls” width=”100%” height=”37” y=”229”&gt;<br />
&lt;mx:Button id=”addButton” height=”16” label=”add” click=”onClick(<br />
ADD )” x=”0”/&gt;<br />
&lt;mx:Button id=”deleteButton” height=”16” label=”delete”<br />
click=”onClick( DELETE )”/&gt;</em><br />
<em>&lt;mx:Spacer width=”{ c_details.width + c_list.width &#8211; (<br />
deleteButton.x + deleteButton.width + editButton.width + 20 ) }”/&gt;<br />
&lt;mx:Button id=”editButton” height=”16” label=”{ (c_details.edit ) ?<br />
‘save’ : ‘edit’ }”<br />
enabled=”{ c_details.edit || c_list.contact_dg.selectedIndex != -1<br />
}” click=”onClick( EDIT )”/&gt;&lt;/mx:ControlBar&gt;</em></p>
<p><strong>11 Handle window closure</strong><br />
TitleWindow has a close button available if showCloseButton is set as true. Enter the code below into the TitleWindow tag and within the mx:Script tags type: private static const CLOSE_WIN:String = ‘closeWin’. This will dispatch a named constant on clicking the close button. We will pick up this event in the ContactManager.</p>
<p><em>&lt;mx:TitleWindow xmlns:mx=”http://www.adobe.com/2006/mxml”<br />
xmlns:view=”components.*”<br />
layout=”absolute”<br />
title=”AIR Contact Manager”<br />
showCloseButton=”true”<br />
close=”{ dispatchEvent( new Event ( CLOSE_WIN ) ); }”&gt;</em></p>
<p><strong>12 Listen for close event</strong><br />
To listen out for the ContactWrapper dispatching our closeWin event modify the ContactWrapper tag as below and enter the closeWindow method within mx:Script tags. When the closeWin event is dispatched, the closeWindow method is fired calling the close() method in the NativeWindow class, and in turn closes the application window.</p>
<p><em>&lt;view:ContactWrapper id=”contactWrapper”<br />
width=”100%” height=”100%” x=”0” y=”0”<br />
closeWin=”closeWindow( event )” /&gt;<br />
private function closeWindow( e:Event ):void{<br />
stage.nativeWindow.close();}</em></p>
<p><strong>13 Transparent backgrounds</strong><br />
Now we have the basic visual framework in place, let’s build our back-end. In the SQLite<br />
folder, create an ActionScript class to extend EventDispatcher named ‘SQLConnector’.<br />
This class will handle asynchronous connections to our SQLite database and dispatch<br />
SQLConnectionEvents for the application to progress and start querying the database.<br />
Enter the code as listed below:</p>
<p><em>package sqlite{<br />
import flash.data.SQLConnection;<br />
import flash.events.*;<br />
import flash.filesystem.File;<br />
public class SQLConnector extends EventDispatcher{<br />
public static const OPEN:String = ‘open’;<br />
public static const CLOSE:String = ‘close’;<br />
public static const ERROR:String = ‘error’;<br />
private var _connection:SQLConnection;<br />
private var _dbFileName:String;<br />
private var _dbFile:File;<br />
public function SQLConnector( name:String ){<br />
_dbFileName = name;<br />
_dbFile = File.applicationDirectory.resolvePath( _dbFileName );}<br />
public function connect():void{<br />
_connection = new SQLConnection();<br />
_connection.addEventListener( SQLEvent.OPEN, onOpen );<br />
_connection.addEventListener( SQLEvent.CLOSE, onClose );<br />
_connection.addEventListener( SQLErrorEvent.ERROR, onError );<br />
_connection.openAsync( _dbFile );}<br />
public function disconnect():void{<br />
_connection.close();}</em><br />
<em>public function get connection():SQLConnection{<br />
return _connection;}<br />
private function onOpen( e:SQLEvent ):void{<br />
dispatchEvent( new Event( OPEN ) );}<br />
private function onClose( e:SQLEvent ):void{<br />
dispatchEvent( new Event( CLOSE ) );}<br />
private function onError( e:SQLErrorEvent ):void{<br />
dispatchEvent( new Event( ERROR ) );<br />
}}}</em></p>
<p><strong>14 Set up connection</strong><br />
Return to the ContactManager and within the initApp() method, create a new instance of the SQLConnector ensuring that the class is imported. Parse in the constructor the named constant that has the database name as a ‘String’ and call the Connect method. Assign listeners for all class-dispatched events: OPEN, CLOSE and ERROR.</p>
<p><em>import sqlite.SQLConnector;<br />
private static const DATABASE:String = “contacts”;<br />
private function initApp():void<br />
{<br />
sqliteConnector = new SQLConnector( DATABASE );<br />
sqliteConnector.connect();<br />
sqliteConnector.addEventListener( SQLConnector.OPEN, onOpen );<br />
sqliteConnector.addEventListener( SQLConnector.CLOSE, onClose );<br />
sqliteConnector.addEventListener( SQLConnector.ERROR, onError );}<br />
private function onOpen( e:Event ):void<br />
{<br />
}<br />
private function onClose( e:Event ):void{<br />
trace(“disconnection”);<br />
}<br />
private function onError( e:Event ):void{<br />
trace(“connection error”);<br />
}</em></p>
<p><strong>15 Start querying</strong><br />
In the SQLite folder, create an ActionScript class to extend EventDispatcher named ‘SQLQueries’. This class will handle all the database queries and dispatch results for each query made. This class needs a reference to the SQLConnection, adds, edits and deletes, and has a method to build the table ‘records’ in the database.</p>
<p><em>package sqlite<br />
{<br />
import events.AllContactsEvent;<br />
import flash.data.*;<br />
import flash.errors.SQLError;<br />
import flash.events.*;<br />
import mx.collections.ArrayCollection;<br />
import vo.ContactVO;<br />
public class SQLQueries extends EventDispatcher{<br />
public static const CONTACTS_ARR:String = ‘contactsArr’;<br />
private static const EDIT:String = ‘edit’;<br />
private static const DELETE:String = ‘delete’;<br />
private var _connection:SQLConnection;<br />
private var _statement:SQLStatement;<br />
private var _data:ArrayCollection;<br />
public function SQLQueries( conn:SQLConnection ){<br />
_connection = conn;<br />
buildTable();}<br />
private function buildTable():void{<br />
var _sql:String = “CREATE TABLE IF NOT EXISTS records ( contactID<br />
INTEGER PRIMARY KEY AUTOINCREMENT, “ +</em><br />
<em>“firstName TEXT DEFAULT ‘’, “ +<br />
“lastName TEXT DEFAULT ‘’, “ +<br />
“email TEXT DEFAULT ‘’, “ +<br />
“mobileTel TEXT DEFAULT ‘’, “ +<br />
“homeTel TEXT DEFAULT ‘’, “ +<br />
“address TEXT DEFAULT ‘’)”;<br />
execute( _sql, buildTableResult );}<br />
public function getContacts():void{<br />
var _sql:String = “SELECT * FROM records”;<br />
execute( _sql, getContactsResult );<br />
}<br />
private function execute( sql:String, _handler:<br />
Function, params:ContactVO=null, action:String=”” ):void{<br />
try<br />
{<br />
var handler:Function = _handler;<br />
_statement = new SQLStatement();<br />
_statement.sqlConnection = _connection;<br />
_statement.text = sql;<br />
if( params )<br />
{<br />
_statement.clearParameters();<br />
if( action != “” ){<br />
_statement.parameters[“:contactID”] = params.contactID;}<br />
if( action != DELETE ){<br />
_statement.parameters[“:firstName”] = params.firstName;<br />
_statement.parameters[“:lastName”] = params.lastName;<br />
_statement.parameters[“:email”] = params.email;<br />
_statement.parameters[“:mobileTel”] = params.mobileTel;<br />
_statement.parameters[“:homeTel”] = params.homeTel;<br />
_statement.parameters[“:address”] = params.address;}}<br />
_statement.addEventListener( SQLEvent.RESULT, handler );<br />
_statement.execute();<br />
}<br />
catch ( e:SQLError )<br />
{<br />
trace(“Error with SQLStatement execution”);<br />
}}<br />
private function buildTableResult( e:SQLEvent ):void{<br />
getContacts();}<br />
private function getContactsResult( e:SQLEvent ):void{<br />
var contacts:ArrayCollection = new ArrayCollection();<br />
for each ( var c:Object in _statement.getResult().data ){<br />
var contact:ContactVO = new ContactVO();<br />
contact.contactID = c.contactID;<br />
contact.firstName = c.firstName;<br />
contact.lastName = c.lastName;<br />
contact.email = c.email;<br />
contact.mobileTel = c.mobileTel;<br />
contact.homeTel = c.homeTel;<br />
contact.address = c.address;<br />
contacts.addItem( contact );}<br />
var event:AllContactsEvent = new AllContactsEvent( contacts,<br />
CONTACTS_ARR, true );<br />
dispatchEvent( event );}}}<br />
</em></p>
<p><strong>The code marathon continues in Part 2 &#8211; coming soon</strong><em><br />
</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.webdesignermag.co.uk/blog/develop-an-air-contact-app-in-flex-part-1/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
