navigate site menu

Become a member and get unlimited access to every course in the library. Try it free for 7 days

Flex 3 Beyond the Basics

Flex 3 Beyond the Basics

with David Gassner

 


In Flex 3 Beyond the Basics, David Gassner delves into advanced Flex development skills, including custom popup windows and programmatic animation; parsing XML with E4X; and integrating Flex applications with ColdFusion, ASP.NET, and PHP. He explores effective ways to use Flash and Flex together, including the exchange of graphical skins, symbols, and components. David also demonstrates how to localize a Flex application. This course is a follow-up to Flex 3 Essential Training, and some experience with ActionScript 3, Flex Builder, and the Flex 3 Framework is recommended. Example files accompany the course.
Topics include:
  • Using the Tree and MenuBar controls
  • Integrating with ColdFusion, PHP, and ASP.NET
  • Managing an asynchronous state with AsyncToken
  • Filtering, sorting, and finding data with ArrayCollection
  • Working with Modules

show more

author
David Gassner
subject
Developer, Web, Programming Languages
software
Flex 3
level
Intermediate
duration
8h 8m
released
Aug 15, 2008

Share this course

Ready to join? subscribe


Keep up with news, tips, and latest courses.

submit Course details submit clicked more info

Please wait...

Search the closed captioning text for this course by entering the keyword you’d like to search, or browse the closed captioning text by selecting the chapter name below and choosing the video title you’d like to review.



Introduction
Welcome
00:00Hi, my name is David Gassner and I'd like to welcome you to this video
00:04series, Flex 3 Beyond the Basics. This is a follow up to a previous lynda.com
00:09series, Flex 3 Essential Training, in which I described how to build and deploy
00:13basic Flex 3 applications using Flex Builder 3 and the Flex 3 Framework.
00:19In this video series, I describe advanced Flex development skills, including
00:23visual tricks like using custom pop-up windows and programmatic animations,
00:28parsing of XML with E4X and integration of Flex applications with Cold Fusion,
00:33ASP.NET and PHP.
00:36I hope you enjoy this training and that it helps you build better, more powerful Flex applications.
Collapse this transcript
Prerequisites
00:00In this video, I am going to describe the prerequisites for this title. This is
00:04a follow up title to the existing video series, Flex 3 Essential Training.
00:09If you've already watched that video series and feel comfortable with the skills
00:13that are taught there or if you have equivalent experience developing Flex
00:16applications, you should be ready to jump into this video series.
00:20The Flex 3 Essential Training Video Series contains information about building
00:24basic applications and deploying them Flex Builder 3. It describes how to layout
00:29applications using containers and absolute positioning. How to work with
00:34events. And how to communicate with application servers, using the HTTP Service component.
00:40In both video series, there is an assumption that you are comfortable with the
00:43ActionScript language, but if you need a refresher course, it might be worth
00:48going back to the video series, ActionScript 3.0 in Flex Builder Essential Training.
00:52That video series covers the fundamentals of programing and advanced
00:56object oriented concepts of programing in the context of ActionScript 3.0.
01:01Once you have watched this video series, you might then want to move onto
01:05another video series called AIR for Flex Developers, where you learn how to
01:09take all these skills put together and use them in the context of building
01:13native desktop applications that are deployed using the Adobe Integrated Runtime or AIR.
Collapse this transcript
Using the example files
00:00Just a quick word about the exercise files we will be using. If you are a
00:04premium member of the lynda.com Online Training Library or if you are watching
00:08this tutorial on a disc, you have access to the exercise files used throughout this title.
00:14In the exercise files folder, I have collected some assets for you to use
00:17during our tour of the advanced features of Flex 3. They include applications,
00:22source code, graphics and text files for using the sample applications that we'll be creating.
00:26I had copied the folder to my desktop, but you can put it wherever you want.
00:31If you are a monthly or annual subscriber to lynda.com, you don't have access to
00:36the exercise files but you can easily follow along and use any files you want
00:41as you create your own sample applications. Let's get started.
Collapse this transcript
1. Using Popup Windows
Presenting simple messages with the Alert class
00:00In this chapter of the video series, I am going to describe the use of pop-up
00:04windows as part of Flex applications. A pop-up window is a rectangular region
00:09that floats and can move above the application container. The user can click
00:14and drag a pop-up window around the screen as they want to. You can create
00:18pop-up windows in a couple of ways in the Flex framework. You can use the Alert
00:22class to display a standard window that displays text messages, optional icons
00:27and a small set of buttons, or you can create and display your own custom
00:31pop-up windows using the PopUpManager class and the title window or panel containers.
00:37For all of the demonstrations in this chapter, I will use exercises from the
00:40Exercises folder. If you are following along with the exercises you can import
00:44the project I will be using. From the Flex Builder menu select File, Import,
00:50Flex Project. Click the Browse button next to Archive File, navigate to the
00:56Chapter 01 folder under the Exercises area, and then import the file Chapter01Begin.zip.
01:05Once the project has been imported, open the project and then open its source folder.
01:10Then open the application UsingAlert.mxml. I demonstrated the use of a
01:17simple alert pop-up window, in the Flex 3 Essential Training video series, so
01:22this will be a review.
01:24Go to the Script section and create a new private function named showPopup. The
01:31function will return void. In order to display a pop-up window, with the Alert
01:36class, call a static show method. Start by typing the word Alert with an upper
01:41case A. The Alert class must be imported to use it correctly. So now, press
01:47Ctrl+Space and you'll see a list of all the classes starting with the word
01:51alert and then select the Alert class.
01:54You should see that Flex Builder automatically adds an import statement above
01:58the function. Now type the dot(.) character and you'll see a list of all the
02:01properties and methods of the Alert class and start typing show. This is the
02:07only static method that the Alert class implements. The show method accepts a
02:11number of arguments.
02:13I'll be showing you how to use each of these in the following videos, but for
02:16this simple demonstration, I am only going to use the first two arguments, both
02:20strings. The first string value is displayed in the body of the pop-up window,
02:24that is in the center region and the second string argument is displayed in the
02:28title, that is in the upper left corner. So in the show method I will pass in
02:32these strings.
02:34Flex 3 is awesome and About Flex 3. I'll close the method call, then go down to
02:44the button with the label of Open Alert Popup, add a click event handler and
02:50then call the method, showPopup. Save your changes and run the application.
02:57Once the application opens in the browser, click the button, Open Alert Popup,
03:02and you should see the pop-up window displayed on the screen, centered in the
03:05application. Notice that the pop-up window created by the Alert class is modal.
03:10That is to say, it locks interaction with the rest of the application and
03:15indicates that it can't interact with the application by blurring the
03:18background. For example, if the user tries to click on the button in the main
03:22application window, they won't be able to until the user clears the Alert
03:28pop-up window, then they can go back and click that button again.
03:32Close the Browser and return to the code. One of the interesting aspects of the
03:36Flash Player when you work with Flex application development is that code
03:41blocks once started always execute to their end. Here's what I mean by this. In
03:46many application environment which operate synchronously such as browser based
03:50Javascript, if you use a mechanism such as the JavaScript Alert method to
03:55display a pop-up window, the code execution pauses until the user interacts
03:59with the window. That isn't the case in the Flash Player. The Flash Player has
04:03a single application thread and so if you pause the ActionScript code execution
04:08everything else has to be suspended as well, such as animations and other
04:12interactions with the application.
04:15So, let me demonstrate this by cloning the code for Alert.Show. In Flex Builder
04:20and in all of the clips, you can clone a bit of code by selecting it and then
04:25pressing Ctrl+Alt and the Down cursor key. On the Mac the keyboard shortcut is
04:30Command+Alt and the Down cursor key. So, now I am calling the Alert.Show method
04:35twice. Save and Run the application again and then once the application opens,
04:41click the Open Alert Popup button and at first glance it may look like you've
04:45only executed the code once, but then if you drag the pop up window off in some
04:50direction, you'll see that there are actually two pop-up windows on the screen.
04:54Clear the first one by clicking the OK button, and clear the second one by
04:59clicking its OK button and only then does the application become completely
05:03available and all of the blurriness go away.
05:06So, that's the demonstration of how the Flash Player and the Flex framework
05:11operate in terms of ActionScript code execution. Once you start an ActionScript
05:15code block, you will always complete it even if you pop-up windows that you
05:19think of as modal. A modal window, such as the Alert class's window, blocks the
05:25user interaction, but does not stop ActionScript code from executing in the
05:29background.
05:29Now, in the next set of videos, I'll show you how to make more advanced use of
05:34the Alert class's pop-up window.
Collapse this transcript
Managing Alert popup window buttons
00:00In this video, I am going to describe how to customize the Alert Popup window's
00:04buttons? How to change the label on the button? And how to select additional
00:08buttons that you want to display, and then at a later video I will show you how
00:12to listen for the event that occurs when the user clicks a button, so you can
00:16determine which button was selected.
00:18For all of the demonstrations in this video, I'll use the application
00:22AlertButtons.mxml from the Chapter01Begin folder. If you are following along in
00:27the exercises, open the application now. In this version of the application, I
00:32am once again showing a pop-up window, this time with a question, are you sure
00:36that Flex 3 is awesome? And I am going to show you how to solicit an answer
00:41from the user by displaying a set of buttons.
00:44Each of the four buttons that the Alert Popup window is capable of displaying,
00:48is represented by a static constant value that's a member of the Alert class.
00:53You indicate which buttons you want to display by selecting each constant for
00:57the button you want to show, separating them with the bitwise pipe(|) character
01:01operator and then wrapping the whole thing in parenthesis.
01:04So for instance, if I wanted to show both an OK and a Cancel button, I would
01:09create a pair of parenthesis in the next argument in the show method and then
01:13within that I would add in the following constants. Alert.OK and then a pipe
01:19character and then the constant for the Cancel button Alert.CANCEL. I'll save
01:25the changes and run the application. I'll click the button to open the Alert
01:31Popup and this time I get two buttons, OK and Cancel. I'll cancel the
01:37operation and close the application and then show you that there are two other
01:41constants that you can select for Yes and No.
01:45Once again, the labels for these values are determined by the resource bundles
01:49that control your particular Flex application. So I'll use Alert.yes and then
01:54the pipe character and then Alert.no. Once again, I'll run the application,
02:00click the button to display the pop-up window and now I get buttons for yes and
02:05no.
02:06You can also change the labels that each button displays. The Alert class has
02:11four properties that are used for this purpose named, yesLabel, noLabel,
02:14okLabel and cancelLabel. So for example if I wanted to change the words yes and
02:21no to something else, before I call the show method, I would call this code -
02:26Alert.yesLabel equals For sure! and then I'd set the noLabel property to No
02:37way. I'll run the application now, and then click the button to display the
02:44pop-up and you'll see that the buttons are displayed, but notice that the
02:48labels are truncated. This is because the labels that are a part of the Alert
02:52class's pop-up window, don't automatically resize themselves, based on their
02:56labels the way standard button controls do. So if you're going to change the
03:00label, you also need to take control over the button width.
03:04I'll do that by setting a property of the Alert class named buttonWidth and
03:10I'll be conservative, I'll allow plenty of space by setting this value to a 100
03:15pixels. I'll Save the changes and run the application again. Click the button
03:21to display the pop-up and now I see the buttons. Notice that the buttonWidth
03:25property affects all buttons in the Alert class's pop-up window.
03:30So, that's how you display the buttons. By the way it's worth mentioning that
03:33there is one other flag or value that you can pass into this argument. In
03:38addition to the four button constants, Yes, No, Ok and Cancel, notice that the
03:45Alert. NONMODAL constant is another flag, that is a value that you pass-in in
03:49this third argument separated from the others by the pipe character or the
03:53bitwise operator.
03:55Save the changes and run the application again and click the Applications
04:02button to display the pop-up window. Once again, the pop-up window is
04:05displayed, but notice that the application background is not blurred this time.
04:10This is a visual indicator for the user that shows that they can still interact
04:14with the rest of the application. I'll drag the pop-up dialog box off to the
04:18side and click the application button again and notice now I can create as many
04:24different pop-up windows all with the same labels and so on as the others.
04:29One thing however that you don't have control over with the pop-up window
04:32created by the Alert class is the positioning of the pop-up, and this is where
04:36the custom pop-up window architecture comes into use. I'll be showing how to
04:41use that in later videos. But in this next video I'm going to show you, how to
04:45listen for and handle the event that's dispatched when the user clicks any of
04:50the buttons in the pop-up window created by the Alert class. You'll be able to
04:53listen for the click, figure out which button was selected and then react in
04:58whatever way you need to for your application.
Collapse this transcript
Handling Alert Popup Window events
00:00In this video I am going to describe how to detect the event that's dispatched
00:04when the user clicks the button in the pop-up window generated by the Alert
00:08class. You will be able to listen for the event and then determine which button
00:12was clicked so you can react accordingly.
00:14For this demonstration I will use the application AlertEvents.mxml that you
00:19will find in the Chapter01Begin project. In this version of the application the
00:24Alert class pop-up window asking a simple question, do you want to continue?
00:29You can use this sort of pop-up window to get any sort of confirmation from the
00:33user and the goal is not only to display a set of options Yes or No, OK or
00:38Cancel or any other customized buttons you like but also to react when the user
00:43clicks one of the buttons.
00:45Change the code as follows. First of all place the cursor inside the Script
00:50section after the existing showPopup function and add a new private function.
00:55When the user clicks any of the buttons in the pop-up window generated by the
00:59Alert class, the pop-up window dispatches a Close event. So, we are going to
01:04listen for the Close event and react accordingly. Name the function
01:09closeHandler. As with all event handler functions accept an event object as an
01:14argument and data type this one as the class closeEvent.
01:18Notice that as I have selected the closeEvent class from the list of available
01:22classes that the Import statement for the class was added automatically. Unlike
01:27the event classes that are members of the standard package flash.Events, such
01:32as flash.Events.Event or flash.Events.MouseEvent, the closeEvent class is a
01:38member of package named mx.Events and it must be imported to be used
01:42successfully. As with all good event handler functions return void and then add
01:48a call to the trace function within the closeHandler method and simply output a
01:52string of close event handled. Now, go back to the function showPopup.
01:59We are going to add two more arguments to the show method call. The fourth
02:04argument that you pass into the show method is the parent, this is a reference
02:09to the application window or to any other window on which you want to center
02:13the pop-up window generated by the Alert class because we don't have any other
02:17windows on which to center the pop-up, we will use this, meaning the
02:21application window itself. This is how we are going to listen for the close
02:25event. Pass in a reference to the function you want to call when the Close
02:29event is dispatched, which we named closeHandler.
02:33In a similar fashion when using the Add Event Listener architecture, you pass
02:38in a simple reference to the function you want to call. The Alert class knows
02:42how to call this function already, it will call the function, pass the Close
02:46event object and then you will be able to determine by inspecting the event
02:51object's properties which button was clicked. Save your changes and run the
02:55application in Debug mode, so you will be able to see the trace method.
03:02Click the button to open the pop-up and then click either button in the pop-up
03:06window. Go back to Flex Builder and you should see that the trace method output
03:12the message close event handled. So, if you have been successful so far, now
03:16you are ready to determine which button was clicked. Terminate the debugging
03:20session and then go back to full screen coding. Within the eventHandler
03:25function you determine which button was clicked by inspecting an event object
03:30property named detail. The event.detailProperty will match whichever alert
03:36button was clicked and you will be able to determine this by inspecting the
03:40constant associated with the button. Place the cursor after the call to the
03:44trace method and add an if conditional block that looks like this, If
03:50(event.detail == Alert.YES).
04:01And again this is the constant representing the YES button. Put in the pair of
04:07braces to complete the conditional section and use another call to the Alert
04:11class and this time show a simple string of Let's go!. To give the pop-up
04:17window a complete look, I recommend that you always pass in two strings, the
04:22first string again is in the body of the pop-up window and the second is in the
04:26title. Now, add an else clause. Now if the user clicks the No button or if they
04:35simply press the Escape key the else clause code will execute. I will display a
04:41message of OK I'll stop, and once again the title Event handler.
04:48Save the application code and once again run the application, this time in
04:52standard mode. Click the button to display the alert dialog, try clicking the
04:58Yes button and you should see the reaction Let's go! Clear that message, click
05:04the button again to display the pop-up window and this time click No and you
05:09should see the message OK I'll stop. So, this shows you how to react to the
05:14close event when using the pop-up window generated by the Alert class and you
05:19are using customized buttons. You can detect the clicks on the Yes, No, OK and
05:24Cancel buttons and once again you can customize the labels of these buttons as
05:29you need to, to ask the questions that you want to ask.
Collapse this transcript
Changing the Alert popup window's appearance
00:00In this video I am going to describe a couple of approaches to customizing the
00:04appearance of the pop-up window generated by the Alert class. For these
00:09demonstrations I will use the application AlertAppearance.mxml. If you are
00:14following along with the exercises you can open that file now. In this version
00:19of the application, I am once again using the Alert class to display a pop-up
00:23window. The code starts at the point where the last exercise left off,
00:28displaying a message, do you want to continue? And then reacting to the Close
00:32event of the Alert class by using an event handler function to determine which
00:36button was clicked.
00:38There are two major aspects to controlling the appearance of a pop-up window
00:41generated by the Alert class. The first is the use of a custom icon, a custom
00:46icon is a graphic that you can display in the Alert class pop-up window. For
00:51this purpose I recommend that you use a graphic format that supports
00:55transparency, PNG, GIF files or SWF files will do the trick and for this
01:01application, I am going to use a graphic that's already been created and placed
01:05in the Assets folder of the project, named questionIcon.png, this is a PNG file
01:11that was originally created in Fireworks and it still has its underlying Sprite
01:18architecture.
01:19So, if you have a copy of Fireworks you will be able to open up this graphic
01:23and make any changes to it such as its color, its font face and so on. I will
01:28close Fireworks and return to Flex Builder. The first step in using a custom
01:33icon graphic is to embed the graphic in the application. There are couple of
01:38ways of doing this but the simplest is to do it in the Script section. Place
01:42your cursor inside the Script section and add and Embed metadata tag. Now, if
01:48you haven't used the Embed tag before, it's a metadata tag similar to the
01:52Bindable metadata tag.
01:54So, it uses brackets on the outside and then the word Embed with an uppercase E
02:00and then a source attribute that points to the location of the graphic file
02:04that you want to embed. I will embed the graphic icon using the source property
02:11assets/questionIcon.png. Make sure you spell the name of the file exactly as
02:17it's saved on disk and it is case-sensitive. Now, after the Embed metadata tag,
02:23declare a variable, datatyped as a class. This will be associated with the
02:28graphic and will be used to pass the graphic to the Alert class pop-up window.
02:33You can name the variable anything you want.
02:35For simplicity I will use the same name as the graphic file itself but without
02:39the .png file extension questionIcon, and then data type it as a class. The
02:46next step is to go to the show method call for the Alert class. Go to the
02:51showPopup method, place the cursor after the closeHandler function call, put in
02:57a comma and then pass in the name of your class questionIcon. Notice that
03:03because the class isn't a variable name, you can auto complete it by pressing
03:07Ctrl+Space and then selecting the appropriate class name. Save your changes and
03:12run the application, then click the button to display the pop-up window and you
03:19should see that the graphic icon is correctly displayed and that because it has
03:23transparency, it displays the background color of the pop-up window through the
03:28graphic icon.
03:29Close the application and return to the code. The other method that you use to
03:34determine the appearance of a pop-up window generated by the Alert class is to
03:38change Cascading Style Sheet properties. Add a pair of style tags to the
03:43application after the Script section and before the button. When you create an
03:47Alert pop-up window, it creates a variable that's actually datatyped as the
03:52Alert class and so one aspect of using Cascading Style Sheets to modify the
03:57appearance is to create a type selector using the Alert class name. Within the
04:03Alert class you can then change any of the styles associated with the Alert
04:07class. If you are not sure which styles are available, check the documentation
04:11for the Alert class but for example you could change the background color and
04:17that would change the color of the center area of the pop-up window that is the
04:21area where the main string, the buttons and graphic icon are displayed.
04:26I will change my background color to a value of #EEEEEE which is an off-white
04:33and then I will also change the font color like this. I will put in a color
04:37style declaration and change that value to #000000 which is black. I will save
04:46the changes and run the application. Click the button to show the pop-up and
04:53you will see that the center area of the pop-up window is the off-white color
04:56and the graphic icon's transparency allows it to show through. I will close the
05:00application and add one more wrinkle. The Alert class supports a predefined
05:05style name called windowStyles, which determines what the fonts in the header
05:09look like.
05:10I will add a windowStyles style name selector. Notice that as with all style
05:15names or classes you prefix the name of the style with a period and then I will
05:20add font properties to change the look of the font in the header. I will add a
05:26font style of Italic and a font size of 18 pixels. Remember when setting font
05:33sizes that everything is in terms of pixels, so you don't add a unit of
05:37measurement after the number as you would in HTML. I will run the application
05:42again, click the button and you will see that the font in the header of the
05:49pop-up window uses 18 pixels in Italics. One caution about the windowStyles
05:55style name, this is used not only by the Alert class but also by the Panel
05:59Container and the Title Window Container. You will learn how to use the Title
06:04Window Container in later videos in this chapter when we talk about custom
06:07pop-up windows. This is because the Alert class, the Panel and the Title
06:13Container are all part of one family of container components in the Flex
06:17Framework. So, if you change the windowStyles here, you will be changing them
06:21for the Panel and for the Title window as well. So, those are two major aspects
06:25of modifying the appearance of your pop-up windows generated by the Alert
06:29class, the use of the custom icon graphics and the use of Cascading Style
06:34Sheets.
Collapse this transcript
Creating custom popup windows
00:00In this video I am going to describe how to define a custom pop-up window using
00:05the Panel Container. The Panel Container has a default dialog box style look
00:10and feel and its well suited for use as the base for any pop-up dialogs that
00:15you want to create. A custom pop-up window is a standard MXML component
00:20typically that has as its root element one of the Flex containers. For this
00:25demonstration I am going to be creating a brand new MXML component from scratch
00:30and I will base it on the panel container and then in the next video I will
00:34show you have to instantiate this component using ActionScript code and then
00:38use a class called the PopUpManager to show it on the screen.
00:42Go to the Chapter01Begin project and locate the windows folder under the source
00:46root. Right click on the windows folder or Ctrl+Click on the Mac and select
00:51New, MXML component. In the New MXML Component wizard, set the file name as
00:58LoginWindow, base your new custom component on the Panel container. Remove any
01:07Width or Height settings so that you will allow the window to resize
01:11automatically depending on its child elements and set the Layout property to
01:16Vertical, then click Finish. The Panel container has a couple of good standard
01:21properties that you can use to control the appearance of the custom pop-up.
01:25For example, the title property determines the text that appears in the
01:31top-left corner of the Panel's header. Set the title property of the panel to
01:35Please Login In. Create a Form container within the panel consisting of a set
01:42of form tags and then go to Design View, so that you can use the Components
01:47View to start creating the form. When you go back to Design View, if you don't
01:52see the Components View appear, go to the Window menu and select Components
01:57which you will find at the top of the menu.
01:59Now, drag in a couple of visual controls. Go to the Components View and scroll
02:04down until you see the text input control, then drag it and place it inside the
02:09form. Make sure that the blue selector is inside the form rectangle, it's very
02:14small and sometimes a little hard to see on these videos, but on your own
02:18computer screen you should see that it is accurately showing you that you are
02:22dropping the text input control into the form. Notice that when you drop the
02:26text input control into the form, it wraps the text input inside a form item.
02:33Double click on the form item's label to change its setting and set it to User
02:37Name. Now click on the text input control, make sure that you can see the Flex
02:42Properties View and again if you can't go to the Window menu and select Flex
02:47Properties, which you will find as the second item on the menu.
02:51With the text input control selected set the ID to userinput. Now, drag in
02:58another text input control. Place this new text input control inside the form
03:04but right underneath the existing form item container. You will know when you
03:08are placing in the right place when the blue selector line expands to the width
03:13of the form item container that is inside the form. Once again if you drop it
03:18in the right place you will see a label and the form item container wrapped
03:21around it. Double click on the label and type password and a colon and press
03:27Enter or Return.
03:29Then once again click on the text input control inside the form item, go to the
03:34Flex Properties View and set the ID to passwordinput. Also set the Display as
03:41password value to true, that will mean that when the user types a value and
03:45they will see asterisk instead of the actual string that they type in. Next we
03:49are going to create buttons wrapped in a control bar, just as with Panel
03:53containers that are displayed inline in the application, a Panel container
03:57being used as a pop-up window can wrap all of its button controls inside a
04:02control bar which will appear as the footer of the panel or the pop-up window.
04:07Go back to the Components view and scroll down to the Layout section. Drag in
04:12the control bar and place it under the form container. It will drop into place
04:17at the bottom of the panel. Now add a couple of buttons, go back to the
04:22Components View to the control section and drag in two buttons. Place it inside
04:28the control bar. You will know you are in the right place when the little blue
04:32indicator is in the footer area of the panel. Drop in the first button then
04:38drag in another button then place it next to the first. Set the labels of the
04:42two buttons as follows.
04:44You can double click on each button control to set its label, set the label of
04:48the first button to Log In and then double click on the second button and set
04:54its label to Cancel. You have now created a custom component that's suitable
04:59for use as a custom pop-up window. In the next video I will show you how to
05:04instantiate this component using ActionScript code and then how to use the
05:08PopUpManager class to display the component as a floating pop-up window.
Collapse this transcript
Displaying and centering custom popup windows
00:00In this video I am going to describe how to instantiate a custom pop-up window
00:05and then show it using the PopUpManager class. I will be using the custom
00:09component that I created in the previous exercise. There is also a completed
00:14version of that exercise file in the windows folder of the project named
00:18LoginWindowComplete.mxml. If you are starting on this video, you can use that
00:23file instead and just rename it as LoginWindow.mxml. If you are following along
00:28with the exercises, go to the project and then open the application file
00:32UseCustomPopup.mxml and take a look at the existing code. This application is
00:39going to display a login window upon application started.
00:43So I have created a function named Init with returns void and then called that
00:47function upon the applicationComplete event of the application component. There
00:52is a label component at the bottom of the application that I will use later on
00:56to display the results of the login. The first step to displaying a custom
01:00pop-up window is to instantiate the component you are using. Typically you do
01:05this outside of any functions, so that you can address the window from any
01:09function in the application. Place the cursor in the Script section before the
01:13Init function but inside the CDATA block. Then declare a new private variable
01:18named loginWin and data type it as your custom component LoginWindow.
01:24Notice that when I select the LoginWindow component from the list of available
01:27classes, that an Import statement is created automatically for me. Now go to
01:32the Init method. The next step is to instantiate the window. Upon application
01:38startup, I will create an instance of the LoginWindow component and I will use
01:42the predeclared LoginWin variable. I will use this code loginWin=new
01:50LoginWindow. The next step is to use the PopUpManager and one of its static
01:56methods to display the window. Start by typing PopupMan, then press Ctrl+Space
02:03to see the list of available classes and select PopUpManager from the list.
02:08Notice that Flex Builder automatically adds an Import statement for this class.
02:12Now, type in dot(.) character and you will see a list of all of the static
02:15methods of the class and select the first one addPopUp. The addPopUp method is
02:21used to display an existing window on the screen. We have already instantiated
02:26the window in memory. Now, we are going to say show it to the user. Add the
02:30loginWin variable as the first argument. The next argument is the parent
02:34window, that is the window that will be use to calculate the position of the
02:38pop-up. As I did in the Alert class demonstrations earlier I will type in this.
02:44The next value is a Boolean property named modal, which determines whether this
02:49pop-up window will block access to the rest of the application. As with the
02:53Alert pop-up, you can display custom pop-ups either modally or non-modally. A
02:58modal window blocks access to the rest of the application, while a non-modal
03:02window allows the user to continue interacting with other elements. Because we
03:07want the user to have to login before they continue with the rest of the
03:10application, I will pass in a value of true. That's all I need. I will run the
03:16application and let's take a look at the result. As the application starts up,
03:20the LoginWindow appears in the top left corner.
03:23This is the default position of the LoginWindow, the user can click and drag
03:28the LoginWindow around the screen and when they release the mouse button, its
03:32position will be retained on the screen. Close the application and I will show
03:36you a couple of ideas about how to position the window on screen. One approach
03:41is to use X and Y properties just like you would with components that are
03:45placed in an absolute positioned container. I will set LoginWin.x to a vale of
03:50100 and LoginWin.y to a value of 100. I will save the changes and run the
03:57application again and notice that as the application starts up, the dialog
04:02appears in a specific position relative to the top-left corner of the
04:06application.
04:07Here is another approach though. Rather than using X and Y properties, you
04:12might want to center a custom pop-up window in the direct center of its
04:15containing window, the application. The PopUpManager class has a static method
04:20for this purpose to call this code. PopUpManager.centrePopUp and then pass in
04:27the reference to the pop-up window which I have called loginWin. Run the
04:31application again and this time as the application starts up, you will see the
04:36pop-up window appear in the direct center of the application and after user
04:40resizes the browser, you will notice that the pop-up window doesn't
04:44automatically reset its position. That's because this is not like constrained
04:48properties where the position is being continually recalculated.
04:52The centering of the pop-up window only happens upon the explicit call to the
04:56PopUpManagers centerPopUp method. So, that's a look at how to display a pop-up
05:02window. Now, in the next video I will show you have to remove the pop-up
05:05programmatically using another method of the PopUpManager class.
Collapse this transcript
Removing popup windows
00:00In this video I am going to describe how to create a custom component that
00:04displays a Close icon in the upper right hand corner and how to handle the
00:08event that's dispatch when the user clicks that icon. I will then show you how
00:12to remove the pop-up from the screen in reaction to the event both from within
00:16the component and from the application code. To get started with this
00:20demonstration, if you are following along with the exercises, go to the windows
00:24folder and open the file LoginWindow.mxml that was created previously or if you
00:30don't have that file because you didn't walk through those exercises, you can
00:33actually use the file LoginWindowComplete.mxml and get exactly the same result.
00:39In the LoginWindow.mxml component, I am going to save it as a new component
00:43name, named LoginWindowWithClose.mxml and then I am going to change its root
00:48element from panel to title window. The nature of that title window container
00:54is that it's a subclass of the panel container that adds the ability to display
00:58and then dispatch events for a Close icon. In the LoginWindow.mxml file, change
01:04the root element from Panel to TitleWindow. Be sure to do this in the both the
01:09start and the end tags. Because the custom component is now a TitleWindow
01:14instead of a Panel, you will now have access to a new property called
01:18ShowCloseButton. This property is Boolean, it takes a true or false value and
01:24when set to a value of true, it results in displaying a Close button in the
01:28upper right hand corner of the component.
01:31Now, save these changes under a new name LoginWindowWithClose.mxml. Now, let's
01:38go to an application that was using the original LoginWindow. Open the
01:42application file RemovePopup.mxml from the source root of your project. Notice
01:48that this application is using the component LoginWindowComplete. It isn't
01:53using the LoginWindow component because that wasn't created at the beginning of
01:56these exercises for this chapter. But we are going to change the data type of
02:00the window we are creating from LoginWindowComplete to LoginWindowWithClose,
02:06the component we just created. Make the change in three places, in the Import
02:11statement at line 8, in the variable declaration at line 10 and then in the
02:18Constructor method call at about line 14.
02:20So, we are being consistent in the data typing of the object and in the
02:25constructor method call. Save your change and now run this version of the
02:30application. As the application starts up, it once again displays and centers
02:35the pop-up window. But now you will see the Close icon appear in the upper
02:39right hand corner as a result of setting the showCloseButton property to true.
02:43If you click this button nothing happens, the only result of clicking the Close
02:48icon is to dispatch a Close event and if you wanted to do something, you have
02:53to listen for the event and handle it in some fashion. Here are two possible
02:58approaches. Close the browser that's displaying the application and return to
03:02the component LoginWindowWithClose.mxml. When the component dispatches the
03:07close event you can listen for it and then react by closing or removing the
03:13pop-up window from the screen.
03:15In this version I will add a close event listener as an attribute to the
03:19TitleWindow tag in the component itself. I will put in the close event listener
03:25and then I will call the PopUpManager. Just as in the application, if you want
03:29to call the PopUpManager's methods you have to import it. In this context you
03:34can type in the word Popup, press Ctrl+Space and then select PopUpManager from
03:39the list of available classes. Flex Builder should react by adding the
03:44appropriate Import statement. Now put in the dot and use this method
03:48removePopUp and pass in a reference to the current component instance, this.
03:54Save your changes and then go back to the application and run it. When the
04:01application starts up it once again displays the component and you should now
04:05be able to click that Close icon in the upper right corner and the window
04:09should close leaving a blank application.
04:12Typically however, it's usually not a great idea to have a component close
04:16itself in this fashion. Remember that you added the pop-up window to the
04:20interface from coding the application's scope and that's typically you could
04:24practice to remove the pop-up window from the same scope. So, now let's go back
04:29to the component definition and we are just going to comment out the code in
04:33the Close event. We might need the close event handler later. So I will leave
04:37the attribute in but I will just comment out the code between the quotes using
04:41the double slash. Save the changes there, then go back to RemovePopup.mxml, the
04:48application.
04:49Place the cursor after line 14 where we are instantiating the pop-up window
04:53component and add a new line of code. Now, add an event listener,
04:58LoginWin.addEventListener and you will listen for the event that's represented
05:04by the CloseEvent class's CLOSE method and then call a method called
05:08closeHandler that will need to create. Now, place the cursor after the existing
05:14function and add a new private function named closeHandler. The event object
05:20that's dispatched with the CloseEvent is named closeEvent.
05:24So, setup your CloseEvent handler to listen for that event object. Name the
05:29argument event and data type it as CloseEvent. As with all good event handler
05:36functions, return void and then within the body of the closeHandler method, use
05:41the same code as you did within the component. PopUpManager.removePopUp and
05:49then pass in the reference to the custom component that you already added to
05:53the interface LoginWin. Save your changes and test the application.
06:00When you click the close icon on the dialog box, once again it closes the
06:04dialog. But now, you are controlling its closing or more accurately the
06:09removing of the pop-up window from the user interface from the same scope and
06:14same code location as where you added it. This will make it easier to maintain
06:18this application and make the application a little less brittle. So in this
06:22video, you learned how to use the TitleWindow container, a subclass of the
06:26Panel, you learned how to use its Close button, how to display the Close button
06:31and how to listen for its close event and then how to remove a custom pop-up
06:35window from the user interface by using the PopUpManager's static removePopUp method.
Collapse this transcript
Handling Popup Window events
00:00In this video I am going to describe how the listen for and react to events
00:04that are dispatched from the custom pop-up window. I already showed how to
00:07listen for one event, the Close event that's dispatched from the TitleWindow
00:11container when it's used as a custom pop-up. In this video, we will listen for
00:16custom events that are dispatched from our own ActionScript code. For this
00:21demonstration, I will use a customized version of the LoginWindow component
00:25named LoginWindowWithEvents.mxml. If you are following along with the exercises
00:30you will find this component in the windows folder under the source root of the project.
00:35Open the source and take a look at it. In this version of the component, I am
00:39using the TitleWindow container as the base or the root element and I am once
00:43again using the showCloseButton property to display the Close icon in the upper
00:47right hand corner of the pop-up window. This version of the component though
00:51also declares two events named login and cancel. In this component when the
00:58user clicks the login button, they call a method called loginClickHandler. This
01:02method constructs an instance of a login value object, passes in values from
01:07the form's input controls, wraps the Value Object in a custom event and then dispatches it.
01:13Similarly, when the user clicks the Cancel button this method
01:17cancelClickHandler is executed. And here I am instantiating the standard event
01:21class with an event name of cancel and dispatching that event to indicate that
01:26the user has tried to cancel the login process. Now, let's take a look at the
01:30application. Go back to the Flex Navigator View and go to the source code root
01:36and open this application HandlePopupEvents.mxml. Go down to the Script section
01:41first. Notice that this version of the application uses the new custom version
01:46of the component LoginWindowWithEvents. It's still listening for the close
01:50event that's dispatched when the user clicks the Close icon in the upper right
01:53hand corner of the component and it's calling the closeHandler method, when that happens.
01:59There is also a private function that's been declared in this application named
02:02loginHandler. This custom event handler function accepts an event object typed
02:07as that same login event class that was instantiated and dispatched from the
02:11component. And there was a trace that outputs the user name and password. I am
02:16going to add a little bit of extra code here to separate the values when we
02:20debug. Now, here is how we are going to listen for the cancel and the login
02:24events. Go to the Init method and place the cursor after the existing call to
02:30addEventListener. Add a line of code and now listen for another event of the
02:35LoginWindow component. loginWindow.addEventListener and this time listen for
02:42the cancel event. When the cancel event occurs, call the same eventHandler
02:47function as for the close event, which we named closehandler. Now, because
02:52these are two different kinds of events, the close event dispatches the
02:55closeEvent class and the cancel event dispatches the standard Flash Event
03:00class. Go down to the closeHandler and notice that this version is using the
03:05standard event class as the event object, not the closeEvent and that will make
03:10the closeHandler function compatible with both uses. Also add one more call to
03:15the addEventListener function, this time listen for the login event and in
03:19response call the loginHandler function. And that will result in passing that
03:24event object to this handler, so we can react accordingly.
03:27Save your changes and run the application in Debug mode. As the application
03:34starts up, it shows the login dialog, you might want to position and size your
03:40application browser so that you can see the Flex Builder console in the
03:43background. So we can see the trace output when we try to login. I will click
03:48into the user name and password and type in a user name and the password and
03:53then click the Login button and you should see a trace output in the console in
03:58the background. Showing the user and password information that was typed in.
04:02Now, I will click the Cancel button and you will see that the window disappears
04:07and the application is completely blank. So, that's the behavior so far. I will
04:11modify the code so that the application reacts a little bit more intelligently
04:16to each event. Close the application and check your Console view to make sure
04:20that you have terminated the debugging session. If it is terminated correctly,
04:25you will see that the Terminate button is deemed out. Now, let's go to the
04:28closeHandler. In this application we don't want the user to be able to escape
04:34from the login dialog unless they have filled in correct information. So if
04:38they try to cancel or they click the close button, instead of calling the
04:42removePopUp we are going to display an error message.
04:46Comment out the existing line of code. In Flex Builder 3 you can do this by
04:51placing the cursor anywhere in the line of code and then you can go to the
04:54source menu and select Toggle Comment. You will notice if you look at the menu
05:00that there is also a keyboard shortcut for this. Now replace that comment to
05:04that line of code with this bit of code, loginWin.errorString = You must login
05:11to see the photos. The errorString property is a property of all visual
05:19components in Flex. It results in displaying the red border around the selected
05:24objects that you set the property on and then when the user moves the cursor
05:27over the object such as in this case, the pop-up window, you will see the error
05:32string displayed in a little tooltip on the side. Run the application this time
05:37in Normal mode, try to close the dialog box and you will see the dialog box
05:45turns red because that's the border of the dialog box and because the cursor is
05:49already over the dialog box, you will see the error message appear.
05:54The same thing would happen if you click the Cancel button. I will refresh the
05:58application in the browser so that it appears in its default presentation and
06:02once again you see the error message displayed. So, now we have handled both
06:06the close and the cancel behaviors. Now let's do with the login behavior. Close
06:12the application browser window and go back to the code. Now before we do any
06:16further coding go back to the top of the application and you will notice that
06:21there is a state that's been defined named photos, which displays some photos
06:25on the screen. So, when the Login event happens I am going to authenticate the
06:30user name and password. For this demonstration I will authenticate by comparing
06:34the values of the user name and password to literal values.
06:37In a full production application, you would probably authenticate the values
06:41the users types in against the Database and LDAP server, the contents of the an
06:46XML or some other security model. So, now here is how we will handle the login
06:52process. Place the cursor inside the loginHandler method and then we are going
06:57to compare the values that the user typed in to some literal strings. I will
07:01put in a conditional statement. If event.Login that's the value object
07:07event.Login.username and then I will put in the double equals equality operator
07:12and I will put in the value I am looking for which is correct user, then I will
07:18put in the double ampersand(&&) for the And operator, then I will check the
07:24password as well and I will check that against a value of correct password.
07:34Now I will add the braces. So, if the user has logged in correctly I will
07:38follow the two steps. First of all, I will take the code that I originally used
07:43in the closeHandler method to remove the pop-up, I will copy that to the
07:48clipboard and paste it into my conditional clause, then I will change the
07:54current state of the application to photos and this will allow the user to see
07:59the photos appear if they login correctly. Now I will add an else clause to the
08:04conditional section and once again I will use the errorString property of the
08:08pop-up window loginWin.errorString = Incorrect login information. Notice that I
08:18don't tell them whether the user name or password was correct. I simply tell
08:22them you passed in incorrect info.
08:24So, now I will run the application one more time. I will click into the User
08:33Name text input and type in a value that's not correct and I also type in an
08:39incorrect password and I will try to click Login and I will see the message
08:44Incorrect login information. This time I will type the correct information in,
08:50correct user and correct password, I will login and there is my application
08:57authenticated and ready to use.
09:00So, this is how you listen for the events that out of a custom pop-up window.
09:05The component itself can declare and dispatch any custom events you want, you
09:10can use a Value Object to wrap the data from the component if you are sharing
09:13data with the rest of the application and then in the application you listen
09:18for the events with the addEventListener function passing in the name of the
09:23event you want to listen for and then indicating which event handler function
09:27you want to use in declarator application.
Collapse this transcript
2. Animating with Visual Effects
Using simple effects and triggers
00:00In this chapter of the video series, I am going to describe the use of effects.
00:05An effect in the Flex Framework is a programmatic animation. Unlike Flash, Flex
00:11and Flex Builder don't have a timeline. So, when you want to cause animation to
00:15happen you program them in ActionScript and an effect is a preprogrammed
00:19animation. There are a number of different animations or effects that are
00:23already a part of the Flex Framework and you can play them in a number of
00:26different ways. In this video I am going to describe the use of effects in
00:30association with Triggers. A trigger is kind of like an event but instead of
00:36executing ActionScript code as you would with an event listener, you play an
00:41effect with the trigger. For all of the demonstrations in this chapter, I will
00:45use a project from the exercises folder.
00:47If you are following along with the exercises you can import the project into
00:51Flex Builder. Select File, Import, Flex Project, click the Browse button next
00:59to Archive file, navigate to the Chapter02 folder under Exercises and select
01:04the project Chapter02BeginProject.zip. Complete the import process, then go to
01:12the Flex Navigator view and open the project and then open the project source
01:16folder. Then open the application file SimpleEffect.mxml. Let's take a look at
01:23the code first for this application. The application has a Panel container
01:28which in turn contains an image. The image displays a particular JPG file
01:33that's in the Assets folder of the project.
01:36Within the control bar, there are two buttons labeled Show and Hide. The Show
01:41button executes a bit of ActionScript that sets the visible property of the
01:44image to true and the Hide button sets the visible property to false. I will
01:50run the application so we can see its initial behavior. The image is displayed
01:55within the panel. The black border around the image is being caused by the
01:59background color style of the panel. When I click the Hide button, the
02:04background color of the panel shows through as black and when I click the Show
02:08button, the visible property of the image is set to true and therefore it
02:11becomes visible again.
02:13Notice that in the application's initial state, the image visibility is abrupt,
02:18it becomes visible or invisible instantly. Using an effect, a programmatic
02:22animation, you can animate and slow down the shift from something being visible
02:27to invisible. Let's go back to the code. One way of playing an effect is to
02:33create a trigger. A trigger, as I mentioned is kind of like an event listener
02:38except it plays an effect. It runs an animation. For this image control I am
02:43going to use two triggers named showEffect and hideEffect and in fact if you
02:48look in the documentation for any particular visual component, you will find
02:52the list of triggers in the documentation.
02:55Here is the first example. I will add a showEffect trigger and associate it
03:00with the Fade class. A Fade class causes an object's Alpha setting to go from 0
03:06to 1, that is from fully transparent to fully opaque or from 1 to 0, from fully
03:12opaque to fully transparent. When you pass in the name of an effect class in
03:16this fashion, you are telling the control to use the effect class with all of
03:21its default properties and the Fade class will automatically set what we call
03:25its alpha to and alpha from properties based on whether you are making the
03:29object appear or disappear.
03:31I will also add a hideEffect trigger and set it to the same effect class Fade.
03:37I will save the changes and run the application and now, I will click the Hide
03:42button to make the object go away and you will see that it fades out of view
03:47and then I click the Show button and it will fade back into view. Going back to
03:53the code I will show you another effect. This one is called the Iris, the
03:59purpose of the Iris effect is to mask the object or unmask it, starting from
04:04the center or from the outside. Take a look at the result. I will run the
04:09application and once again hide and show the graphic. When I hide it, it
04:14collapses inward and when I show it, it unmasks from the center outward.
04:19There are any number of effects that you can use but again when you pass in the
04:23name of the Effect class in this fashion, you are accepting the default
04:27properties of the effect. Its also possible to create your own custom effect by
04:33instantiating the effect class using either MXML or ActionScript and then
04:37setting its properties. Let's try that. I will place the cursor above the Panel
04:42container and then I will create an Iris using MXML markup and I will give the
04:48Iris object an id of myIris. This time I will set a duration, the duration
04:55property for all effects is the amount of time you want to take to play the
04:58effect. I will set it to a value of 2000, which means 2 seconds because in the
05:04Flex Framework, the duration is set in terms of milliseconds, that's 2000
05:09thousands of a second.
05:10I will complete the MXML tag and then I will go down to the image control and
05:15change both the showEffect and the hideEffect triggers. When you refer to an
05:20instance of an effect class, you refer to it using a binding expression. So I
05:25will put in pair of braces and then within the braces refer to the id of the
05:30Iris object, myIris and I will do the same thing with the hideEffect as well. I
05:35will save the changes and run the application and then once again I will hide
05:44and show the graphic and you will see that now the effect runs much more
05:48slowly. It takes a full 2 seconds to either hide or show. There is one more
05:53application in the project that's worth looking at this point. Open the
05:57application EffectSelector.mxml, in this application I have created instance of
06:02some of the most commonly used effects that are associated with hiding and
06:06showing an object. The Fade, the Dissolve, the Iris, the Zoom and then for
06:10wiping effects WipeRight, WipeLeft, WipeUp and WipeDown. Each has an id and
06:17then towards the bottom of the application, there is a set of radio button
06:21controls, each of which is associated with one of the effect objects.
06:25Finally, in the image control which in this application is at the bottom below
06:29the panel, both the showEffect and the hideEffect triggers are associated with
06:33the effects selected through the radio button group through the binding
06:37expression effectGroup.selectedValue. I will run the application and
06:42demonstrate its behavior. This application allows you to test various effects
06:50and see what they will do. With the Fade selected I will hide and show and you
06:56will see it once again fade in and out. Now, I will try the Iris again and hide
07:02and show. And now I will show you some of the wiping effects. This is a
07:07WipeLeft, it's a masking effect which means it shows or hides the object rather
07:13then changing its dimensions, position or other visual aspects.
07:18Here is the WipeDown effect, I will select it and then click Show and Hide.
07:24Now, the Dissolve effect. The difference between the Fade and the Dissolve is
07:28that you associate a color with the Dissolve and when you select the effect it
07:33creates that color as a background and then allows the Alpha of the object to
07:38either go from 0 to 1 or from 1 to 0, using the background as the transition
07:43color. It will do this in both directions and in this particular version of the
07:48Dissolve I am using the color of black. Finally, the zoom effect, the zoom
07:53effect changes the size of an object from the inside out or from the outside
07:58in. With the zoom effect you will sometimes see a little bit of a flash, every
08:02time you show or hide the object.
08:04For instance, when you show the object, every once in a while you will see the
08:07object appear quickly than disappear and then show again. There are some things
08:12you can do to solve that, but if you don't like the use of the zoom effect, you
08:16can instead use the Iris which is similar in its visual feeling but doesn't
08:20have that flickering side effect. So, this has been a look at how to use basic
08:25effects. In the next video I will show you how to apply more customized
08:29properties to a particular effect called the Move effect that allows you to
08:34animate the movement of an object on the screen.
Collapse this transcript
Customizing animation with effect properties
00:00In this video I am going to describe how to set and use properties of effect
00:04objects. As I showed in a previous video, you can create your own effect
00:08objects by instantiating them using either MXML or ActionScript and then you
00:13can set the specific properties of each effect class to modify its behavior.
00:18For this demonstration I will use an application from the Chapter02Begin
00:22project named EffectPropertes.mxml. If you are following along with the
00:27exercises, open that file now. Then, go take a look at it in Source view.
00:33In this application I am once again displaying an image with its source set to
00:37the buckinghampalacesmall.jpg file. This image is placed into an application
00:41with its layout set to absolute and the X and Y properties of 200 -- placed the
00:46image 200 pixels from the left and top of the application. There are already
00:51hideEffect and showEffect triggers that are bound to instances of the Fade
00:55class and then as before two buttons that set the visible properties of the
00:59image to either true or false. In the current version of the application when I
01:04either hide or show the image, I am using the Fade class to do so.
01:09So, lets now go back to the code. As I described earlier, you can set specific
01:16properties of each object, every effect class supports the duration property
01:21which is set in terms of milliseconds. So, if I set the duration of both Fade
01:25classes to 1000 that means that each fade will take one second. I will run the
01:32application again, once again show and hide the image and now it takes one full
01:37second to either appear or disappear. Each Fade class has its own unique set of
01:42properties that allow you to determine how its going to do what it does.
01:46You can take a look at the documentation for any class by placing the cursor in
01:50the tag name and then pressing F1 in Windows. I will press the F1 key and
01:55restore the editor so I can see the Help view and then in the relevant API
02:00section of the Related Topics, I will click the Fade class, that will open up
02:05the help system for the fade class. I will expand the Help editor by
02:09double-clicking on the tab and then take a look at the properties listing.
02:14Notice that the first two properties listed under the Fade class or alphaFrom
02:18and alphaTo. These are properties that are particularly relevant to this
02:22particular class. The Alpha property for any component when set to a value of
02:26zero means it fully transparent and when set to one means fully opaque.
02:31So, the Fade class is used to go from an alpha of zero to an alpha of one over
02:36some amount of time. Let's take a look at another useful effect called the Move
02:42effect, I am going to change both of my effects from Fade to Move. I will
02:48restore the source code editor then press F1 while the cursor is in the Help
02:52tag, click on the link for the appropriate tag Move and then double click the
02:57Help tab to expand the help to full screen. Now I will click on the properties
03:02link within the documentation and then hide the inherited properties because I
03:07am really only interested and looking at the properties that are specific to
03:10this class.
03:12The purpose of the Move effect is to move an object around the screen. There
03:17are properties named xBy, xFrom and xTo and yBy, yFrom and yTo. The From and To
03:24properties are absolute positions. For example, if you wanted to move an object
03:29from one specific position to another you would set either the x or the y
03:33versions depending on whether you want it to move horizontally or vertically.
03:37The By properties xBy and yBy indicate how many pixels you want to move in each
03:43direction. For a positive number for xBy property means move to the right and a
03:48negative means move to the left and for the yBy, a positive number means move
03:52down and negative means move up.
03:54I am going to use the From and To properties for both x and y, to move my image
04:00across the screen to make it appear and disappear. I will close the Help view
04:05and then go back to the source code. For the Move effect that I am using for
04:08showing the object I will set these properties. A negative value for the xFrom
04:13property means that the object will start off the screen to the left and then I
04:18will add an xTo property and I will set it to the final position of the image
04:22object to 100 pixels from the left side of the application. Now I will do the
04:27same thing for the Move effect being used to hide the object but I will reverse
04:31the values.
04:33The xFrom will be a positive 200 and the xTo will be a negative 200. Because I
04:38am not moving the object vertically at all, it will retain its predeclared y
04:43position of 200 pixels. I will save the changes and run the application. Now I
04:50will click the hide button to set the visible property to false and the effect
04:54will be to move the object off the screen. Now I will show the image and once
04:59again the Move effect causes it to slide on to the screen from the left. This
05:03is a bit of a trial and error process. For example, you may notice that the
05:06image slides off to a certain point and then disappears and then when it's
05:11being shown its appearing and then sliding in, that's because the negative
05:16number that I am using as the starting and ending point for either effect is
05:20not large enough. I need to make it wide enough for the whole image to slide
05:24completely off the screen. So I will close the application and return to the
05:27source code and I will change the negative number from -200 to -300 for both
05:34the myShowEffect and myHideEffect. I will save the changes and run the
05:37application again. Once again I will hide the image and this time it slides
05:44completely off the screen and I will show the image and it starts off
05:49completely off the screen and slides back into position. Now, in the next video
05:53I will show you how to use the same Move effects but with easing functions that
05:57cause an object to change it's pace of movement or to come into a final
06:01position and bounce into place.
Collapse this transcript
Using easing functions
00:00In this video I am going to describe the use of Easing functions. An Easing
00:04function is a mathematical equation that describes, in mathematical terms, how
00:09an animation degrades or changes over time. By default when you play an effect
00:15its behavior is linear. That is if for instance you are moving an object, the
00:20amount of movement over a half a second at the beginning of the effect is the
00:24same as at the end of the effect. With an Easing function you can have movement
00:28that increases or degrades over time or for another example have movement that
00:32bounces into place.
00:34For this demonstration, I will use an application named EasingFuctions.mxml.
00:40This is the same application that I finished in the previous video. It uses two
00:45Move effects, one to show and one to hide the object and right now the movement
00:49for either action is linear. When I click the hide button, the object slides
00:54off the screen and when I click the show button its slides back into place.
00:59Easing functions are built into the Flex class library, each set of functions
01:04is a member of a class which in turn is a member of a package called
01:07mx.effects.easing.
01:09I am going to show you the behavior of two of these classes. The first named
01:13Exponential causes movement to degrade or increase over time and the other that
01:19I am going to demonstrate called Bounce causes the Bounce effect that I talked
01:22about. There are many other classes that encapsulate various mathematical
01:26approaches to animation. You can investigate the documentation for each. Each
01:31of these classes typically has three functions that you can select from,
01:34easeIn, easeOut and easeInOut. The easeIn typically starts the motion slowly
01:41and then accelerates and the easeOut goes in the other direction, it starts
01:44fast and then decelerates over time. Here is how we use them.
01:48I will go back to the source code and place the cursor above the move effects.
01:54In order to most conveniently refer to the easing functions, I am going to
01:58import the classes I want to use. I will create a Script section and then
02:03import mx.effect.easing and for the first example I am going to use the
02:10Exponential class. Now in order to pass an easing function to one of the
02:14effects, you use the easingFunction property of the effect object and you refer
02:19to the function by its class and the function's name. For the showEffect I will
02:24use Exponential.easeOut. When you type in the names of the classes and
02:30functions here you won't get code help like you might be use to.
02:33Instead you just have to make sure you spell the name of the class and the name
02:36of the function correctly and they are of course case-sensitive. I will do the
02:41same thing for the hideEffect. I will set the easingFunction this time to
02:45Exponential.easeIn. So, now I will save the changes and look at the behavior. I
02:50will run the application, click the Hide button and now instead of moving off
02:58in a linear fashion it starts off slowly and then accelerates as it goes.
03:03Moving onto the screen the behavior is the opposite, it comes in fast and then
03:08parks itself slowing into place.
03:11Once again here is the Hide and here is the Show. So that's the Exponential
03:16class. Let's take a look at another one. Another class that can be useful is
03:21called the Bounce class. I am going to change the import statement so that
03:26instead of referring to the Exponential class I will refer to the Bounce class
03:30and then I will make the same change to each of the easingFunction calls. For
03:34each effect I will refer to the same function name but I will call it from the
03:38Bounce class. I will save the changes and run the application. I will hide the
03:45image and watch what happens, notice it starts by bouncing slowly and then
03:49takes off in the left direction and now the more dramatic and interesting
03:53effect is when you show it, where it will just slide into place and then will
03:58look like it bounced against a barrier and then finally settles.
04:02Seeing the effect again, it starts off shaking and then moving and then sliding
04:07into place and bouncing. Again there are many other Easing function classes
04:12that you can investigate and it's also possible to call these easing functions
04:16and customize their behavior by passing in numeric values to each of their
04:20properties. Take a look at the documentation and some of the sample code that's
04:25included in the Flex Framework for some great examples of using Easing functions on effects.
Collapse this transcript
Using Sequence and parallel effects
00:00In this video I am going to describe the use of Compound effects. A Compound
00:04effect is a wrapper effect that wraps around the individual nested effects and
00:09causes each of these nested effects to execute either simultaneously or
00:13consecutively. For this demonstration I will use an application named
00:17CompoundEffects.mxml. If you are following along with the exercises you can
00:21open this application from the Chapter02Begin project. This is the same
00:26application I worked on in a previous video. It uses two Move effects to cause
00:31an image to slide on and off the stage. When I click the Hide button it slides
00:36off and when I click the Show button it slides on.
00:40Notice in this version of the application I am not using any Easing functions.
00:44There are two types of Compound effects known as Parallel and Sequence. A
00:49Parallel effect plays two or more effects simultaneously, while a Sequence
00:53effect plays two or more effects one after the other or consecutively. I will
00:58first demonstrate a sequence effect. I will create a new tag set named
01:03mx:Sequence. Now I am going to take the move with an id of myShowEffect and
01:09move it into the sequence. I will select the Move tag, release the mouse button
01:14and then drag and drop the code into the Sequence tag set.
01:18Now, I am going to take the id property that has a value of myShowEffect and
01:23drag and drop that into the Sequence tag. Now, whenever I make the image
01:27appear, I will be running the whole sequence of effects rather then the Move
01:31effect by itself. I am going to change the effect so that it consist of two
01:36separate moves. The first move will be a slide onto the screen as before but
01:41this time it will slide across the screen at the top. So, I am going to set two
01:45new properties, I will set a yFrom of zero and a yTo of zero. By setting the y
01:53position both at the beginning and the ending of the effect to zero that means
01:57the component will stay at the top of the screen for the whole move.
02:01Now I will add a second Move effect after the first. This one will also have a
02:06duration of 1000 or one second and this effect will cause the image to drop
02:12down from the top of the screen into its final position. I will use a yFrom
02:16value of zero and a yTo value of 200, which matches its y setting in the
02:23original image declaration. I will be sure to close the tag with the /> and now
02:29I will run the application to see the result. When I hide the image it still
02:35slides directly off to the left. But now watch what happens when I show the
02:40image. It slides across and then drops down. Let's the effect again, the hide
02:47is the single move, the show is a sequence of two moves. When you use a
02:52Sequence effect, you can add pauses between the internal effects using a
02:57special kind of effect called Pause. The only really useful property of the
03:01Pause effect is its duration. I will add a little bit of space between the move
03:05effect declarations then I will add a tag mx:Pause and set a duration once
03:12again of 1000 for a one second. I will save the changes and run the
03:17application. I will hide the image and then I show the image.
03:27Once again hiding, and notice that when I show the image, the image slides in
03:32the place, pauses a second and then drops down. So, that's how we use Sequence
03:37effects. Like a Sequence effect, a Parallel is a wrapper around two or more
03:41effects but a Parallel place its nested effects simultaneously. You can nest
03:46effects in any order that you want. I am going to add a Parallel wrapper around
03:51the original move. I will create an mx:Parallel tag set. Now I will take the
03:57Move effect and drag it up into the Parallel, correct all of my tabulation and
04:03indentation and now within the Parallel I am going to add one more effect named
04:08Rotate.
04:09The default behavior of the rotate effect is to cause the object to rotate one
04:13revolution clockwise, from an angle of 0 to an angle of 360. If you set the
04:19angleFrom and angleTo properties and you reverse them, saying angleFrom of 360
04:24and an angleTo of 0, that would cause the rotation to go counterclockwise. But
04:29I want the default behavior, I will also add a duration of 1000 to match the
04:34Move effect. So, both of the effects are playing over the duration of one
04:37second. Let's see the result. I will save and run the application. Once again
04:44when I hide the image it just slides off to the left. But now when I show the
04:49image, it appears to roll on and then drop down. The appearance of rolling is a
04:55combination of the Move and the Rotate played simultaneously.
05:00So, that's a look at using Compound effects, Sequence effects to play two or
05:04more effects consecutively and Parallel effects to play two or more effects simultaneously.
Collapse this transcript
Declaring effects inside components
00:00In this video I am going to describe how to declare effect within custom
00:04components. As with any effect you can declare these effects either using MXML
00:08or ActionScript code. As in previous videos I will be using the MXML approach
00:14but this time instead of defining an effect in an application that affects a
00:17component instance, I will define the effect inside the component and then call
00:21it from the application. I will be using the same set of tools but the overall
00:26application architecture will be a bit different.
00:28For this demonstration I will be using an application named
00:31UseComponentEffect.mxml. If you worked through the previous chapter about using
00:36custom pop-up windows, this application will look familiar. When the
00:41application starts up, it prompts the user for a user name and password. If a
00:46user types in the correct user name and password, they will see a photo gallery
00:49but if we type in an incorrect user name and password currently this components
00:53simply turns red and displays an error message.
00:55I am going to add a visual effect to this component to make it shake back and
01:00forth if the user types an incorrect information. This will mimic the user
01:04interface of Mac OS 10. When you enter the user name and password information
01:08to authenticate yourself on that Operating System the dialog box basically
01:12shakes its head back and forth to indicate that the information was wrong. We
01:16will do the same here. I will close the application and open the component
01:22LoginWindow.mxml from the windows folder. This again is the same code that I
01:27used in a previous chapter. It defines and dispatches custom events to share
01:32information about the user's action and the data that the user has entered with
01:36the rest of the application.
01:38I will start by declaring a Sequence event. You can place this anywhere within
01:42the component code. I am going to place it after the Script section but before
01:47the form. I will create a Sequence and I will give it an id of shakeEffect. Now
01:54within the sequence I am going to do a series of moves. The first move we will
02:00use an xBy value of 5 pixels. That means the entire window will move 5 pixels
02:05to the right and I will set a duration of 15 milliseconds. Now, I am going to
02:11clone that line of code by pressing Ctrl+Alt and the Down arrow. If you are on
02:15the Mac that would be Command+Alt and the Down arrow.
02:20In the next move I will go -10, meaning go 10 pixels to the left. I will add
02:28another move effect and that will be a 10, meaning go 10 pixels to the right.
02:34Now I will select these two move effects and clone those and finally put in one
02:39more move effect with an xBy value of -5.
02:42So, now I have defined a sequence of moves where I simply shake the object back
02:46and forth by a few pixels and each move is happening in 20th of a second or 50
02:52milliseconds. So, the entire fact just takes a fraction of a second. Now, I am
02:58going to set a property of the sequence called the target. The target property
03:02indicates what object is going to be affected when this sequence is played and
03:07I will use a binding expression wrapped around the value this, meaning that I
03:11am going to animate the current instance of the current component. So, that's
03:16the definition of the component effect.
03:18Now, I am going to create a public interface that allows the application to
03:22make this effect happen. I will go up to the Script section and add a new
03:27public function. The name of the function is simply going to be shake. It will
03:34receive no arguments and it will return void and it is going to call the
03:38following code, shakeEffect.play. Notice the play method excepts a number of
03:44optional arguments. Because I already defined the target of the effect this,
03:50that is the current instance of the current component, I don't need to pass any
03:54of these values in. I will simply call the play method with no arguments. So,
03:59that completes the definition of the effect and creates the public interface to
04:03call it from the application.
04:05Save those changes and now go to the application UseComponentEffect.mxml.
04:12Locate the loginHandler method inside the Script section. This is the code that
04:16checks the users information and compare it to certain values. We are looking
04:21for values of correctUser and correctPassword. If the user doesn't pass in
04:26those values currently, we are just displaying an error string which is turning
04:30the object red and displaying the pop-up error message. Go to the else clause
04:34of this conditional statement and add the following code, loginWin.shake. So,
04:42now we are going to display the error string but we are also going to tell the
04:45window to shake itself.
04:47Save the changes and run the application. Click the Login button without
04:55entering any password information and you should see the pop-up window shake
04:59back and forth very quickly at the same time it turns red and displays the
05:03pop-up error. Try it again, click Login and once again you will see that the
05:09dialog box shakes every time you click. Now, type in the correct password which
05:14is the word correctPassword with an upper case P, click the Login button and
05:21this time you see the gallery of photos.
05:23So, that's how we encapsulate effects within custom components. The declaration
05:28of the effect is exactly the same as when declaring it in the larger
05:31application. In this case however, I used the target property to refer to the
05:36object I wanted to animate that was the current instance of the current
05:39component, created a public method that would allow the application to make the
05:43effect happen and then called that method from the application.
Collapse this transcript
Using effects with view states as transitions
00:00In this video I am going to describe how to use Transitions. A Transition is an
00:05effect that's applied during a move from one view state to another. You declare
00:10transitions using MXML and then they cause effects to be played when you move
00:14from one state to another. For this demonstration I will use an application
00:19named UseTransition.mxml. If you are following along with the exercises, you
00:23can open this application file from the project. In the application source,
00:28there is a view state named Detail. When you first run the application you will
00:33see four images displayed in a grid. When you move the mouse over any of the
00:37images and then press the mouse button, you will see the image appear as part
00:41of the new view state and when you release the mouse button you go back to the
00:46base state that displays just the small versions of the images.
00:49Notice that the change to the detail state and the reverse and back to the base
00:53state are abrupt, that is the larger picture appears quickly and then
00:57disappears quickly. I am going to add Transition declarations to this
01:01application, so that whenever the image appears it's animated both zooming and
01:06moving into place and when it disappears, it goes away through a fading effect.
01:12Go back to the source code and add some code below the states property in the
01:16application. You always declare each transition within a transitions tag set.
01:23This architecture is very similar to that of the states. you start of with a
01:27set of mx:transitions tags and then for each transition that you want to
01:31declare, you create a transition tag set.
01:35The transition tag has two required properties called fromState and toState.
01:40Each of these properties can either name a specific state, for instance you
01:44could put in the two state value of detail and then this transition would be
01:48defined only when you are moving to that particular state or you can use an
01:52asterisk as a wild card to indicate that either for the toState or the
01:56fromState, you can use it for any state transition. I am going to add a
02:00fromState property of an asterisk meaning going from anything and a toState
02:06property of detail and this matches the state name of detail that's already
02:10been declared. Now, within the transition we declare an effect. In this case I
02:15am going to declare a parallel effect that looks like this.
02:18I will create the parallel and then I will set a target. This is the same
02:23target property I used in a previous video to indicate which object I am
02:27animating and I am going to use a binding expression and refer to an object
02:31that has an id of detailImage. The detailImage object is the larger version of
02:36the image that's being added when you move to the detail view state. Now,
02:40within the parallel we are going to do two effects simultaneously, a Move and a
02:46Zoom. First create the Move effect. Give it an id of customMove. By adding an
02:52id to an effect, we will be able to modify it on the fly later on.
02:57Set the xFrom property at 0 meaning you are going to start from the left side
03:01of the screen. Also set the yFrom value to 0 and then set the xTo and yTo
03:08values to the same positions of as the actual image decoration. The xTo will be
03:14300 and the yTo will be 50. Now add a Zoom effect. The purpose of a Zoom effect
03:22is to start an object off, it's very small and then expand it into place. You
03:27declare the Zoom effect once again with and MXML tag mx:Zoom and now I will set
03:32some specific properties. I will set the zoomHeightFrom value to 0 and the
03:38zoomWidthFrom to 0 and these will be the starting size of the object, and then
03:43I will set the zoomHeightTo and zoomWidthTo to values of 1, which means full
03:48size.
03:49You don't put in the actual pixel values here. Zero means nothing and 1 means
03:55the complete size of the object whatever it might be. Once again, I will set
04:01zoomHeightTo and zoomWidthTo to full size, meaning 1. Lets just use that
04:06transition initially. Save the changes and run the application, try clicking on
04:13any graphic and you will see that now the image flies in from the top left
04:17corner of the application and zooms to full size at the same time. You can do
04:22this for any of the images and if you look at the code in the application you
04:27will see that upon the mouse down event on the image control we are capturing
04:31whichever image is clicked on and supplying that information to the detailImage
04:35component.
04:38Now let's add another transition and this will be the transition that happens
04:42when the image goes away. Place the cursor after the first transition but still
04:47within the mx:transitions tags. Create another transition tag set and this time
04:53set the fromState value to detail meaning we are going away from that state and
04:58the toState to once again an asterisk. This transition is going to be a
05:03sequence, where we fade the object out and then remove the object from the
05:07screen. This is how we are going to choreograph the order of effects. If you
05:12don't do this in the right order you will see that object start to flicker and
05:16then fade out. So, add a pair of mx:Sequence tags, once again use the target
05:23property to indicate what object you are animating detailImage.
05:28Now within the sequence, add a fade effect and set the alphaFrom to 1 and the
05:35alphaTo to 0, meaning that you are going from fully opaque to fully
05:39transparent. Now, add a tag called RemoveChildAction. This means that you are
05:44going to wait until after the fade has been accomplished before you actually
05:48remove the object from the display list of the container, the application. Then
05:54finally add one more fade. The purpose of this fade effect is to reset the
05:59alpha value or the transparency value of the object to fully opaque. So, next
06:05time you try to use the effects everything will still work. Save your changes
06:10and try running the application again. Once again I will click on any of the
06:14images and it will fly in from the top-left of the application and then I
06:19release the mouse and notice that it now fades out of view. And this again will
06:23work no matter which image you click on.
06:26Click to make to fly in, release the mouse button to make it fade away. Let's
06:31make one more customization. Notice that in the transition that's being used as
06:37I go into the View state I am using a parallel effect wrapped around a move and
06:41a zoom and the move has an id of customMove. I am going to use that id and
06:48change the value of the xFrom and yFrom so that instead of having the object
06:52fly in from the top left of the application, I am going to have it fly from the
06:56position of the mouse click and here is how we will accomplish that.
07:00Scroll down to the Script section of the application. Notice that there is a
07:04method there named showDetail. The showDetail method is an eventHandler
07:09function, it's receiving an event typed as mouseEvent and you will be able to
07:13capture information about the location of the mouse at the movement that the
07:17mouse was clicked. Place the cursor inside the function above the existing code
07:22and we are going to change the xFrom and yFrom properties of the move object
07:27and set them to the values of stageX and stageY properties of the event object
07:32like this, customMove.xFrom = event.stageX. So, that means we are setting the
07:44xFrom property that is the horizontal starting position of the move object
07:49based on the horizontal position of the mouse. Do the same thing for the Y
07:53dimension, customMove.yFrom = event.stageY.
08:01Save your changes and run the application. Click on any of the images and this
08:08time you will see that the image flies in from wherever you click. Instead of
08:12always flying in from the top-left corner of the application we are now
08:16capturing the position of the mouse click and customizing the behavior so that
08:21it looks like we are paying attention to what the user is doing. Transitions
08:25can be applied to many different kinds of movements, from one view state to another.
08:30Each transition takes an effect which is very commonly a combo effect such as a
08:35parallel or sequence but really can be any effect you like. The purpose of the
08:40transitions is to allow you to choreograph and slow down the movement from one
08:44state to another and make it easier for the user's eye to track what's going on the screen.
Collapse this transcript
3. Using Graphical Skins with Flash and Flex
Using the default Flash graphical skins library
00:00In this chapter of the video series, I am going to describe the use of
00:03graphical skins, to customize the look and feel of your Flex applications. A
00:08graphical skin is a graphic built in either Bitmap or Vector format. The
00:13purpose of the skin is to change the look and feel of a Flex component at
00:17runtime. The Flex framework comes with the set of pre-built graphical skins
00:22that are delivered in flash format. You can find a source FLA file and open it
00:27in Flash CS3 if you have the product available. I am going to navigate to the
00:32Flex Builder 3 installation folder. On windows the default location of this
00:36folder is under program files, Adobe Flex Builder 3. If you are working on the
00:41Mac, you will find the same folder under applications/FlexBulider3.
00:46In order to find the FLA file that contains the default skins, navigate to the
00:51sdks folder, under the Flex Builder installation folder. From there go to sdk
00:573.0, from there to frameworks, to themes and in this folder you will find a set
01:06of themes which are combinations of skins plus cascading style sheet files. The
01:11first one listed alphabetically is called AeonGraphical. This is the set of
01:15graphical skins and styles that constitute the default look of a Flex 3
01:19Application. Navigate into that folder and you'll find two files with CSS and SWF extensions.
01:27The SWF file, is a compiled flash file that contains the graphical skins for
01:32default Flex applications and the CSS file is the cascading style sheet file,
01:37that binds the graphics into the applications. In order to customize the
01:41graphics for your own application, you can use the source file located in the
01:46SRC sub folder under AeonGraphical. This is a flash file that you can open up
01:51in Flash CS3 Professional or Flash 8. I am going to open the flash file and
01:56let's take a look at it. The flash file consists of a stage, which contains
02:03instances of all the different graphics for each component in the Flex
02:07framework. As an example, the Check Box component involves eight different
02:11icons. The icon for the Check Box component for example has eight different
02:16visual presentations.
02:18There is a selected icon when it's disabled. There is a selected icon for when
02:23the mouse button is down, over and up and then four different icons for each of
02:28the states when the check box is unselected. Each of these graphical icons is
02:33built as a symbol in the Flash document library. I'll go over to the Library
02:38panel and go to the check boxes section and here you will find the same eight
02:42icons. They are labeled check box disabled icon, check box down icon and so on.
02:48So you can easily identify which icon is used for which visual state. If you
02:53want to customize the look and feel of your application, one good approach is
02:58to use Flash to built Vector graphics.
03:01The nature of Vector graphics in contrast to Bitmap graphics is that they can
03:05easily resize. Their visual presentations are calculated mathematically, rather
03:11than bit by bit such as, as the case with PNG, GIF or JPEG files. So in a Flex
03:17application where you might need to stretch a component, Vector graphics really
03:20do the best job. If you want to take one component's Skins from the default
03:25library and create your own customize Flash document, so you can customize your
03:30look and feel for that component. Here is a very simple way to do it.
03:34Open the Aeongraphical.fla file in Flash CS3 or Flash 8. Then go to the Stage
03:41and select all of the objects that you want to put into your new document. For
03:45example I am going to select everything in this range, the check box label, all
03:51of the other labels, but I am also selecting the Library Symbol Instances. Now
03:56I am going to copy those to the clip board, then I'll create a new Flash
04:02document and then I'll paste the same object on to the stage in the first frame
04:08of the timeline. By pasting the object instances that also causes the same
04:14library symbols to be copied into the Flash document. Now you can go into each
04:18of these symbols and customize its look and feel. For example, I am going to
04:23select a check box selected up icon, I'll right click on the library symbol or
04:28Control+Click on the Mac and select Edit.
04:33Then I am going to Zoom in to 800%, so I can see exactly what the graphic looks
04:38like. Notice that the graphics in this movie clip symbol are made up of a
04:42number of graphical objects. Am going to click off the stage and then click and
04:47select the Check Mark Graphic. I'll Delete it and then I'll add my own graphic.
04:53I'll click the text tool, click into the graphic and set the size of the font
04:57to a reasonable size. Now I'll put in letter X to indicate that the value is
05:03selected. I'll click off the text object, select it again and then move it into
05:12place so that it's approximately centered. I would go through and do that with
05:16each of these library symbols and then at the end of the process, I would be
05:20ready to actually create a SWT file that could be imported and used in the Flex application.
05:27Now in the next video I am going to use a Flash document that's already been
05:30customized and I'll show you how to export this for use in Flex.
Collapse this transcript
Exporting a graphical skins library from Flash
00:00In this video, I'm going to describe, how to export a component library from
00:04Flash, that's suitable for use in importing into Flex Builder. For these
00:08demonstrations, I'm going to use files that are in a Flex Project, that's the
00:12part of the Exercises folder. If you're following along with the exercises, you
00:16can import the project now, from the Flex Builder menu select File, Import,
00:22Flex Project, click the Browse button next to Archive file and then navigate to
00:27the Chapter03 folder under the Exercises area and import the project
00:32Chapter03BeginProject.zip.
00:37Once the project has been imported, open it in the Flex Navigator view and then
00:41take a look at a folder within the project named FlashContent. There are two
00:46files with .fla extensions in this folder. The first one contains the original
00:51skins that have been extracted from the Aon graphical resource file, if you
00:55have Flash CS3 or Flash 8 installed in your system, you will be able to open
01:00this file and follow the export process with me, right click on the fla file or
01:06Ctrl+Click with the Mac and then select Open With, System Editor, don't just
01:12double click. In clips, typically that won't work for this kind of file, after
01:16a few moments the file opens in Flash CS3 Professional and you will see that,
01:21this version of the file contains the original graphical skins.
01:25Now, switch back to Flex Builder and open the other Flash file which is named
01:29CheckBoxSkinsNew.fla, once again right click on the file or Ctrl+Click on the
01:35Mac and select Open with System Editor and that should open the file in Flash.
01:41This version of the file has modified graphical skins, the graphical skin icons
01:46are significantly larger and instead of using a checkmark to display the
01:51selected property. These customized versions of the skins are now using text
01:56objects with a particular font.
01:58Notice once again, that each of the objects on the stage is simply an instance
02:02of a library symbol and you'll find the Library symbols over in the Library
02:06panel. Here is how you export these graphical skins for use in Flex. In Flash,
02:13you can export one symbol at a time to a SWC file. What you really want is a
02:18SWC file, that combines all of these symbols together and makes them all
02:21available to Flex at the same time.
02:24So, to make that happen, create a new empty symbol in the Library, go to the
02:30Library panel and right click or Ctrl+Click on the Mac and select New Symbol,
02:36you can name the symbol anything you want, but you should not include any
02:40spaces or special character in it. I am going to name the symbol CheckBoxSkins,
02:46I'm using CamelCase syntax rather than spaces, because of the restrictions on
02:49the naming convention. The type must be set to Movie clip. The goal is
02:54essentially to export classes, that can be read and recognized in Flex and only
02:59Movie clips symbols serve that purpose, click OK to create the symbol. That
03:04will then take you into editing mode in the new skin. In order to combine all
03:08of the skinning symbols into one exportable SWC file, drag one instance of each
03:14of the existing symbols into the new symbol. It doesn't matter where you put
03:18the symbol instances. The user is never going to see this file.
03:22Again, the goal here is just to create a library of each of the symbols that
03:26you can easily export. The CheckBoxSkins symbol, now contains at least one
03:38instance of each of the other symbols. Now, you are ready to export to SWC
03:43format. Save your changes, I will select File, Save from the menu, then go back
03:48to the library panel and right click on the CheckBoxSkins symbol. Select Export
03:54SWC File from the menu, you can place the SWC file anywhere you like, but I am
03:59going to navigate to the Chapter03Begin folder under my Workspace, where I am
04:03actually working in Flex right now and from there I will go down to the
04:07FlashContent folder and I will save the exported component library as
04:12CheckBoxSkins.swc, it takes just a few seconds for the export to happen, I'll
04:20go back to Flex Builder and you will see that the new SWC file has been created in the project.
04:26In the next video, I will show you how to import the graphical skins into a
04:30Flex application and connect them up with the Flex components, in this case the
04:34CheckBox component that you want to reskin and redesign.
Collapse this transcript
Importing Flash-based skins in Flex Builder
00:00In this video, I am going to describe how to import a set of graphical skins
00:04that have been created in Flash and exported as a component library in SWC file
00:09format. In the previous video I showed you how to create the SWC file, now if
00:14you don't have Flash CS3 Professional or Flash 8 Professional available. You
00:18can still follow through this exercise if you have the Exercise Files because
00:22in the finished folder of the FlashContent area, you will find a pre-built
00:27CheckBoxSkins.swc file that contains everything you need for this exercise.
00:32So if you are following along with the exercises, the next step is to open up a
00:36Flex application. Go to the project in the Flex Navigator view and go to the
00:40source folder and open the file UseCheckBoxSkins.mxml. This application
00:47displays a set of CheckBox components wrapped inside a panel; each of the four
00:52CheckBox components has a different set of states. There is one CheckBox that
00:56has a Selected property of true, one that's Selected and disabled and then two
01:01others that combine the properties in various ways. This allows us to see the
01:06CheckBox presentation in its initial state, both when the mouse is not anywhere
01:10near the check boxes and you can also see what happens when you manipulate the
01:15check boxes using the mouse cursor.
01:18Now I will go back to the application; Flex Builder 3 includes the ability to
01:23automatically import these graphical skins from the component library and make
01:28them a part of your application. Here are the steps, from the Menu, select
01:32File, Import, Skin Artwork. You can import a number of different kinds of files
01:40into Flex, you can import a folder of Bitmap images that are built in PNG or
01:45JPEG format for example or you can import a SWF file that was built in
01:49Illustrator or as in this demonstration a SWC file that was built in Flash.
01:55Select SWC or SWF file and then click the Browse button, navigate to your
02:00workspace area; my workspace is under lynda.com under my C colon root and from
02:07there flex3btb, Chapter03Begin, FlashContent and I will select the component
02:15library CheckBoxSkins.swc that I created in the previous video.
02:19Click the Open button and then indicate where you want to create skin style
02:24rules; this process is going to result in generating some Cascading Style Sheet
02:28code. You can indicate where you want to create the CSS file, the default is to
02:34create a CSS file with the same name as the SWC file but with a .css extension
02:39and by default it will be placed in the source code root of your application.
02:44Then indicate which application you want to bind the CSS file to; in this
02:49project they only have one application UseCheckBoxSkins.mxml, then click the
02:54Next button. The next step is to match up the Symbol Class names
02:58from the Flash component library with Style Selectors and which skin matches
03:04each symbol. If we use the default skinning library that I showed in Flash as
03:08the basis of your skinning library, Flex Builder automatically recognizes the
03:13Symbol Class names and matches them up with the Style Selectors and the Skin Parts.
03:18So for example the CheckBox_selectedUpIcon Symbol Class matches the
03:23selectedUpIcon Skin Part and this is an already recognized style name that's a
03:28part of the API or the public interface of the CheckBox component. Notice that
03:33there is no automatic selection for the wrapper symbol, CheckBoxSkins. The only
03:38purpose of that symbol was to be able to create a single component library that
03:43wrapped all of the others. We won't be using that skin directly in the Flex
03:46application; you also don't need to deal with the special Symbol Class
03:50fl.livepreview.LivePreviewParent. Click Finish and you will see a few things
03:56happen, first of all Flex Builder creates the Cascading Style Sheet file that
04:00you requested. In this CheckBoxSkins.css and it generates the code with a
04:06CheckBox selector matching the component name and then 8 different skinning
04:11property values.
04:12Each of these property names matches a property name supported by the CheckBox
04:16component. Then there is a call to the embed compiler directive that goes and
04:21gets a class from SWC file and notice that we are referring to the name of the
04:26Symbol Class as it was generated from Flash. Now go back to the application
04:30itself to the MXML file, scroll down towards the bottom of the file and you
04:36will find a style declaration that's been added to the application below any of
04:40the other existing code, 'mx:Style source =' and then a reference to the CSS
04:45file. So that's how the MXML application and the Cascading Style Sheets file
04:50are bound together.
04:51There is one other step in the process that's a little less visible, in order
04:55for these graphical skin classes to be available to the project in the
04:59application, the SWC file must be added to the build path of your project and
05:04this is handled automatically by the import process as well. Go to the Menu and
05:08select Project, Properties then navigate to Flex Build Path and from there to
05:14the Library Path tab and you will see that your CheckBoxSkins.swc file has been
05:19added to the Library Path of the project. That's the third critical part of how this all works.
05:25The SWC file is a part of the build path therefore its classes are available to
05:30the Flex compiler. The Cascading Style Sheet file refers to those class names
05:34from the Flash component library and associates them with their respective
05:39styles names and then again the application binded altogether by incorporating
05:44the Cascading Style Sheet file. I will save the change and run the application
05:50and you will see that this version of the application now uses my new graphical
05:53skins. I can click and select and see how the CheckBox control is going to
05:58appear using my new graphic design.
06:01Now I will caution you throughout that I am not a graphic designer, this is the
06:04best I am able to come up with and if you are going to follow this process of
06:08incorporating new graphic designs into your application, I recommend that you
06:12get a great graphic designer who is acquainted with Flash or if you decide to
06:16go the route with Illustrator who knows Illustrator inside and out and you will
06:20be able to give your applications a distinct look and feel that's very
06:24different from the default Flex visual presentation.
Collapse this transcript
4. Integrating Flash and Flex
Preparing a Flash Document for Use in Flex
00:00In this chapter of the video series I am going to describe a variety of
00:04approaches to integrating Flash content in Flex applications. I will start with
00:08the simplest of approaches loading a basic Flash document using a Flex
00:12component called SWFLoader. I will then move on to the next level of complexity
00:17embedding a Flash symbol and using it from within a Flex application and
00:21finally I will move on to the most advanced approach which involves the tool
00:25called the Flex Component Kit that you can install into Flash CS3 and then use
00:30to create an export Flex components that are built in Flash.
00:34For all of the exercises in this chapter I will use a Flex Project that's part
00:38of the Exercises Folder. If you are following along with the exercises you can
00:42import the project now from the Menu select File, Import, Flex Project, click
00:50the Browse button next to Archive file, navigate to the Chapter04 folder under
00:55Exercises and select Chapter04BeginProject.zip and import it. Once the project
01:02has been imported open the project in the Flex Navigator view and start off in
01:07the FlashContent folder. This folder has a file called CarRace.fla; if you have
01:13Flash CS3 available you can open this file now. It's important to know that
01:17this is a Flash file that was created in Flash CS3 using ActionScript 3. If you
01:23have an older version of Flash, Flash 8 for example, you won't be able to open it.
01:27If you can't work through these exercises directly, there are finished versions
01:31of all of the Flash and exported SWF files available in the finished folder
01:36underneath FlashContent. If you do have Flash CS3 available, right click on the
01:41file or control click with the Mac and select Open With, System Editor. As I
01:47described in a previous video, if you try to open a Flash file from within Flex
01:51Builder simply by double-clicking it, normally an error will occur. This is a
01:56very simple Flash document, it has a set of layers and each layer has a symbol
02:01instance. When its run, this Flash document shows a very simple car race.
02:05I will preview by selecting File, Publish Preview, Flash and you will see that
02:13the cars move across the screen from left to right until one of the cars hits
02:17the finish line and then it stops. The application has a tiny amount of
02:22ActionScript code, I will show you the final frame in the actions layer and it
02:26simply has a stop command to stop the animation after running through it once.
02:32That's it, there is no complex logic in this Flash document, its simply using
02:37the Timeline and motion tweening to move objects across the screen. In order to
02:42use this document in a Flex application in the most simple way, all you need to
02:46do is publish it; before publishing for this purpose make sure that you have
02:51turned off the export of HTML and JavaScript that's normally associated with a new Flash document.
02:57Go to the Menu and select Publish Settings, then take a look and make sure that
03:02the HTML option is turned off. It should be in this document because I prepared
03:06it that way but for your FlashContent you will probably want to turn off the
03:11HTML output. Here's another thing to check before you publish the document, new
03:17documents built in Flash have a default Frame rate of 12 frames per second. The
03:22Flex framework runs at 24 frames per second, so in order to make sure that the
03:27Flash document and the Flex application that hosts it are compatible with each
03:31other, you should typically set your Flash documents Frame rate to 24 frames
03:36per second to match Flex. I will make that change and then once again I will
03:41preview it using Publish Preview, Flash.
03:45Notice that this time the car has traveled across the screen twice as fast,
03:49that's how the animation will look when you play this Flash document from
03:53within the Flex application. Now you are ready to publish, go to the Menu and
03:57select File, Publish or press the keyboard shortcut to do the same thing. Now
04:03go back to Flex Builder and you will notice that you now have a new CarRace.swf
04:08file in the FlashContent folder. Take that CarRace.swf file and copy it to the
04:15clipboard, you can right click on the file or control click with the Mac and
04:19select Copy. Now go the source folder and paste it, this SWF file is now a part
04:27of the assets of your Flex application and in the next video I will show you
04:31how to use the SWFLoader component to load the SWF file and display it as part of the Flex app.
Collapse this transcript
Displaying a Flash Document with SWFLoader
00:00In this video I am going to describe how to use a Flash document that's been
00:04prepared for use in Flex by setting its Frame rate to 24 frames per second and
00:09then publish to a SWF file. For this demonstration, I will use an application
00:13named LoadSWFFile.mxml. If you are following along with the exercises you can
00:19open this application in Flex Builder; the beginning application has some very
00:23simple code, it has a VBox container with a white background and padding
00:28settings. In order to load a SWF file into Flex you use a component named
00:33SWFLoader, you can declare the SWFLoader object using MXML code or
00:38ActionScript; in this demonstration I will use MXML.
00:42You declare the SWFLoader object and then you set its source property to the
00:46location of the SWF file you want to load, in this case its CarRace.swf. Save
00:53your changes and try running the application, as you run the application you
00:58immediately load the SWF file and start playing its animation. When you load a
01:03Flash document in this fashion you don't have a huge amount of control over the
01:07document; for instance you can't pass data in or listen for events coming out
01:11of the document in this way. But you do have Timeline control, that is, to say
01:16you can call the standard Timeline functions that are associated with movie
01:20clips in the Flash environment.
01:21In order to do that you have to get a reference to the Flash document as a
01:26movie clip and then you can call the functions to control it. Let's see how to
01:30do that, I will go back to Flex Builder to the application Source code and then
01:35I will add a Script section and within the Script section I am going to create
01:39a new private function named playAnimation. The function will return void,
01:45within the function I am going to get a reference to the SWF object, its
01:49referenced through a property called content of the SWFLoader object. I will go
01:54down to the SWFLoader declaration and add id property so I can address it in my
01:58code and I will set its id as loader. Then within the function, I will declare
02:04a variable named flashContent and I will data type it as a class named MovieClip.
02:10This is a Flex version of the MovieClip class that exposes all of the Timeline
02:14functions such as goto, gotoAndPlay, stop and so on. I will initialize the
02:20flashContent variable using this syntax, loader.content as MovieClip. This now
02:29gives me a reference to the Flash document and I can control it. I will call
02:34the gotoAndPlay method which you will see actually shows up in the public
02:38interface of the MovieClip class. There are couple of different options here,
02:42you can pass in a frame number or a frame name, you can also pass in scene
02:46names if you use scenes in your Flash content. I will use the gotoAndPlay
02:51function and pass in a value of 1 meaning goto frame 1 and play the movie.
02:56Next I will place the cursor under the VBox container and add a new Button
02:59control. I will set the Buttons label to Play Movie and set its click event to
03:07call my new function playAnimation. I will save the changes and run the
03:13application. Once again as the Flash document starts up, the Flash movie loads
03:20and plays but now I will play the Flex button labeled Play Movie and you will
03:26see that it has the effect of the sending the play head of the Flash movie back
03:30to frame 1 of its Timeline and playing the movie.
03:33So again this is the simplest approach that you have available for
03:37incorporating Flash content into a Flex application, its worth looking at the
03:41documentation for the MovieClip class. I will place the cursor inside the
03:45MovieClip data type and then press Shift F2 to bring up the documentation and
03:50then click on the list of Methods. These are all the methods that you have
03:53available, gotoAndPlay, gotoAndStop, play, stop and so on.
03:58The MovieClip class is actually a member of the Flex framework, it's a wrapper
04:03for the Flash document and while again it doesn't give you great control over
04:08the document, you can't get to the documents data or call its public methods.
04:12You can at least control the animation. Now in the next couple of videos I will
04:16show you a more fine tuned approach where you expose Flash content as a symbol
04:21and then embed it in a Flex application which allows you to call its methods
04:25and get to its data.
Collapse this transcript
Preparing a Flash Symbol for Use in Flex
00:00In this video I am going to describe the steps required to prepare a Flash
00:04symbol for embedding in a Flex application. Just as when working with Bitmap
00:08images such as PNGs and JPEGs you have the ability to embed Flash content in a
00:14Flex application. This results in being able to display the content instantly
00:18rather than having to wait for it to download from a web site. The tradeoff for
00:22embedding content in this fashion is that whatever the size of the SWF content
00:27is, your Flex application size will expand by that much.
00:31Before you embed the content, you need to turn it into a Flash symbol and then
00:35link that symbol to an ActionScript class. I am going to start with the
00:39existing Flash document in the Chapter04BeginProject, CarRace.fla. Now if you
00:45don't have Flash CS3 available, you will need to use a finished version of the
00:49published SWF file I am about to create and I have included that in the
00:53finished folder under Flash content in a file named CarRaceAsSymbol.swf but if
00:59you do have Flash CS3 and you have access to the Exercise Files you can follow
01:03along. Right or control click on the file CarRace.fla and select Copy, then
01:10right or control click on Flash content and paste.
01:14You will be creating a new version of the CarRace.fla file and I am going to
01:19name the new version of the file CarRaceAsSymbol.fla. Next open the new file in
01:27the Flash authoring environment, right click on the file or a control click on
01:31the Mac and select Open With, System Editor and that should open the file in
01:37Flash. Now your next step is to create a new movie clip symbol. The movie clip
01:42symbol must be linked to an ActionScript class; you don't have to create an
01:46explicit ActionScript class, Flash will do that for you if you follow the right
01:51steps. Go to the Library panel and click the plus button at the bottom or you
01:57can also right or control click and select New Symbol and create a new movie
02:01clip symbol. In the Create New Symbol dialog, set the Name of the new symbol to
02:07mcCarRace; make sure the Type is set to Movie clip, that's the only kind of
02:12symbol that you can embed in a Flex application.
02:15Then click the Advanced button and that will open up all of the ActionScript
02:18properties. Under Linkage, click Export for ActionScript. You will be creating
02:25an ActionScript class named for the symbol mcCarRace and it will be based on
02:29the Flash.display.MovieClip class. Now as I mentioned you don't actually have
02:35to create an explicit ActionScript class file here. So just click Okay and you
02:40should see this warning, indicating that the class couldn't be found and so one
02:44will be automatically generated for you in the SWF file when it's published or
02:48exported. If you see this warning, click Okay and now you are editing your new
02:53symbol. Now go back to the main document Timeline, click the Scene 1 link above
02:59the editing area and then select all of the frames in all of the layers as
03:03follows.
03:05Click in the first frame of the first layer, then hold down the Shift key and
03:10click into the last frame of the last layer. Right click anywhere in the
03:14selected area or a control click on the Mac and select Copy Frames. Go back to
03:20editing the symbol, go to the Library panel and right click or control click on
03:24the Mac on the symbol you created and select Edit. Go to the first frame of the
03:31first layer, right or control click and select Paste Frames and that will take
03:37all of the content that was in the main document and copy it over into the
03:41symbol. It's very important in order for this symbol to be compatible with Flex
03:47for the top-left corner of all of the visual content to be aligned with the
03:51registration point in the center of the symbol.
03:55Essentially that means that you want the X and Y properties of the top objects
03:58to be set at 0. To accomplish this easily click into the first frame in the
04:04first layer that contains visual content, greencar. Hold down the Shift key and
04:09click into the last layer, fist frame then move the cursor down into the stage
04:13area and click on any of the selected symbols. Go to the properties area and
04:19set the X and Y properties to values of 0 each. I am going to expand to full
04:23screen so we can see the result. Notice that the top-left corner of the top car
04:28is on the registration point, that's exactly what you want. Now that does not
04:32affect what happens in the final key frames.
04:35So the next step is as follows, go to the course layer and lock it. Click the
04:40link under the Lock icon and that will mean that no matter what you do next you
04:44won't be moving the finish line from its current position which is correct.
04:48Then go to the last frame for all of the layers containing visual objects;
04:52click into the last frame in the first visual layer, Shift and click into the
04:57last frame of the last visual layer and then click on one of the car objects
05:02and drag them into place. This will take a little bit of eyeballing because you
05:06want the images to appear so that the yellowcar is just going over the finish
05:11line at the end. With those objects selected take a look at the Properties
05:15view, I have been pressing the F4 function key to show and hide all of the
05:19panels.
05:20Now with those cars still selected set the Y value at 0 but leave the X value
05:26alone; that will mean that the cars are still in the same location vertically
05:30but you have placed them horizontally where you want them. To test the symbol
05:34go back to the main document Timeline, click on the Scene 1 link above the
05:38editing area, select all layers below the actions layers. Click into the first
05:42layer, hold down the Shift key and click the last layer, then click the trash
05:46can icon at the bottom to delete all those layers. Double-click the actions
05:51layer name and change it to carrace because now it's going to be the only layer
05:56displaying the instance of this symbol. Then click into the first frame of the
05:59remaining layer, go to the Library panel, drag in the instance of the symbol
06:05and sets its X and Y properties at 0 each.
06:09Save your changes and then preview your document by selecting File, Publish
06:15Preview, Flash and the carrace should play correctly. Now you may notice that
06:21at the end of the animation the content went away; close the preview, go back
06:26to the one remaining layer, click into the second frame, Shift and click into
06:31the last frame. Then right click and Remove Frames and then try previewing your
06:37document again. Select File, Publish Preview, Flash and this time only the
06:46component is doing the animation and you should see the cars stop correctly.
06:52So here are the critical steps that I followed, I selected all frames and all
06:56layers in the main document and then pasted all of those frames and layers into
07:00the movie clip symbol. I made sure that the top-left corner of the visual
07:04content of the symbol was at the main registration point that is X and Y
07:08properties of 0 and 0 and then when I created this symbol, I set up the Linkage
07:14properties so that I had a named class I could refer to in my Flex application.
07:19I didn't have to create an actual explicit ActionScript class; that was done
07:23for me by the Flash authoring environment.
07:25The final step is to publish your document, from the Menu, select File,
07:31Publish. Then go back to Flex Builder and you should find a file
07:36CarRaceAsSymbol.swf has been created in your FlashContent folder. Right or
07:41control click on the SWF file and copy it, go to the source folder and paste it
07:48and now your SWF file is ready for embedding in the Flex application and I will
07:52show you how to do that in the next video.
Collapse this transcript
Embedding Flash symbols in Flex
00:00In this video, I'm going to describe how to embed a symbol built in Flash in a
00:04Flex application. Before I start with the demonstration, I need to describe one
00:09serious limitation to this approach.
00:11When you embed a symbol directly from a SWF file, you loose access to the
00:16ActionScript code that's a part of that symbol, that is the ActionScript code
00:20in the symbol is essentially ignored. So this approach is best suited for
00:24Flashed animations that loop infinitely, where you don't need to execute any
00:28ActionScript code that's inside the symbol.
00:31You will however still be able to execute movie clip functions using the movie
00:36clip wrapper class that I demonstrated in an earlier video.
00:39For this demonstration, I'll use the EmbedFlashSymbol.mxml application file
00:44from the Chapter04Begin project. If you are following along with the exercises,
00:48you can open that application file now.
00:51The application file is the same as I created in a previous video. It uses the
00:55SWF Loader component to load CarRace.swf at run-time. I'll run the application
01:01and show the current functionality. As the application starts up it loads the
01:06SWF file and plays its animation. When you get to the end of the Flash
01:10document's time-line, the animation stops due to the Stop command that's in the
01:15SWF file. You can click the Play Movie command to restart the animation.
01:21Now, let's go back to the application. In the previous video, I created this
01:25file, CarRaceAsSymbol.swf where the content of the animation was in a symbol
01:31instead of the main time-line of the document and I made sure that I provided
01:34Linkage Properties for this symbol so I could refer to this symbol from within
01:39my Flex application.
01:41As I mentioned earlier, if you are following along with the exercises but you
01:44don't have access to Flash CS3, you can use this version of the SWF file that's
01:49in the Finished folder under FlashContent, CarRaceAsSymbol.swf, and you would
01:54just want to copy that SWF file to your source folder before you go on with the
01:58rest of the code. Let's go to the code now.
02:01I return to the application file and place the cursor inside the script
02:05section. To embed a symbol, you use the Embed metadata tag. As with all
02:11metadata tags, it starts with the bracket character. Then you put in the word
02:15Embed and an opening parenthesis. You are going to pass in two attributes. The
02:20first is named 'Source' and it's going to point to the SWF file that contains
02:25the symbol you want to embed. I am going to be using CarRaceAsSymbol.swf, then
02:33put in a comma and add a symbol attribute. The value for the symbol attribute
02:38is the linkage ID of the Flash symbol. It's not necessarily the symbol name as
02:44it exists in the library in the Flash document, instead, it's that class name
02:48that was created when you set Linkage Properties.
02:52In my symbol, I used mc CarRace as both the symbol name and as the linkage ID.
02:57By using the same value for both, it's one last thing to remember.
03:03The next step is to also have the Bindable tag. This is going to allow you to
03:07easily pass the SWF file to the SWF Loader through a bindable expression.
03:12Finally, create a private variable and name it flashSymbol. The name of the
03:18variable can be anything, I am just naming it flashSymbol so I can remember
03:21what it is. And then data type it as a Class.
03:25That's all the code you need to embed the SWF file in the application. The
03:29first line embeds it, the second makes it bindable and the third declares a
03:34variable, that's associated with the symbol so we can refer to it in our
03:38ActionScript and binding expressions.
03:41Now, go down to the SWF Loader tag at the bottom of the application. In the old
03:46version, the source tag should to be pointed to the full SWF file and loaded at
03:50run-time. Replace that reference to a binding expression, that refers to
03:55flashSymbol, that is the name of the variable that's associated with the symbol.
04:00Save your changes and run the application. You'll see that the application
04:04starts up, and once again it plays the animation. But now, instead of stopping
04:10at the end of the animation what it hits the last frame, it just continues, and
04:16again, that's because when you embed content in this fashion, ActionsScript
04:20code in the time-line is ignored.
04:23You can still control the movie's time-line from outside. Every time I click
04:28the Play Movie button, it goes back to the first frame and continues playing,
04:32and you could also add other buttons and execute other time-line functions by
04:37referring to the SWF Loader's content property as a movie clip and then calling
04:41any of the movie clip functions that I demonstrated in an earlier video.
04:45So this a nice approach again for Flash animation that simply loops and where
04:50all you need to do is control its time-line, but for more sophisticated
04:54integration of Flash with Flex, you are going to want to create full Flex
04:58components in the Flash environment, and that's what I'm going to show you how
05:02to do in the next few videos.
Collapse this transcript
Installing the Flex Component Kit in Flash CS3
00:00In this next set of videos, I'm going to describe how to take a Flash symbol
00:04and export it as a Flex component from the Flash authoring environment.
00:09In order to do this, you need a little bit of extra software that you can
00:12download for free from the Adobe website. The Flex Component Kit was available
00:17for sometime at Adobe labs as a public data. There are notes on left side that
00:22indicate that the Flex Component Kit is a part of the SDK that was delivered as
00:25part of Flex Builder. However, the kit didn't make it into the final delivery.
00:30You can however get it from the Adobe website if you know where to look.
00:33I have included a text file in the project and if you are following along with
00:38the exercises, you can open it and for those of you who don't have access to
00:41the exercise files, I'll show it to you here.
00:44Navigate to this web page
00:45www.adobe.com/cfusion/entitlement/index.cfm?e=flex%5Fskins.
00:58That will take you to a log-in screen where you'll need to login with an Adobe ID. If you don't
01:04have an Adobe ID, you can sign-up for one for free. If you do have one, go
01:08ahead and log in and you'll go to this page.
01:11The Flex Skin Design Extensions and Flex Component Kit for Flash CS3 download
01:16page has links to a number of valuable tools. In addition to the Flex Component
01:21Kit for Flash that I'll be demonstrating here, there are also links to skinning
01:25libraries for FIREWORKS, FLASH, ILLUSTRATOR and PHOTOSHO of particular interest
01:31for graphic designers, there is a Skin Design Extension for Illustrator that
01:35you can download. I'm going to focus here, on the use of the Flex Component Kit.
01:40The link for that is at the bottom of the page at least as of this viewing.
01:43Click the link and download the kit which will come to you as a ZIP file.
01:47Now, I have already downloaded the kit. As I mentioned, it comes to you as a
01:50ZIP file and this ZIP file contains two files. A readme.txt file that contains
01:56some instructions and an MXP file which is an Adobe Extension. The purpose of
02:01an extension file is to add capabilities to an Adobe application such as Flash
02:07or Dreamweaver, extracts the contents of the ZIP file.
02:10For example, I simply dragged the MXP file to my desktop where it's already
02:15available as a non-zipped file. Then, start up the Adobe Extension Manager. If
02:20you are working on Windows Vista, you can get to the Extension Manager by going
02:24into the Start Menu and then start typing Extension and look for Adobe
02:29Extension Manager CS3.
02:31If you are working on Windows XP or the Mac, navigate to the application as you
02:35do on those operating systems. And either way open up the application. Before
02:40you continue, make sure you've closed down Flash CS3. You always want to close
02:44down any application that you are about to upgrade with an extension. Then go
02:48to the Adobe Extension Manager Menu and select File - Install Extension.
02:54Navigate to the location where you abstracted the file, select
02:58FlexComponentKit.mxp and click Install. Review the license agreement and if you
03:04agree with it, except it and you'll see very quickly a conformation that says
03:08that the kit has been successfully installed.
03:11Click OK, close the Extension Manager and then restart Flash CS3.
03:20Open up any Flash document. For this test, you can create a brand new Flash
03:24document, then go to the Commands Menu and you should see these new choices,
03:30convert symbol to Flex Component and convert symbol to Flex Container.
03:35If you see these menu selections, then you are ready for the next steps.
03:39In the next videos, I'll show you how to prepare a symbol for use a as Flex
03:42component and then how to export it as a component library, and then finally
03:47how to use it in your Flex application.
Collapse this transcript
Creating and exporting a Flex component in Flash
00:00In the previous video, I described how to download and install the Flex
00:03Component Kit into Flash CS3, to allow you to take Flash symbols and turn them
00:09into Flex components.
00:10In this video I'll describe the steps you follow to take a Flash document with
00:14symbols and export these components as a Component Library that's compatible
00:18with Flex 3.
00:19I'll be starting in Flex Builder using the Chapter04Begin project, and I'm
00:24going to make a copy of the file CarRaceAsSymbol.fla.
00:28Now, for any reason you don't have this file, you can get a copy of it from the
00:31finished folder under FlashContent if you are following along with the
00:34exercises. I am going to select the file CarRaceAsSymbol.fla, right-click or
00:40Ctrl+Click with the Mac and select Copy, then go to the Flash Content folder
00:46and Paste.
00:46You are prompted to assign the file a new name. I'm going to name the new file
00:52CarRaceAsComponent.fla. Then I'll select the file in the Flex Navigator view,
01:00right-click or Ctrl+Click on the Mac and select Open With - System Editor.
01:06Now I have my component open in Flash. Let's take a look at the symbol that I
01:09created in a previous video mcCarRace. This is the symbol that encapsulates the
01:14car race functionality including animations and ActionScript code.
01:19Right now, the current linkage properties, set the class name as mcCarRace
01:22which is what I selected previously and the base class as
01:26flash.display.MovieClip. The MovieClip class is compatible with the Flash
01:31environment. It represents a movie clip object. In the Flex environment though,
01:35you need a more complex component in order to be able to easily add objects to
01:40the Flex framework, that is Add Components to Containers and so on.
01:44So if you have already installed the Flex Component Kit, this is a very simple
01:48thing to do. I'll cancel out of the Linkage Properties, go to the Flash Menu
01:53and select Commands - Convert Symbol to Flex Component. It takes just a moment
01:59for the conversion to happen. The Output view appears and shows you some
02:03information about the steps that were taken in the background. Close the Output
02:06View and go back to the Library panel and once again look at the Linkage Properties.
02:12Notice, this time the base class is mx.flash.UIMovieClip. The UIMovieClip which
02:18is now the base or the super class for my component is compatible with the Flex
02:22framework, and any class that's derived from UIMovieClip can be easily added to
02:27a containership architecture in Flex.
02:30Now, let's take one more step before I export this for use in Flex. You can set
02:35the class name as anything you want. As with all good classes that you
02:39typically use in the Flex environment, it's a good idea to assign a package
02:43name, that is a prefix to the class name and following good object-oriented
02:47conventions that we tend to follow in Flex to uppercase the name of the class.
02:52So I am going to change the name of the class as it will be known in Flex to
02:56flashcomps.FlashCarRace. I still haven't created an explicit ActionScript
03:02class, instead, when I save these linkage properties, I'll be prompted and told
03:07that a definition for the class couldn't be found and so one will be
03:10automatically generated. Click OK to save your changes. Now, you are ready to export.
03:16You can export to a component library in a couple of ways. You can either go to
03:20the Library panel and right or Ctrl+Click on the symbol that you want to
03:24export, and then select Export SWF file or in a slightly simpler step, you can
03:29simply publish the Flash document. I'll select File, Publish and that's going
03:36to generate both a SWF file and a SWC file.
03:39The SWF file won't be used in this example, instead, when I go over in to Flex
03:44and integrate my component into the Flex application, I'll be using the SWC file.
03:49Now, I'll go over to Flex Builder and take a look at the results. In the
03:53FlashContent folder where I cerated my CarRaceAsComponent.fla file. Here's the SWC file and here's the SWF file.
04:01Now in the next video I'll show you how to incorporate this SWC file into your
04:05Flex application and how to instantiate your new Flex component.
Collapse this transcript
Using Flash component libraries in Flex
00:00In previous videos, I described how to download and install the Flex Component
00:04Kit into Flash CS3, and then how to use the kit's capabilities to prepare and
00:09export a Flash symbol as a Flex component. The result was a SWC file, a
00:14component library that you can then incorporate into a Flex application.
00:19In this video I'll show you how to incorporate the SWC file and its symbols or
00:22components into a Flex application. For this demonstration, I'll use the
00:27application file UseFlashSWC.mxml. If you are following along with the
00:32exercises, you can open up this MXML file from the project now.
00:36The application in it's beginning state has a layout property of absolute and a
00:40style name of plain. By setting the style name to plain, the result of the
00:44plain style name is to give the application a white background, to match the
00:48white backgrounds of the images in the Flash component of using. There is also
00:52a simple label control with a text property of Flash CarRace and with its X and
00:57Y properties set to 20 pixels each, and the application, its beginning state
01:01simply displays that label.
01:04Here are the steps to incorporating the Flex component from Flash. First, you
01:08need to add this SWC file to your build or library path. There are two ways to
01:12do that. One way is to copy this SWC file into the project's Libs folder. When
01:18you build a project in Flex Builder 3, the Libs folder is created automatically
01:22and it's a part of the class or build path automatically. So any SWC files that
01:27you drop into that location will automatically be available to the compiler.
01:31On the other hand, if you can do it in that way, any changes that you make in
01:35Flash won't be published to the Libs folder unless you configured Flash that
01:38way. So another approach is to explicitly add the SWC file to the build path of
01:44the project. That's the approach I'll take.
01:47I'll go to the Flex Builder Menu and select the Project, Properties. Then I'll
01:51select the Flex Build Path category, from there click on the Library Path tab
01:57and then click Add SWC.
01:59In the Add SWC dialog click the Browse button and navigate to the FlashContent
02:04folder under your Chapter04Begin project, My browsed window already came up to
02:09that folder. Then I'll select CarRaceAsComponent.swc, open it and click OK.
02:15Then click OK to save your new project properties. Every time you add a new SWC
02:20file or the SWC file gets updated, the project will be rebuilt and any
02:24components in the SWC file will automatically be available to your Flex application.
02:29The next step is to add an instance of the component. As with all MXML tags,
02:35you do need to add a custom name space prefix, mapped to the package in which
02:39your component is stored. Flex Builder 3 however automates this process for
02:44you. So, I'm going to place the cursor after the mx label tag and before the
02:48end application tag then type in a less than (<) character and then start
02:53typing the name of the component as it's known in the Linkage Properties in Flash.
02:58I named this class FlashCarRace. Notice, that Flex Builder is already aware of
03:04the component name and its package flashcomps which I created in the Linkage
03:08Properties in Flash. I'll select the class and take a look up at the
03:12application tag. Notice that Flex Builder has automatically added a name space
03:17prefix, matching the package name of the component as I named it in Flash.
03:23I'll add an ID property and simply call it Race and then I'll also add x and y
03:28properties. This is now a complete visual component and you can place it on the
03:32screen relative to the top left corner of any absolute layout container; such
03:38as the application with its layout is set to Absolute or a Canvas perhaps. I'll
03:42set the values to x of 100 and y of 100.
03:48I'll save the changes and run the application and there is my Flash component
03:54running in a Flex application. So, now I would like to show you a couple of
03:58other interesting things you are able to do with this component.
04:01Just as I showed in an earlier video that incorporated SWF files and embedded
04:05symbols, you are able to execute simple time-line commands with these
04:09components. Each component that's extended from the UIMovieClip class is this
04:14one now is supports methods such as Play, Stop, Go to and Play, Go to and Stop
04:20and other functions that you might be used to with the Flash time-line.
04:24I'm going to place the cursor above the label and add an Application Control
04:28Bar with it's doc property set to True, and then within the Application Control
04:33Bar I'll add a button, set its label to Replay and its click event handler to
04:41call this function race.gotoAndPlay and notice that the gotoAndPlay and
04:46gotoAndStop methods are already available. They are a part of the UIMovieClip
04:51component and its descendants, and I'll pass in frame one.
04:58Add another button with the label of Stop. Add a click event listener that
05:05calls the Stop method and then one more button this one with the label of Play
05:12and this one we'll call race.play. I'll save the changes and run the application.
05:20I'll let the movie play for the first time when it loads then I'll click the
05:23Replay button, the Stop button to pause it and the Play button to continue,
05:29So, you see that when you expose a Flash symbol as a Flex component, you
05:34automatically get all the time-line behavior that previously I had to add
05:38additional code to execute.
05:40So, that's a look at how to take a Flash symbol and use it in a Flex application.
05:45Now, there is one more interesting step in this process. Once you've hooked
05:49this up as a Flex component, you have the ability to go back into Flash and
05:53extend the capability to the component adding whatever component style
05:57ActionScript code you want including custom properties, custom methods and
06:02custom events.
06:04I'll show you how to do that in the next video.
Collapse this transcript
Extending a Flash component with a custom class
00:00In this video I am going to describe how to extend the capabilities of Flash
00:04symbol that you have exposed as a Flex component and integrated into your Flex
00:08application. Here are the steps I am going to follow. First all, create a
00:12custom ActionScript class. This custom ActionScript class will extend the
00:17UIMovieClip class that's currently used as the base for my Flash symbol. Then I
00:21go back over to Flash and I will re-link my movie clip symbol to the new custom
00:26ActionScript class. Then I will be able to add custom functionality to that
00:31class and I will be able then to call that functionality in Flex.
00:35The first step is to create the custom ActionScript class. You could do this
00:38step in either Flash or in Flex. Since Flex Builder has better code generation
00:43capabilities though, I will start there. From the menu select File, New,
00:50ActionScript Class. Set the package as flashcomps and the name of the custom
00:57ActionScript class as carRaceClass. You can name the class anything you want
01:02and you can put it in any package. Initially this class is going to be created
01:06in the source root of the Flex project. But after it has been created I am
01:10going to move it over to the folder that contains my Flash content.
01:14Click the Browse button to select a super class and then start typing the name
01:18of the UIMovieClip class until you find it and then click OK and that fills in
01:24the super class correctly, Click Finish and that's your beginning ActionScript
01:30class. Now close the class in Flex Builder, go over to the Flex Navigator view
01:37and drag to flashcomps folder that was created in the source root into the
01:41FlashContent folder, so that it becomes unavailable to the Flash content. Now
01:47go to the flashcomps folder within the FlashContent folder, go to
01:51CarRaceClass.as and select Open With, System Editor and this should result in
01:58opening the class in Flash.
02:00Now you are ready to start adding custom functionality to your Flex component.
02:04I am going to create a new function which is simply named go. It will be
02:09function that calls the simple gotoAndPlay function. So, its not going to do a
02:13whole bunch, but you will see that you are able to call it from Flex and you
02:17will be positioned to be able to add additional custom functionality later on.
02:22I will create the function, I will make sure it's public so I can call it from
02:25the Flex application and I will name it simply go and return void and within
02:33the go function I call gotoAndPlay and pass in a value of 1 for frame1 and I
02:41will save the changes to the ActionScript class.
02:45Now go back to the Flash file, CarRaceAsComponent.fla, go to the library symbol
02:51mcCarRace, right click on it or Ctrl+Click on the Mac and select Linkage. The
02:57name of the linked class as its known in Flex is flashcomps.flashCarRace and
03:03the base class is UIMovieClip. Change the base class to
03:07flashcomps.CarRaceClass. Make sure you exactly match the case of both the
03:13package and the class name, as you declared it earlier. If you want to make
03:17sure you typed it correctly, you can click the Edit button next to the base
03:21class name and in the background you should see the Flash ActionScript editor
03:25open and you should see the class. Click OK to save your changes, then go back
03:31to the Flash file CarRaceAsComponent.fla, select File, Publish and this will
03:38republish the SWF file and make the new class generation available to your Flex
03:43application. Go back to Flex Builder and let's make a change in the code that's
03:48calling the component. I am using the file UseFlashSWC.mxml which I modified in
03:54the previous video to instantiate the CarRace object.
03:59Go to the button labeled Replay, remove the call to the gotoAndPlay function
04:04and with the cursor right after the period press Ctrl+Space and start typing go
04:09and you should see the component's new custom method go available. Select it,
04:15save your changes and run the application. Wait for the initial animation to
04:22complete and then click the Replay button and you should see that you are still
04:27successfully restarting the animation. Right now all I am doing is adding
04:31additional layers of code, but the goal here is to be able to add real custom functionality.
04:37So, in the next video also you have to share custom information from the
04:41Flash-based Symbol component to the Flex application by dispatching custom events.
Collapse this transcript
Dispatching and handling Flash Component events
00:00In this video I'm going to describe how to dispatch custom events to share data
00:05from Flash symbols that you've exposed as Flex components, and then how to
00:09listen for and handle those events in a Flex application.
00:13The syntax will be exactly what you already know how to do in Flex and because
00:17both environments use ActionScript 3 as their programming language, there
00:21really aren't any major differences. The goal however is to show you that this
00:25a good way of integrating the components with the Flex application and working
00:30back and forth between the two environments.
00:32For this demonstration, I'll continue to use the files CarRaceAsComponent.fla
00:38which contains the visual symbol and animation, and CarRaceClass.as which is
00:43the custom ActionScript class that I created in the previous video.
00:47If you are following along with the exercises, you should first make sure that
00:50you have gone through those previous exercises so you have these files in this state.
00:55Let's start off in CarRaceClass.as. As in components that you build in the Flex
01:00environment, if you are going to dispatch custom events, you should declare
01:04ahead of time that those events are going to happen and you should indicate
01:08what kind of event object will be dispatched. You do this as in Flex with the
01:14event metadata tag.
01:15Now, because you are working in ActionScript rather than MXML, you don't wrap
01:20this in an mx metadata tag. You simply start with the event metadata tag above
01:25the class declaration.
01:26I'm going to be declaring two different events; one named Start and the other
01:30named Finish and I'll dispatch each event when the race begins and when it ends.
01:36Here is the first declaration. The event metadata tag will have a name of start
01:44and a type of the standard Flash event object, flash.events.Event.
01:51Now if you are working in the Flash ActionScript Editor as I am here, you have
01:55to add your import statement explicitly, unlike in Flex Builder it won't be
01:59added for you. So I'll place the cursor above the event declaration and add an
02:04import statement for flash.events.Event.
02:09Now I'm also going to add an event declaration for the finish event, and this
02:14one is going to use a class that's already in the framework named Text Event.
02:19The Text Event class is a standard event class that you can use to dispatch an
02:24event object containing a simple string value. I'll declare the event with the
02:28metadata tag, I'll give it a name of finish, and I'll set it's type to
02:34flash.events.TextEvent. Be careful to pay attention to the case sensitivity
02:41with an upper case T and an upper case E and then as before, I'll add the
02:46appropriate import statement, this time for flash.events.TextEvent.
02:52Now, whenever I explicitly restart the race, I'm going to dispatch the start
02:56event from this class. Move the cursor into the go method right after the
03:01gotoAndPlay call and add a new line of code and call the dispatch Event method
03:07and pass in a new Event object and in the call to the event class's constructor
03:12method pass in the name of the event you are dispatching, start.
03:17Save your changes, then go back to the Flash file and re-publish the document.
03:25Switch back to Flex Builder and if you don't already have it open, open the
03:29application file use FlashSWC.mxml if you are following along with the exercises.
03:36Now, we want to listen for the event that might occur. Go to the Flash
03:40CarRaceComponent, place the cursor after the y property setting and press the
03:45Spacebar. Start typing st and because you declare to the start event in the
03:52metadata tag you should see it in the list.
03:55Select the start tag and type in a call to the trace function and pass in a
04:00simple string of Race started. Save your change, restore your ActionScript
04:08Editor size so that you can see the Console view at the bottom, and then run
04:13the Flex application in Debug mode.
04:18Resize the Browser, so you can see the Flex Builder Console in the background
04:23and then click the application's Replay button and in the Console you should
04:28see the trace output Race started. So now you can see that you can actually
04:32listen for and handle events.
04:35Let's go one step further though. Let's go back to the application, first
04:39closing the Browser so you terminate the debugging session.
04:44We'll go back to the Flash document, and this time, I'm going to dispatch an
04:47event from code that's in the time-line. Now, for those developers who work a
04:52lot in Flash, you might be thinking, why would you put code in the time-line,
04:56isn't it better to put it in the ActionScript class itself? And my answer is,
05:00absolutely it is, but some developers do prefer to put the code in the
05:04time-line and what I show you that it is technically possible to dispatch
05:08events from any ActionScript code anywhere in the symbol.
05:12Go to the symbols actions layer, now if you don't see all these layers, make
05:16sure that you are in the mcCarRace symbol. Notice down here where I am pointing
05:20the cursor that I am editing the symbol and not the main document time-line. In
05:25the actions layer, locate the final frame, right or Ctrl+Click on the frame and
05:30select Actions. Currently the code in this frame only executes a stop method.
05:36We now want to also dispatch an event that tells the application not only that
05:41the Race is finished but who won. Move the call to the stop function down a
05:46couple of lines and then add an import statement for flash.events.TextEvent.
05:54Then move the cursor after the call to the stop function and you are going to
05:58execute the following code.
06:00First create an event object which I'll name here eventObj and data type it as
06:06a TextEvent class. Then instantiate it using a call to this TextEvent class's
06:13constructor method and pass in the name of the event that you want to dispatch
06:18which is finish.
06:21Next, pass in the string value that you want to send to the application, you'll
06:25put this into the text property of the TextEvent object. The code will look like this,
06:31eventObj.text = "Yellow car won!"
06:37Now in this application there isn't any suspense because the yellow car always
06:41wins, but in a more complete Flash symbol that had a lot of logic to it, you
06:45might be reporting a dynamic result.
06:48Finally dispatch the event. Call the dispatch event function and pass in
06:53eventObj. Save the changes to the ActionScript class and close the actions
06:59panel. Go back to the Flash file if it's not already active and re-publish.
07:06Now go back to Flex Builder and in Flex Builder you can now listen for the
07:10finish event and handle it in some fashion. Place the cursor above the
07:16Application Control Bar and add a Script section. Then create a function named
07:21finishHandler. Data type it's event argument as TextEvent and return void.
07:32Now, within the finishHandler function, use the alert class to display message
07:37to the user to tell them who won the race. The code will look like this, I'll
07:42type in the Alert class name and press Ctrl+Space and select the class that
07:47causes Flex Builder to add the import statement, then I'll select the show
07:51method and I'll pass into the show method event.text, then I'll pass into a
07:57second argument a little string value for the pop-up window's title.
08:03Now, go down to the FlashCarRaceComponent instance, move the cursor down a bit
08:08so are in new line and press Ctrl+Space to see the list of all available
08:12members of the component and start typing fi and you'll see the finish event
08:18exposed. Select it, call the finishHandler method and pass the event object.
08:24Save your changes and run the application and wait a moment till the
08:28application loads and the car gets to the end of the line and you should see
08:32that the event is dispatched and handled by the Flex application and the alert
08:37pop-up window is displayed showing the race results.
08:40So this demonstration represents a more complete integration between the Flash
08:44symbol as a Flex component and the overall Flex application. You can customize
08:50your Flex symbols as much as you want now, adding custom properties, custom
08:54methods and whatever logic and functionality you need, and then using the Flex
08:59Component Kit, you can expose that as a Flex component and use it in the Flex application.
Collapse this transcript
5. Working with XML and E4X
Using the ActionScript XML class
00:00In this chapter of the video series, I am going to describe how to work with
00:04XML formatted data using an aspect of the ActionScript 3 programming language
00:08known as E4X. E4X stands for ECMAScript for XML and it represents an aspect of
00:15the language that allows you to easily parse and extract data from XML objects
00:20and also modify those XML objects in application memory at runtime. E4X is
00:25similar in some respect to XPath, another XML expression language, but whereas
00:30XPath is used only to extract data from XML objects, you can use E4X, both to
00:35read and write the data in memory. It also worth mentioning before I get
00:39started with the demonstrations that like ActionScript itself, E4X is compiled
00:44part of the language and to demonstrate it properly, you have to compile the
00:49expression into your applications that you use to extract or modify the data.
00:53For the demonstrations in this chapter, I will use a flex project that's part
00:57of the exercises. If you are following along with the exercises, you can import
01:01the project now.
01:02From the Flex Builder menu, select File, Import, Flex Project. Click the Browse
01:09button next to Archive file and then select Chapter05BeginProject.zip. Import
01:16the project, go to the Flex navigator view and open the project, open its
01:21source folder and then open the application UsingXMLClasses.mxml. This
01:28application starts with an empty script section, an Application control bar
01:32that's docked that contains a couple of buttons with labels and a text area
01:37control that will be used to output the results of creating certain XML objects.
01:42There are two primary XMLClasses that we use in ActionScript to represent XML
01:47and data, they are called the XML and the XMLListClasses. There's also an older
01:53version of the XMLClasses known now as XML node and XML Document these are what
01:59we call the legacy XML Classes. And they represent functionality that was used
02:03in ActionScript 2 that could navigate and parse XML using document object style
02:08programming. The new versions of the classes XML and XMLList are compatible
02:13with the E4X language.
02:15The first thing I would like to show you is that there are a couple of
02:18different ways of creating XML objects in memory. An XML object is instance of
02:23an XMLClass and so one way to create an XML object is simply to hard code it or
02:29declare it directly in your ActionScript code. Then outside the function, I am
02:40going to create a variable and then data type it as XML. I will declare it as
02:45private, I will name it as xData, give it an XML data type and then I am going
02:52to initialize it within the init function. I am also going to mark the object
02:56as bindable so that I can use its information in binding expressions with
03:01visual controls.
03:02Now within the init function, create the XML object like this, xdata = and then
03:10on the next line you can code any XML structure you want. This is an XML
03:14object, not a string. So you don't wrap the XML content in quotes. I am going
03:20to create a root element called data, a sub element named row, and within the
03:28sub element I will create sub elements named firstname and lastname.
03:40Now I am going to copy this row to the clipboard and then paste it once, so I
03:48have two row elements. Then I will fill in the values. For the first row, I
03:54will use a first name of Joe and a last name Smith and then in the second row I
04:00will use a first name of Mary and a last name of Jones. So this is one way of
04:05creating an XML object in memory. You declare the object, if you want it to be
04:10bindable, you indicate it with the bindable metadata tag and then the data is
04:15available for use in your application.
04:17In this first example, I am going to display the content of the XML object
04:22using the text area control. I will go to the text area control and set its
04:26text property to a binding expression of xData.tostring. Finally I will go back
04:34up to the top of the application and add an application complete event listener
04:39and there I will call the init method.
04:41So here are the steps, I have declared the variable outside of any function, so
04:45I can get to it from anywhere in the application. Within the init function I
04:50have initialized the object using XML markup. If you like to make this very
04:55clear that it's a complete ActionScript statement, you can even add a semicolon
04:58at the end. Again this is an object that's being declared, not a string. In the
05:04text area control, I will display the text representation of the XML object
05:08using the expression xData.tostring. I will save the changes and run the
05:13application and you should see that the data is now displayed as XML in the
05:20text area control.
05:21Now in the next video, I will talk about another type of XML object called XML
05:25list which is a collection of XML notes.
Collapse this transcript
Extracting an XMLList with E4X
00:00In this video I am going to describe the use of an Action Script class named
00:04XML list. The nature of the XML list class is that it represents a collection
00:09of XML nodes. You can create an XML list object using hard coded ActionScript
00:15code as I did in the previous example using the XML class or more commonly, you
00:20create an XML list by extracting it from an XML object, using an E4X expression.
00:26For this demonstration, I will use the application using XMLlist.mxml, if you
00:32are following along with the exercises, you will find this application in the
00:35Chapter05BeginProject. This is the same application I worked on in the previous
00:41video. It declares a variable named xData, data typed as XML, then in the init
00:47function, it initializes that object using XML markup as part of an
00:52ActionScript statement. In this demonstration I am going to show you how to
00:57declare an XML list object and then extract a data for the XML list from the
01:02XML object using E4X.
01:05Create a new private function named getList, make it return void. Within the
01:13function declare a variable named xList data typed as XMLList. Then extract the
01:20value of that variable using the following syntax, start the expression with
01:25xData, the name of the XML object variable and then walk down to the repeating
01:31elements of the XML object, row. Notice that you don't refer to the root
01:36element data. When you are working with E4X expressions, the variable that
01:41refers to the XML content refers to the element already. So you wouldn't say
01:45xData.data.row, xDAta already represents the root element that is the data
01:51element. Next place of breakpoint on the final line of the getList function
01:57that is the line with the closing brace, then scroll down to the application
02:01control bar container and locate the button labeled getList, add a click event
02:06listener and call the new function getList. Run the application in Debug mode.
02:18When the application starts up, the xData object is initialized and its string
02:23representation is shown in the text area. Now click the getList button, that
02:28should trigger the breakpoint in Flex Builder. Go over the Flex Builder and if
02:32prompted to switch to the Flex Debugging perspective, click yes. Then go to the
02:37variables view and double click its tab. Here is the variable that was declared
02:41within the function xList. Take a look down at the bottom of the variables
02:45view. You may need to scroll upward to see all of its content, but you will see
02:49the complete set of row elements is represented.
02:55You can also go back up to the variables view and open the tree and you will
02:58see that the xList variable consist of multiple items, rows, each with an index
03:03number indicating that XML objects position within the list. So you can see
03:08that you have successfully extracted just the repeating rows and are now
03:11representing that data in an object in memory. Resize the variables view so you
03:17can see the other views and then terminate your Debugging session and return to
03:22the Flex Development perspective. Output the string representation of the
03:27XMLList to the text area control, like this, out.text = xlist.tostring. Save
03:38the changes and run the application this time in normal mode. When the
03:44application starts up, click the getList button and you should see that the
03:47text area control now displays the string representation of the list of XML
03:52objects rather than the entire XML objects.
03:55So that's your first simple introduction to the world of E4X. The E4X
04:00expression, xData.row, successfully retrieves and returns a list of XML nodes.
04:07You can represent that data in any variable that's data typed as XMLList,
04:12powerful E4X expression syntax that you can use.
Collapse this transcript
Retrieving XML in E4X format with HTTPService
00:00In this video, I am going to describe how to retrieve XML formatted text files
00:05and parse them in to a format that can be read with E4X. For this demonstration
00:09I will use an application named ImportWithHTTPservice.mxml. If you are
00:14following along with the exercises, you can open this file from the project.
00:19This version of the application has an empty init function. The controls at the
00:23bottom of the application, the Application control bar with the buttons and the
00:27text area are the same as in the previous application.
00:31In this application I am going to retrieve a file named invoices.xml that you
00:35will find in the data folder under the source code root. This file has a root
00:39element named invoices and repeating elements named invoice and then a mixture
00:45of customer and items element in each invoice. If you watched the Flex 3
00:50essential training video series, you learned that the HTTPservice control is
00:55able to retrieve XML formatted data, parse it and return the data in a format
01:00that you can use in your ActionScript code. In that video series, I used the
01:04HTTPservice element to retrieve data as a set of objects, that is, an object
01:10tree that contained a mixture of objects and array collections.
01:14In this video I am going to show you how to retrieve the data and instead
01:17return it as a true XML object that's compatible with E4X. Place the cursor
01:23after the script section and create an HTTPservice object, give it an ID of XML
01:30service and a URL pointing to the location of the XML file, data/invoices.xml.
01:39Add a result event handler and call a function that you will need to create
01:43named result handler and pass the event object. Next go to the script section
01:50and create that function, name it result handler, set it up to receive a single
01:56event argument, data typed as the result event class and return void.
02:03Make sure at the top of the script section, that Flex Builder added the
02:06required Import statement for the result event class. Now place the cursor
02:11inside the init method and send the request for the HTTP service using the
02:15syntax xmlService.send. Place a breakpoint on the last line of the
02:22resultHandler function, that's the line with the closing brace, then run the
02:27application in Debug mode. When you hit the breakpoint and the application is
02:31suspended, if Flex Builder prompts you to go to the Flex Debugging perspective,
02:35click yes. Then go to the variables view.
02:39In the variables view, navigate to the event.result object. The default
02:44behavior of the HTTPservice component is to parse and return the data as a set
02:48of objects. The top level node or the root element of the XML is returned as an
02:53object wrapped inside a class called ObjectProxy and then within that data
02:59structure, you will find that any element that only occurs once within any
03:03particular level of the XML hierarchy, it's returned once again as an
03:07ObjectProxy.
03:08But any element that occurs at least twice such as the invoice element is
03:13returned as an array collection. This is what we call the object structure of
03:17XML and well the object structure can be useful in certain circumstances, in
03:23many cases, you are going to instead want to return the data as true XML. So
03:27let's terminate the Debugging section. Go to the Debug view or the console view
03:31and click the red terminate button, return to the Flex Development Perspective
03:37and go back down to the declaration of the HTTPservice object.
03:41In order to return the data as a true XML object, set the HTTPservice
03:46components result format property to a value of E4X, save the changes and run
03:52the application in Debug mode again. When you hit the break point, once again
03:57go into the Flex Debugging perspective, take a look at the variables view and
04:02look at event.result. This time it comes back as a true XML object and as I
04:08showed in a previous video, if an object is data typed as pure XML, it's
04:13compatible with E4X expressions. So restore the size of the variables view and
04:17once again terminate the Debugging session. Go back to the Development
04:22perspective, place the cursor inside the resultHandler function and now you are
04:27going to save the results that are returned from the HTTPservice request to the
04:32pre-declared xData variable which has been marked as bindable and data typed as XML.
04:38With the cursor inside result handler add this code, xData = event.result as
04:46XML. The compiler doesn't know that event.result will be returned as an XML
04:50object. It expects a generic ActionScript object, so the 'as' operator
04:55explicitly declares that this will be an XML object and from this point on
05:00everything should bind together correctly. Save your changes and run the
05:03application again, this time in normal mode, not Debug and as the application
05:08starts up, it loads the data, retrieves it and then due to the binding
05:13expression in the text area control, the string representation of the XML
05:17object is displayed. Go back to the code and take a look at the getList function.
05:23In this version of the getList function, the E4X expression that's retrieving
05:27data is xData.invoice. And once again we are walking down directly from the
05:32root element to the repeating elements and because there are at least two of
05:37them, they are returned as an XML list. Run the application again, once again
05:42see that the full XML content is returned and displayed and now click the
05:47getList button. And you will see that you are retrieving now only the list of
05:50XML objects, multiple invoices.
05:54So that's how you use the HTTPservice component to retrieve an XML file and
05:59represent it in Flex application memory a true XML object that's compatible with E4X.
Collapse this transcript
Modifying XML data with E4X
00:00In this video I am going to give a brief demo of how to modify XML formated
00:04data in application memory in Flex, using an E4X expression. For this
00:09demonstration, I use the application file ModifyXMLData.mxml. This is the same
00:16application I had been working on in the previous videos. It now retrieves data
00:20using the HTTP service component, and saves it as an XML object that's
00:25compatible with the E4X language. In the previous video, I showed how to save
00:29the datas in XML object, using the Result Event Handler of HTTP service
00:33component, and then how to extract data, using a simple E4X expression. In this
00:39case, this expression was extract in data. In this video I am going to show you
00:43how to use a simple E4X expression to change the data.
00:47Create a new private function in the script section of the application. Name it
00:52changeData. Return void, and then within the function, modify the text value of
01:00the first name element of the first customer in the first invoice. Here's how
01:05the syntax works. I will start off with xData, (that's the name of the XML
01:10object .invoice) xData.invoice and then I will use a ray style syntax to
01:15indicate that I want to address the first invoice element in the external data
01:19object. Then refer to the first customer in the first invoice, using similar
01:23syntax. I am now referring to the first customer in the first invoice.
01:29Finally, refer to the firstname element of that customer, and change the value
01:35of that elements text note, using any literal strength. I will pass in a value
01:40of "Michael". Then to see the result, output the string representation of the
01:45first invoice. As before, use the text area control with an id, and set its
01:51value using the expression xData.invoice 0.toString.
02:00 Go down to the ApplicationControlBar to the button with a label of "Change Data," and add a
02:05quick event listener, and handle the event by calling the new "changeData"
02:09function. Run the application. When the application first starts up, it loads
02:16the external formated file using the HTTPservice component and delivers it as
02:21an XML object. The text area control using it's binding expression displays the
02:26string representation of the XML.
02:29Click the Change Data button, and you will that the first invoice, first
02:33customer, firstname element has been successfully modified to a value of
02:37Michael. So that's a look at a simple E4X expression that modifies data. Now in
02:43the next couple of videos I will go through a whole set of example expressions,
02:46that you can try out in your own applications, and show you what their results
02:50are. So you can see some of the flexibility of E4X expression syntax.
Collapse this transcript
E4X expressions for parsing data
00:00In this video I am going to describe the variety of operators and other
00:04expression elements you can use in E4X to extract data from an XML object. For
00:10this demonstration, I'll use two files. The application is named
00:14E4XParsing.mxml. If you are following along with the exercises you can open it now.
00:20This component uses an ActionScript class, named E4XParsingHelper. This
00:25ActionScript class has two static functions named getExpressions and evalE4X.
00:30The getExpressions function returns an array collection of strings. These are
00:35simple labels that will be used to display to the user which expression is being evaluated.
00:40The evalE4X static function actually executes each E4X expression. If you want
00:46to add new expressions to this sample application, or change any of the
00:50expressions to see what happens, you would modify the element both in the
00:53getExpressions method and in the evalE4X method.
00:56For example, the first label that's returned in the array collection
01:01xInvoices.invoice matches the expression that's returned in the function
01:06evalE4X. Now we'll go back to the application and run it.
01:11When you run the application, it displays the XML that's being searched on the
01:15left, in the top left corner and then a set of possible E4X expressions and
01:20again these values are being retrieved from the helper class's static method. I
01:24am going to go through each of these expressions, talk about what they do and
01:28then show you the result.
01:30As I described in a previous video, the simplest of E4X extraction expressions
01:35start with the root element represented by the XML object itself, in this case
01:40xInvoices. When you use a single dot, that's called the child accessor operator
01:46and it means that you are walking down to the named element. xInvoices.invoice
01:50means go get the invoice elements, that are direct children of the root element.
01:56I'll click on that expression and in the right result pane, you'll the
02:00returned XML consisting of all invoice elements. When you are dealing with
02:04elements that repeat, that is, where there is more than one element of the same
02:08name in that position, you can use array syntax to indicate which one item you
02:13want to retrieve.
02:14The expression xInvoices.invoice 1 means retrieve the second invoice element
02:21within the root element, as with all the arrays and other indexing in
02:25ActionScript, indexing starts at zero. So an index position of 1 means give me
02:30the second item.
02:32The next example is this extended dot syntax to walk down the XML tree a little
02:36bit further. xInvoices.invoice 0 means the first invoice, .customer means give
02:42me the customer element within that invoice. If you take a look at the actual
02:47XML that we are searching, you'll see that the invoice only has one customer
02:51and that's what's being returned.
02:53The next example uses the descendant accessor operator. The .. operator means
02:59go down to this named element, wherever it is in the XML hierarchy. It does a
03:04deep search of the XML structure, so if you know which element you want by name
03:08and you know that it won't be repeated in any other level of the XML hierarchy,
03:13you don't have to walk down one element at a time.
03:15Xinvoices. that customer means give me all the elements named customer anywhere
03:20in the XML hierarchy regardless of level. The next example uses a predicate
03:25expression. A predicate is like a filter or a query, it's a way of saying
03:30return this element by name but only where it's particular sub- element or
03:35aptitude equals a particular value.
03:37In this example we are saying, give me all customer elements where the last
03:42name of sub-element has a text value of 'Jones'. And in the result you see that
03:47that's what returned. You can also return a particular element that only has a
03:51text note by using it's toString method.
03:53Here we are saying, give me all line items, where the string node, that is the
03:58text node of the element equals a value of 'Mouse' and this expression returns
04:04two line items in the result panel. Using predicate expressions you can also
04:08compare values to attributes. In order to refer to an attribute, rather than an
04:13element by name, use the @ character as a prefix. So this expression means,
04:18give me all line items where their price attributes are less than eight.
04:22If you are working with numeric values, as you are here, you can indicate
04:26whether you are doing a numeric or a string comparison by the presence or
04:30absence of quotes around the value. In this example that's highlighted, the
04:34number eight doesn't have quotes. So this is a numeric evaluation. I am asking
04:38for all items where the price attribute is less than eight numerically and I
04:43get these three items back, where the price is less than eight.
04:47But if you wrap the number eight with quotes, then you are saying that it's a
04:51string evaluation and now you are comparing the value of each price attribute
04:56to this string eight. And notice that you also now get back a line item element
05:00where the price is 21.41, it's more than eight numerically but it starts with a
05:06value of less than eight in terms of string values.
05:09So these were the various operators that you can use in E4X expressions. If you
05:14compare this to the kind of code you would have to write in old style document
05:18object model code, you can see that you can extract data with very simple, very
05:23concise expressions that might otherwise take five or ten lines of ActionScript
05:28code to execute.
05:29Now in the next video, I'll show you some other examples of this kind of E4X
05:34expression but this time modifying data in the XML structure.
Collapse this transcript
E4X expressions for modifying data
00:00In this video I am going to describe various methods you can use to modify XML
00:05data at runtime using E4X expressions. For these demonstrations, I will use an
00:10application named E4XChanging.mxml and it's associated ActionScript helper
00:15class which you will find in the helpers folder named E4XChangingHelper.as.
00:22Let's talk about the application first, when you first start the application up
00:26it retrieves an XML file and then displays its string representation on the
00:31right side. You will see that it's the same XML file I used in the previous
00:35exercise. This time the goal is to modify the data in memory and then display
00:40the results in this panel. Now let's go back to the code, whenever the user
00:45selects an item from the list of available expressions, this evaluate function
00:50is called from the application.
00:52The first step at line 38 is to make a copy of the existing XML data object.
00:58The XML class has a method named copy which results in cloning the XML object
01:04so that the new version is completely detached from the old one. This allows us
01:08to make changes to the new version without disrupting or disturbing the old
01:12data. So this copy of the data is named tempXML. The next step is to make a
01:17call to a static method of the helper class named evalE4X which passes in the
01:23index of the selected expression. In this function we will receive the
01:27temporary XML object as an argument and the index, we evaluate the index and
01:33then we modify that XML data object and then return.
01:38The XML data object which is being modified by reference is then displayed as a
01:42string representation in the text area control. Let's take a look at the first
01:47example in action; once again as the application starts up we display the
01:51string representation of the original XML and heres the first expression, very
01:56similar to the one that I demonstrated earlier. In this expression, I am
02:00changing the value of the firstname element of the customer in the first
02:04invoice. Right now that customer is Maria Smith; let's see what happens when I
02:10click on the first expression. The result is that the firstname element has been changed.
02:16Each time you make a change, you can go back to the original by clicking this
02:19button at the bottom labeled Show Original and you will go back to the original
02:23data and you will be ready for the next example. In the next expression we are
02:28doing something very similar to the first, we are modifying a particular value
02:32but this time we are changing the value of an attribute rather than an element.
02:36The syntax lineitem 0 .@price means change the value of the price attribute in
02:43the first lineitem, that lineitem is currently 21.41. I will select the element
02:50and the result is to change the price to 12.5.
02:55Now notice that even though in the expression, I said price equals 12.50, this
03:00was truncated down to 12.5 and this is because the numeric value is evaluated
03:06as a number. If you want to retain the full string, you should wrap the value
03:11with quotes as in the next example. This expression is saying change the price
03:16attribute of the first lineitem to a string of 12.50 and there is the result.
03:23So, once again as I showed in the previous video, when you modify data the
03:28quotes have meaning, if you wrap quotes around a numeric value that means you
03:32are treating it as a string and if you eliminate the quotes, that means you are
03:35treating it as a number. You can also use an E4X command or expression to add elements.
03:41Let's go back to the original XML data by clicking the Show Original button and
03:46I will show you that the customer element has elements of firstname and
03:50lastname. You can add an element any time you want by pretending it already
03:55exists in your E4X expression. The fourth expression in the list says the
04:00customer.city element of the first invoice equals Seattle. Notice the use of
04:05the single equal's operator, this is the assignment operator in ActionScript
04:09rather than the quality operator and if that element doesn't exist, running
04:14this expression will create it. I will select the expression and then show you
04:18in the XML data that results that the city element has been created and then
04:24once again I will go back to the original. You can do the same thing with attributes.
04:28In the fifth expression in the list, we are saying set the value of the inStock
04:33attribute to a value of true. If you go to the first lineitem you will see that
04:37it doesn't have an inStock attribute but by selecting that expression, the
04:42attribute is added. So you can add elements and attributes using E4X
04:47expressions by simply pretending they already exist and setting their values.
04:52The last three expressions in the list use an operator named delete; you can
04:56use the delete operator to remove whole elements or attributes of elements from
05:01the XML content. Lets once again go back to the original and then select the
05:06first delete expression; this says delete xInvoices.invoice 1 . Remembering
05:13that all indexing starts at 0, this means in English remove or delete the
05:17second invoice. I will click the expression and the second invoice is removed
05:23from the XML structure.
05:24Notice that the remaining XML structure is well formed and intact, so there is
05:29an intelligent parsing of the XML structure and then the particular node that
05:33you refer to is removed. Once again I will go back to the original and this
05:39time I am going to delete a number of items, this syntax delete
05:43xInvoices.invoice 0 , the first invoice .items.lineitem refers to all elements
05:51named lineitem within that particular items parent element. I will select the
05:55expression and you will see that the items element is now empty. So this allows
06:00you to remove more than one element at the same time if they all match in some
06:05fashion, in this case by the element name.
06:08Finally going back to the original one more time, you can also delete a
06:11particular attribute from an XML structure by using the delete operator and
06:16then in the expression referring to the particular attribute you want to
06:19remove. This one says remove the quantity attribute from the first lineitem in
06:25the items element, in the first invoice; that would be this value of quantity
06:30equals 4 and let's see if it works. I will select the expression and the
06:35attribute is deleted.
06:37So these are various methods that you can use to modify XML data in application
06:41memory at run-time. You can use E4X for extracting data as I showed earlier and
06:47you can also it to manage or modify the data whenever you want and then if you
06:52want to save the data, say to a file or push it into a database you can always
06:56use the XML classes to string method to get the string representation of that
07:01XML object for saving in some format.
Collapse this transcript
Using XML namespaces with E4X
00:00In this video, I am going to describe how to use XML namespace objects to
00:04distinguish between elements that have the same name in an XML structure. For
00:09this demonstration, I will use the application E4XWithNamespaces.mxml. If you
00:15are following along with the exercises, you can open this now in Flex Builder;
00:18take a look at the script section of this file. There is a variable declaration
00:23right in the script section outside of any functions, the name of the variable
00:26is xTravel, its data type is an XML object and it has a root element named
00:31travel and within the root elements begin tag there are three names based
00:36declarations.
00:37The actual URIs that is the namespace strings are unimportant here, what's
00:42really important to us is the XML prefixes. Each of these prefixes identifies a
00:47particular a namespace or a particular group of elements that can be
00:52distinguished from each other and then within the journey element there are
00:56three travel time elements that use those namespaces. There is a
01:00train:traveltime, a plane:traveltime and a car:traveltime and they each have
01:06three different values. When you are parsing XML that uses namespaces you have
01:10to know how to use a namespace object to qualify your search and distinguish
01:15between elements of the same name.
01:18At the bottom of the application there is a set of RadioButtons grouped within
01:21a panel. When the user clicks on one of the RadioButtons, the itemClick event
01:26handler of the RadioButtonGroup control calls the getTravelTime method. Here we
01:31extract the value of the RadioButton that was clicked and save it in this
01:35vehicle variable. Our job is to use that value and XML namespaces to do a
01:41qualified search for a value based on a combination of namespace and element name.
01:46Here are the steps; first I am going to declare one namespace object for each
01:52XML namespace prefix that I want to use in my searches. For each one I will
01:57declare a variable, I will start off with private var and then give the
02:02variable a name, I will call the first one trainNS for namespace and I will
02:08data type it as a namespace object. I will initialize it using this syntax, I
02:13will start with xTravel which is the name of the variable referencing the XML
02:17object and then I will call its namespace function and I will pass in the
02:22prefix that I want to associate this namespace object with as a string.
02:29Notice that the XML namespace as a string here matches the prefix in the actual
02:34XML declaration. Now I am going to clone that line of code a couple of times
02:39and I will change the namespace object name and the namespace prefix as a
02:44string so that they match up. The second one will be for the plane namespace
02:49and the plane prefix and the third will be for the car namespace and the car
02:55prefix. I now have one namespace object for each of the namespace prefixes
03:01declared in the XML file. Now I am ready to do a search, go to the
03:06getTravelTime function and place the cursor after the declaration of the
03:10vehicle variable.
03:11The next step is to create a switch statement that evaluates the vehicle
03:16variable and then looks at three possible cases. The first one is for the value
03:22of plane, the second for the value of train and the third for the value of car.
03:30Let's go to the first case, I am going to use the planeNS namespace object to
03:35qualify my search for the traveltime element in the XML content and then I am
03:40going to save the results of my search to the pre-declared variable result
03:44string. This value is being displayed through a binding expression in the
03:48panel; going back to the code I will place the cursor after the case
03:51declaration and I will set the value of the resultString variable using this
03:56E4X expression.
03:57I will start off with the xTravel variable name that represents the root
04:01element of the XML content. Then I will walk down to the journey element,
04:06that's its child element and then I will use the namespace object to qualify my
04:10search. I am looking for a planeNS::traveltime. Now make sure that you match
04:19the element name here traveltime to the name of the element as it's declared in
04:23the XML content. This is very highly case sensitive and you got to get it
04:27right. The double colon operator is used to qualify the element name; so in
04:33English we are saying give me the value of the traveltime element that's a
04:37member of this namespace object and this namespace object in turn is associated
04:43with the train namespace string as it's declared in the call to the namespace function.
04:49After that command, add a break command so you don't continue through and
04:52execute the rest of the switch statement. Then copy and paste these two lines
04:58and paste them after each case, then go back to each of those commands and
05:05change the namespace that we are using to qualify your search; for the second
05:09one use trainNS and for the third one use carNS. So that's all with the code,
05:17when the user selects a particular value through the RadioButtonGroup, you will
05:21evaluate what they selected and then use the appropriate namespace object to
05:26qualify your E4X expression.
05:28Run the application, notice that the initial return string has a value of
05:33Choose a vehicle and you should now be able to click on any particular
05:37RadioButton and you will be doing qualified E4X search of the XML data. So
05:43that's a look at how to use namespaces in E4X expressions. The most critical
05:48parts to remember are the double colon operator, that's used to separate the
05:51namespace object from the element name you are looking for. The use of
05:56namespace objects to hold that information and the use of the XML objects
06:01namespace function to initialize the namespace object and associate it with a
06:05particular namespace prefix. Using these tools you will be able to navigate and
06:10extract data from any XML file, no matter how complex.
Collapse this transcript
6. Using the Tree and MenuBar Controls
Using the Tree control with XML data
00:00In this chapter of the video series I am going to describe the use of Tree and
00:04MenuBar controls. These are visual controls in the Flex class library that
00:09distinguish themselves from other list style controls that you might use, such
00:13as the data grid, list, horizontal list and tile list. Those controls which I
00:18described in some detail in the Flex 3 Essential training video series use data
00:23that you might get from an SQL statement from a database. That sort of data is
00:28stored in rows and columns and presented in the DataGrid or other styles of lists.
00:34The Tree and the MenuBar controls in contrast use hierarchical data that's
00:39typically stored as XML. Now in the previous chapter of this video series, I
00:44described how to work with XML using the E4X aspect of the ActionScript
00:48language and we will be combining those skills, that is, the ability to extract
00:52data from XML using E4X with a look at the visual controls that use that sort
00:57of data. For the demonstrations in this chapter, I will be using a Flex Project
01:02from the Exercises folder. If you are following along with the exercises you
01:06can import it now. From the Flex Builder menu select File, Import, Flex
01:13Project, click the Browse button next to Archive file, navigate to the
01:18Chapter06 folder under Exercises and select the file Chapter06BeginProject.zip.
01:26Import the project, go the Flex Navigator view and open the project, open its
01:32source folder and then open the application file UseTreeControl.mxml. I run the
01:41application so we can see its initial presentation. This application has two
01:46empty panels shown side by side, the first has a title of Photos by Location
01:53and the second has a title of Photo Detail. Our job will be to fill these
01:57panels in with other visual controls. By the time these exercise are done, we
02:02will have a treecontrol in the first panel and a detail presentation of
02:07selected data from the treecontrol in the right panel. I will go back to the
02:11source code, notice this application already has an HTTPService component
02:17declared, it has a URL attribute that's pointing to a file called
02:20slideshow.xml, a result event listener that's calling a method called
02:25resultHandler passed in the event object and its result format property is set
02:30to e4x.
02:32Go to the resultHandler function and add a break point on the last line, that
02:36is, the line with the closing brace. Then run the application in Debug mode, as
02:43the application starts up, it retrieves the XML content and if you are prompted
02:47to switch to the Flex Debugging perspective, click
02:50Yes. Then in the Flex Debugging perspective, go to the Variables view and
02:56inspect the event objects result property and as I showed in the previous
03:00chapter of this video series, because the result format property of the
03:04HTTPService control is set to e4x, we will receive a true XML object that can
03:10be parsed using E4X expressions. Restore the Variables view to its original
03:16size and terminate your Debugging session.
03:19Then go back to the Flex Development perspective, here are the tasks I am going
03:25to accomplish in this application. First, I am going to declare a variable
03:29that's bindable, data type is an XML list. You can use either an XML object, an
03:36XML list or another kind of object called an XML list collection as the data
03:41provider for a Tree or a MenuBar control. Typically you make these data objects
03:46bindable just as you might within a ray collection for a DataGrid. So I will
03:50place the cursor above the resultHandler function and add a [Bindable] metadata
03:54tag and then I will declare a private variable and I will name it xLocations,
04:01data typed as XMLList. Now go down to the resultHandler function and fill in
04:08the value of that variable using the following syntax, xLocations =
04:14event.result, that expression points to the root element of the XML document
04:20and then we will walk down to the repeating element which is named location.
04:25This xLocations variable now contains the data that I would like to display in
04:28the Tree control. Now go down to the Panel that has an id of locationPanel,
04:35make a little bit of space between the panel tags and declare a Tree control.
04:41Give it an id of locationTree and set its dataProvider property using a binding
04:47expression to the xLocations variable that you just declared and filled in.
04:55Make the Tree expand to fill the entire panel, set its width and height
04:59properties to 100% each. Save your changes and run the application now, you
05:09will see that the Tree control is created but the display isn't quite what you
05:14want. Notice that each node of the Tree displays all of the XML for that
05:20particular location node, without further instruction the Tree control doesn't
05:25know how to break down the XML content and extract the appropriate label for each node.
05:30So that will be the next step; close the application and then take a look at
05:36the XML file that we are using, it's in the data folder and its name is
05:40slideshow.xml. Notice that this XML file structure has been designed so that
05:47each element that's going to represent a node in the Tree has an attribute with
05:51the same name; I have named it label here. You must provide this information to
05:57the Tree control so that it knows how to extract and present the label for each
06:01node. Go back to the UseTreeControl.mxml file and add one more attribute to the
06:07Tree. The name of the attribute will be labelField and the value will be an E4X
06:14expression of @label.
06:17As I described in the E4X chapter, the @ character before an identifier means
06:23look for an attribute name rather than an element name. Save your changes and
06:28run the application. Now the Tree control is doing what we want, there is one
06:34node for each item in the XML list that was retrieved from the XML object and
06:39within each of those nodes there are child nodes that represent the different
06:43photos that we would like to display.
06:46So that's a look how to create a basic Tree control and associate it with
06:49hierarchical data in XML format. Now in the rest of the videos of this chapter,
06:54I will show you how to do a few more advanced things with the Tree control
06:57including how to re-skin it, that is how to provide replacement graphics for
07:01these folder and document graphics you see by default and also we will apply
07:06these principles to the MenuBar control.
Collapse this transcript
Controlling leaf and branch labels
00:00In this video, I am going to describe the use of a special feature of the Tree
00:04control that allows you to dynamically determine the label that's applied to
00:08each node of the Tree. I will be using a property called labelFunction. The
00:13architecture of the labelFunction property for the Tree control is very similar
00:17to that for the DataGrid and other list type controls. But you will see that
00:22the kind of data that's passed into the labelFunction is a bit different. You
00:26create a labelFunction so that it will be called each time a node of the Tree
00:30control is rendered.
00:31For this demonstration, I will use an application named ControllingLabels.mxml.
00:37If you are following along with the exercises you can open this file now. This
00:42is the same application that I was just working on in the previous video. The
00:46Tree control is inside a panel and it has a labelField property that uses an
00:52E4X expression to indicate what value should be displayed as the label for each
00:56node of the Tree. I am going to replace the labelField property with a
01:00labelFunction. To get started, go to the Script section and create a new
01:06private function named getTreeLabel. When you use the labelFunction property,
01:13each time the Tree control renders a node; it will call this function and pass
01:18in the underlying XML object that's being used for that node. So when the
01:24function is called a single argument will be passed in; you can name it
01:28anything you want but its data type should be XML and the return data type of
01:33the labelFunction should always be String.
01:38Here's the effect I would like to achieve, if the current node is a location
01:42node I want to uppercase its label but if the current node is a photo node,
01:48that is, a child of the location I want to return the label in its original
01:52form. So in this next step I am going to use a function of the XML object
01:57called name which returns the name of the current element. The code will look
02:02like this, if (item.name() has a value of location and then put in a pair of
02:11braces and then I am going to return the label attributes value at uppercase
02:16like this, return item.@label.toUppercase. Put in an else clause and in the
02:30else clause we are going to assume that instead of the location we got a child
02:33element or the photo and so here we will return the item label intact.
02:40Now go down to the Tree control within the panel, remove the labelField
02:45property, we are not going to use that anymore and instead put in a
02:49labelFunction. You pass in the name of the function that you want to call; you
02:57are not actually calling the function at this point, you are just passing a
03:01reference to it to the Tree control and then it's up to the Tree control to
03:05actually call the function whenever it's needed. So I will pass in the name of
03:09the function which I named getTreeLabel; make sure you spell this correctly, it
03:16is highly case sensitive. Save your changes and run the application and this
03:22time when you present the Tree control you should see that the locations are
03:26uppercased but the labels for the child nodes that is for the photos, are their
03:31original mixed case. So you can see that the labelFunction is working.
03:36Now whenever you use a labelFunction, it's sometimes instructive just to put a
03:40trace statement and then see how often it's being called. So I am going to go
03:44back to the function getTreeLabel and I am going to add a trace statement and
03:49each time the function is called I am going to output a value to the Flex
03:52Builder console. It will be concatenated string that starts off with a literal
03:56value of Formatting and then we will output item.@label. Save your changes and
04:05this time run the application in Debug mode.
04:09As the application starts up and starts rendering the various nodes of the
04:13Tree, in the console in Flex Builder, in the background you should see the
04:18trace output happening. Now open one of the parent nodes and you should see the
04:24trace method happening again; close the node and you will see it happening
04:28again, open and so on.
04:31So what you will see is that this function is being called a lot. The guideline
04:35for a labelFunction is very simple, keep it short, don't do anything complex in
04:41the labelFunction, keep it to just one or two lines of very simple, very
04:45concise code that gets the data, formats it and returns it as a string and this
04:51allows you to customize the appearance of your Tree control and the labels that
04:55it uses for its various nodes.
Collapse this transcript
Using graphical skins with Tree controls
00:00In this video, I'm going to describe the use of custom graphical skins that you
00:04can use to replace the default folder and document graphics that are used in a
00:08Tree Control. For this demonstration, I'll use an application named
00:12TreeSkins.mxml.
00:14This is the same application I've been working on in the previous videos. It
00:19currently opens the XML file, retrieves data and applies it as the data
00:24provider for a Tree Control. Let's take another close look at the Tree Control.
00:30When you first create a Tree Control, regardless of whatever kind of data
00:33you're actually displaying, the branches that's the parents nodes, that have
00:37child nodes display folders.
00:40There are two graphics associated with each parent note, a Closed folder and an
00:45Open folder and then the child nodes knows as Leaves display a document. Now,
00:52if your data doesn't consists of folders and documents, you can create your own
00:56custom graphics and apply them as graphical skins. I've already created a few
01:01skins that we can try out.
01:03I've placed them in the Skins folder under the Source Root. I'm going to open
01:08one of them now in Fireworks. Notice that the graphical skin is very small.
01:14I've created my graphical skins for the Tree Control using dimensions of 16
01:18pixel square. Notice that Fireworks shows you the size of the graphic that's
01:23currently displaying.
01:24I've created two icons for the folder, one for its open state and one for its
01:29closed stated and then I've also created icon for the leaf that's for each
01:34photo. That's again that same size, 16 pixelsx16 pixels. So, I'm going to close
01:41Fireworks and go back to the code. In order to use a graphical skin, you create
01:47Style Embedding code.
01:49Now, you can create this code yourself or as I showed you in the previous
01:53chapter, you can use flexible import capability to generate the required style
01:59code. I'm going to do the latter. I'll go to the Menu and select File, Import,
02:06Skin Artwork. Now, when I demonstrated this capability in an earlier chapter, I
02:12was working from a SWC file generated in Flash.
02:15This time, I'm working from a set of Bitmap images that are in a simple folder.
02:20So, I select the option Import Skins from folder or images. Then you'll
02:25navigate to the Skins folder under the Source Root of the current project,
02:29which I've already selected. Down at the bottom of the Wizard, you set the
02:34option for how you want to create the skins style roots.
02:37You always create them in an external Style Sheet and here I'm creating a new
02:42Style Sheet file named skins.css. I'm going to apply the styles to the
02:47application TreeSkins.mxml. Click Next, so there are three graphic files in the
02:55selected folder. I'm going to check them all by clicking the Check All button
03:01and then I need to indicate explicitly what kind of Style Selector I'm going to
03:05use and what aspect of that Style Selector I'm going to apply the skin to.
03:10Let's start with the icon_location_closed_gif file. Set the Style Selector to
03:16Tree, make sure that you spelled correctly with an uppercase T, then pull down
03:21the list of available parts of skins and you'll the various icons that are part
03:27of the Tree Control displayed. Select folderClosedIcon.
03:29Now, repeat these steps for each of the other images. Set the Style Selector to
03:37Tree, pull down the list and for the icon_location_open.gif file, select
03:44folderOpenIcon and once again, for the third one set Style Selector to Tree and
03:51the skin part for this one will be defaultLeafIcon.
03:55That's it, click the Finish button and Flex Builder will take the following
04:00steps. First of all, it creates a new file called skins.css, let's take a look
04:06at the code generated. For each icon skin, it embeds the graphic as a part of
04:12the application using the Embed Compiler Directive. The source actually points
04:16at the actual location of the graphic file.
04:20Then in the application file, ThreeSkins.mxml, you find at the bottom of the
04:25application a new style tack has been created with the source attribute. Now,
04:30my preferences to put my style declarations up at the top, so I'm going to cut
04:34that declaration to the clipboard, then go back up toward the top of the
04:39application and I always place my style declarations after my script section.
04:44That's just the convention I typically follow, then I'll save the changes and
04:49run the application. You should see that the different nodes for each location
04:56display the Folder Closed icon, open the icon and you'll see that it switches
05:02to the open graphic which has the little lights on and the buildings and each
05:07of the photo nodes is displaying the appropriate graphic for that node.
05:11So, that's a look at how to reskin a Tree Control, how to provide custom
05:16graphics that represent the type of data that you're representing in the tree
05:20rather than the document and photo graphics that the Tree Control uses by default.
Collapse this transcript
Handling Tree events
00:00In this video, I'm going to describe the use of events that are dispatched by
00:04the Tree Control as these are navigates and selects nodes from between. For
00:09this demonstration, I'll use an application named TreeEvents.mxml, this is the
00:15same application I've been working on throughout this chapter.
00:18I'm representing XML formatted data in a visual Tree Control which allows the
00:22users to select from any level of the XML and I've already implemented the
00:26custom skinning graphics that represent the different nodes. Now, when the user
00:33selects any item from a Tree Control, you'll get an event named Change.
00:37When the Change event occurs, you can react by getting a reference to the
00:41underlying data of the Tree selected node. Then you can use that data and
00:45represent it visually, store it or do anything else you want. I'm going to
00:49start this demonstration by creating a new bindable variable.
00:53If you're following along in the exercises, you can open TreeEvents.mxml and
00:57add a new bindable variable within the script section named xPhoto. This is
01:03going to contain a reference to the currently selected XML node for the
01:07currently selected visual node of the Tree. Data type it as XML.
01:12Now, the next step is to create an Event Handler function. As I mentioned, the
01:17event is going to be dispatched when the user selects a node is named Change.
01:22Create a new private function named changeHandler and data type its event
01:28argument as ListEvent and as with all Event Handler functions, we turn void.
01:36Now, the next step within the Event Handler function is to get a reference to
01:40the currently selected XML node. Declare a new variable named selectedXML, data
01:46typed as XML and get its reference using this expression, event.target which
01:53currently references the Tree Control, .selectedItem as XML.
02:00Now, before I go any further with the code of this function, going to do a
02:03little bit debugging and tracing, so I can see what kind of node is being
02:07selected. Add a call to the trace function and add a literal string of "You
02:13selected a" close the quote, add a concatenation operator, a + and then trace
02:20the name of the currently selected node, selectedXML.name.
02:26Now, go down to the Tree Control within the first panel, add an attribute based
02:30change Event Listener and call the changeHandler function passing an event
02:35object. Now, you're ready to do a little bit of debugging and tracing. Save and
02:41run the application in debug mode, arrange your browser window that's
02:45displaying the application so that you can also see the counsel in the background.
02:50Then go to the tree and click on one of the parent nodes. You should see the
02:53counsel show a traced output of You selected a location. Now, open that node
02:59and select one of its child objects and you should see the trace output, You
03:03selected a photo. Each time you select another photo node, you should see the
03:07same message and if you go back to the parent node, you should see the output,
03:12You selected a location.
03:14So, now you know that you're correctly detecting whether you're on the location
03:18or the photo element. Now, the next step is to put in a conditional clause that
03:23decides whether to save the selected XML object as xPhoto and you're only going
03:28to do that if in fact, you got a photo from what the user selected.
03:32So, add a conditional clause after the trace statement and use this syntax. If
03:38selectedXML.name has a value of photo and then within that conditional clause,
03:47assign the value of xPhoto from selectedXML. Now, if the user selected a parent
03:55node that is a location, you don't want to display a photo in that case. So,
04:00put in an else clause and set the value of xPhoto to null.
04:05Now, it's time to add some visual controls to show the result. Go to the panel
04:10at the bottom of the application with the title of Photo Detail, add an Image
04:15Control and set its source property using a combination of a literal string
04:19pointing to the location of your graphic file that will be assets/ and then a
04:25binding expression pointing at the source attribute of the xPhoto object.
04:30That will be xPhoto.@source. Also, in order to make sure that the Image Control
04:37only appears when it has something to display, set its visible property using a
04:41binding expression of xPhoto not equal to null. So, now the image control will
04:47only appear if in fact there's something selected from the Tree.
04:51We'd also like to show the label of the selected photo, go to the panel
04:56containers, start tack and add a status property using a binding expression of
05:01xPhoto.@label, these are e-forex expressions that are extracting the
05:07appropriate attribute for each purpose. The status property of the panel is a
05:11simple string that appears to the right of its title.
05:14The source property is a string also and it's going to be loading the photo at
05:17runtime from the local disk or from the web when you deploy the application.
05:22Save your changes and run the application in normal mode this time. Notice now
05:28that when you click on an item which represents the location, nothing happens.
05:31But, when you open up the Tree and select the photo node, the actual selected
05:36photo is displayed in the right panel. You now have a good photo browsing
05:40application that you can use that displays the contents of the XML file using
05:44the Tree Control and displays the selected detail using a standard Image Control.
Collapse this transcript
Using the MenuBar control
00:00In this video I am going to describe the use of the Menu Bar control. The Menu
00:05Bar control is very similar to the Tree control in that it's designed to use an
00:09XML formated data provider so that it can display hierarchical data.
00:13For this demonstration I will use the Application UseMenuBar.mxml. If you are
00:18following along with the exercises you can open this application now. This
00:22application starts off in a very similar fashion to the ones I have been
00:25working on in this chapter. It retrieves the same XML data that contains
00:29location and photo information and saves it as a variable named xLocations and
00:34then extracts data to an XML list.
00:38Now when use a Menu Bar typically you put it at the top of the application. So
00:42I have created an ApplicationControlBar container with it's dock property set
00:46to true. I will place the cursor between the tags of the ApplicationControlBar
00:51and then declare a MenuBar and I will give it an id of myMenu and then I will
00:56set it's dataProvider using a binding expression to the xLocations XML list.
01:02Close the tag with a slash greater than(/>) and then as with the Tree control I
01:07have to specify for the MenuBar which attribute or element should be used to
01:12provide the label for each node of the menu. I will use labelField attribute
01:17this time rather than labelFunction and I will pass in the E4X expression at
01:22label. Meaning that I want to use the label attribute of each XML element to
01:27provide the label for it's equivalent menu node.
01:29I will save the changes and run the application and you should see the each
01:34node in the XML list that I used as the dataProvider creates a top level menu
01:39and then the child elements of that XML node are used as the sub menu. So I now
01:44have four items on the menu and each has it's own sub menu. Just as with the
01:49Tree control you have the ability to customize the labels on each of the menu
01:53nodes using the label function property and a custom ActionScript function,
01:58that returns a formated string.
01:59You also have the ability to provide skinning and custom item renderers just
02:03like you would in a List control. Now in the next video and the last in this
02:07chapter, I will show you how to handle the events of the MenuBar and react
02:11when the user has selected an item from the menu.
Collapse this transcript
Handling MenuBar events
00:00In this video I am going to describe how to listen for an event that occurs
00:04when the user select an item from the menu bar, and how to get information
00:08about that event and react accordingly.
00:11For this demonstration I will use the Application, MenuBarEvents.mxml. If you
00:15are following along with the exercises, you can open this file now. This is the
00:20same application that I worked on in the previous video. It uses an XML file to
00:25populate a menu bar which is wrapped inside an ApplicationControlBar and docked
00:30to the top of the application. As the user navigates the menu bar, the control
00:35dispatches an event named item click. In contrast to the tree control, with the
00:40menu bar, the item click event only happens when you are on a terminal leaf of
00:44the external structure.
00:46So for example, when the user selects London, as I am doing here, an item click
00:51event does not happen. But when the user select an item under London, such as
00:55London Bridge, then the event is dispatched. So here are the steps I will
01:00follow to listen for the event and react. Go to the Script section and add a
01:06new private function, named itemClickHandler. When the item click event is
01:12dispatched by the menu bar, the event object is data typed as a class named
01:16MenuEvent. The MenuEvent class is a member of a package that must be imported,
01:23in order for it's classes to be used. So when you select MenuEvent from the
01:27list of available classes, Flex photo should add an import statement for you.
01:34Within the event handler function, you can get a reference to the selected
01:37item, using the item property of the event object. So to clear a variable name
01:43selectedMenu, data typed as XML, and get its reference from event.item as XML.
01:54Add a call to the trace function, and type in a literal string of "You
01:58Selected, and then can catenate that to an E4X expression of
02:06selectedMenu.@lable. And this will allow you to trace and verify what you are
02:13getting from the selection on the menu. Now go down to the MenuBar control, and
02:18add an event listener that calls that function. The event listener looks like
02:22this. ItemClick = "itemClickHandler (event)"and pass the event object. Now run
02:29the application in debug mode. Arrange the browser that's displaying the
02:34application, so that you can see the console view of Flex Builder in the
02:37background. Click on the top level item, and you will notice that you don't get
02:41any console output. But now click on the item from the sub menu and you should
02:47see a trace message in the console indicating which item you selected.
02:52So now you know that you are correctly getting a reference to the XML object
02:56underlying the selected menu item. Close the browser and return to Flex
03:00Builder, go back to the itemClickHandler function. Now the only remaining step
03:06for this application is to save the selected menu object as the xPhoto object
03:12that was already declared. All the code to create the visual detail
03:17presentation is already in this application. So I will use this syntax. Xphoto
03:23= selectedMenu. I am taking the XML object, I am saving it to this predeclared
03:29xPhoto variable, and then the visual output at the bottom of the application
03:34within the panel, uses an image control to display the photo itself, and a
03:39status property of the panel to display the label. This part of the code is
03:44exactly the same as for the version of the application that used a tree control
03:48to navigate the XML content.
03:51Save your changes and run the application this time in normal mode. Try
03:59selecting an item from the menu, I will choose New Orleans and Riverboat, and
04:04you should see the selected photo and its label displayed in the panel. So this
04:10is how we use a menu bar, and detect it's events. We use the item click event,
04:15which generates an event object data typed as MenuEvent. The event object has
04:20an item property which we can use to get a reference to the selected XML, and
04:24then we can get whatever values we want out of the XML, displaying information
04:29visually, or using that information to navigate around the application as needed.
Collapse this transcript
7. Integrating Flex with ColdFusion
Installing ColdFusion on Windows
00:00In this chapter of the video series I am going to describe how to integrate
00:03your Flex applications with Adobe ColdFusion. ColdFusion is a rapid application
00:08server platform that runs on multiple operating systems. It's based in JAVA in
00:13the background but developers use a proprietary language called ColdFusion mark
00:17up language, to write the server side code, and integrate with server side
00:20databases. In this video I am going to describe how to install ColdFusion on
00:24Windows, and then in the next video I will describe how to install it on the Mac.
00:28You can download ColdFusion for free from the Adobe website at this URL,
00:32www.adobe.com/products/coldfusion. From this page click the download free trial
00:40link, and after signing in with an Adobe ID which is free, you will come to
00:45this download screen. SELECT the appropriate version of ColdFusion for your
00:49operating system. If you are developing on the Windows platform, you'll
00:52probably want this version, English/Windows, or if you have 64-bit Windows,
00:57there is a version for that as well. There are also separate versions for Mac
01:00OS X. Once again for 32 or 64-bit installation. Now probably I am only going to
01:06be demonstrating the installation of ColdFusion on Windows, and the Mac in this
01:09video series. The instructions I am going to give you should work on any of the
01:13other supported platforms as well.
01:16After downloading the ColdFusion, start up the installation. Click OK from the
01:19first screen, and after a few moments you will see an informational dialog.
01:24Click Next, take a look through the License Agreement, and if you accept it
01:28,click the appropriate button ,and click Next again. Then you'll come to the
01:31Serial Number screen. If this is your first time using ColdFusion, I recommend
01:35you can figure it as the Developer Edition. This version of ColdFusion requires
01:39no serial number, and you can use it as long as you want to on your own
01:43development system. You will be able to develop and test with it, but this
01:47version won't be usable for deployment.
01:49To deploy the applications you build with ColdFusion, you will even need to go
01:52get your own copy of the ColdFusion software, or rent website space at an ISP,
01:57that supports ColdFusion. On the Next screen you are asked for the
02:01configuration. Again, if this is your first time using ColdFusion, choose the
02:05Server configuration. This installs ColdFusion as a complete self contained
02:09server, including an underlined application server named Jrun, and a
02:13development Web server that you can use if you like. On the Next screen you are
02:16prompted for the various services that you want to install. If you are working
02:20on windows, you will see an option for .NET integration Services, and for all
02:24platforms you also see an option to include Life Cycle Data Services ES. I
02:29recommend that you leave all these options selected, and then click Next, and
02:33then select it directly into which you will be installing ColdFusion. The
02:36Default is C:/ColdFusion8, I will be accepting that option, and throughout the
02:42exercises in this chapter, I will be referring to that as the installation
02:46folder. Click Next, go through the options for Life Cycle Data Services ES,
02:51including reviewing the License Agreement, and just as with ColdFusion itself,
02:55there is a free version of Life Cycle Data Services. This is called the express
02:59edition, and it can be used for free without any serial number or registration.
03:03There are some significant limitations on Life Cycle Data Services Express, and
03:07it's worth reading through the license for this product.
03:10In the next screen you are asked which Web Server you would like to use. I am
03:14going to be demonstrating the use of ColdFusion with the built-in Web server.
03:18If you are working on windows, and you already have Internet information
03:21services or IIF installed, you will be able to select the connector for that
03:25Web server. But if you don't have the Web server installed, I recommend the
03:28built-in Web server. Click Next, and now you are prompted for password
03:33information. Type in any password you like. I am typing just the word password,
03:38and click Next again, and on the next screen you are prompted for Enabling RDS.
03:43RDS stands for the Remote Development Service, and it's a service that allows
03:47you to connect to the ColdFusion server for debugging, data source information,
03:52and a lot of other features.
03:54If you're going to work through all of these exercises in this and the next
03:56chapter of this video series, you will definitely need RDS to connect the Flex
04:01builder from ColdFusion. So Enable RDS, and once again Enter a password. Click
04:08Next again, review the summary information, and then click Install. The
04:13installation process takes a few minutes, but at the end of the process, you
04:17are prompted to configure the ColdFusion server. The installation happens in
04:22two major steps. The primary installation may take up to 10 to 15 minutes, but
04:26then one's the primary installation is completed, you will be prompted to go
04:30into a configuration and administration screen. Once you see this screen
04:34labeled installation complete, you will be ready to go to the configuration
04:38wizard. Make a note that in the installation screen it shows you the primary
04:42URL of the ColdFusion administrator, which is a Web application that you use to
04:46configure the ColdFusion server.
04:48I recommend that you leave the Launch Configuration wizard option selected, and
04:52then click Done. That will result in navigating to a Web browser and opening
04:57the Configuration Wizard. You will be prompted for the ColdFusion administrator
05:02password that you registered during the installation process. Enter the
05:05password, and click Login, and then it will take a few more minutes to complete
05:10the configuration process. I recommend that you leave the browser undisturbed
05:14during this process, and it may take up to three or four minutes to complete.
05:19When the configuration process is complete, you will be prompted to click OK,
05:22to open the ColdFusion Administrator. Click the OK button, and the ColdFusion
05:27Administrator Interphase appears. Again, this is a Web application that allows
05:31you to configure and manage your ColdFusion server. If you would like to be
05:34able to get back to the screen easily from your browser window, Bookmark or Add
05:38a Favorite in Internet Explorer. So I am going to select Bookmark, Bookmark
05:43This Page and click OK, and anytime I like, I can now get back to this screen.
05:48So that's to look how to install ColdFusion8 on Windows. In the next video I
05:53will show how to do the same thing on the Mac.
Collapse this transcript
Installing ColdFusion on Mac OS X
00:00In this video, I am going to describe the steps for installing ColdFusion 8 on
00:04Mac OS X. As I described in the previous video, where I described how to
00:08install ColdFusion on Windows, you can download ColdFusion from the Adobe
00:12website, starting at the URL I am displaying on the screen now
00:15http://www.adobe.com/products/coldfusion From this page, Click the Download
00:24Free Trial link. You will need to login with a free Adobe ID, and then download
00:28the version of ColdFusion for Mac OS X.
00:30I have already downloaded the file, which comes to you as a zip file, and when
00:35you extract the zip file, you'll get a ColdFusion 8 Installer. Double-click on
00:39the Installer to start it up, and the first screen you will see indicates that
00:43you are installing ColdFusion using English. Click OK to go to the next screen.
00:48On the Informational Introduction Screen, Click Next, review the License
00:52Agreement and if you accept it, select the appropriate Radio button and click Next again.
00:57ColdFusion 8 can be installed as the Developer Edition. This version of
01:01ColdFusion can be installed on any number of systems and used for as long as
01:05you want. It's limited in terms of how many concurrent connections to the
01:08server you can use. But you can use it for developing and testing without
01:11paying any license fee.
01:13Click the Next button, and on the Installer Configuration Screen, select Server
01:17Configuration. This means that you are installing ColdFusion with an underlying
01:21Jrun application server and if you want to use it a built-in web server. Click
01:26the Next button, and then confirm that you don't already have ColdFusion
01:30installed in the Server Configuration and Click Next again.
01:33On this screen, you select which sub-components you want to install. There are
01:37fewer options on Mac OS X than there are in Windows. For example there is no
01:41.NET integrations since the .NET framework isn't available on the Mac.
01:45However, you can choose as many items here as you like. I recommend that you
01:49deselect the options start ColdFusion on system in it, and then at the end of
01:53the installation process, I'll show you how to start up ColdFusion manually.
01:57I do recommend that you install the ColdFusion 8 Documentation and the Adobe
02:01LiveCycle Data Services ES optional install. Click Next. Now indicate where you
02:06want to install ColdFusion. On Mac, the default installation folder is
02:11Applications/ColdFusion 8, and I recommend that you use the default. Click Next.
02:16On the next couple of screens, review the options for the LiveCycle Data
02:19Services if you selected that option, and as with ColdFusion itself, you can
02:24leave this Serial Number blank. And that installs a trial version of LiveCycle
02:28Data Services. After 120 days, it becomes an express edition which can be used freely.
02:35Click Next and indicate whether you need to migrate settings from a previous
02:38version of ColdFusion. I haven't installed ColdFusion on this system before. So
02:42I will leave the option set to No, and Click Next.
02:45Now indicate which Web Server you want to use. I recommend for these exercises
02:50that you use the built-In Web Server. That will allow you to follow the
02:54exercises and use the same path and port numbers that I am using. So I have
02:58selected Built-In Web Server and Click Next again, and now I am prompted for
03:02password information. You need to enter two passwords. The first password is
03:07for the ColdFusion Administrator. A web application that allows you to
03:11configure and manage your ColdFusion installation.
03:14On the next screen, Enable RDS. RDS, the remote development service, allows you
03:19to connect to ColdFusion from Flex Builder. So that you can see the structure
03:23of your data sources and other useful information. Once again you'll need to
03:29enter a password twice.
03:31Here is the summary screen that tells you about all the selections you have
03:34made. Click the Install button to run the installation. The primary
03:38installation takes quite a few minutes, but when it's completed, you will be
03:42prompted to go into a Web Browser. When you get to the Installation Complete
03:46screen, you are prompted to launch the configuration wizard. A browser based
03:50application that completes the configuration of the ColdFusion install.
03:53Before you Click the button to continue, note the URL on the screen that
03:58indicates where you can address the ColdFusion Administrator. Click the Done
04:02button to continue, and after a moment the ColdFusion Configuration and
04:06Settings Migration Wizard opens in a browser. You will need to enter the
04:10ColdFusion Administrator password that you put in during the installation
04:14process. Then Click Log in.
04:18On Mac OS X, it takes just a few moments to complete the configuration, and
04:22when the process is done, you will see this screen that prompts you to Click OK
04:25to open the ColdFusion Administrator.
04:27Click the OK button and the ColdFusion Administrator Application opens. Now,
04:32before I conclude this video, I am going to show you how to stop and start
04:35ColdFusion on Mac OS X. I am going to close the browser and then I will
04:40navigate to the Macintosh hard disk, from there to Applications and from there
04:44to the ColdFusion 8 Folder that was created during the installation.
04:48The Mac OS X version of ColdFusion includes this application, the ColdFusion
04:52Launcher. Open the Application, and you will see that it has three buttons.
04:57Start ColdFusion 8, Stop ColdFusion 8 and Web Server Connector Utility. If
05:02during the installation, you indicated that you didn't want ColdFusion to
05:05launch upon system initialization, you will need to use this application to
05:09start ColdFusion each time you want to do a development and testing with it.
05:13So I am going to stop ColdFusion by Clicking the Stop button and it takes just
05:16a few moments for the server to stop in the background. Once the process is
05:20completed, you will see this message, ColdFusion 8 has been stopped. Then you
05:24can Click the Start button again, and the ColdFusion will startup again.
05:28Once you see a message indicating that ColdFusion has been correctly started,
05:32you can once again navigate to the ColdFusion Administrator which you will find
05:36at http://localhost:8500/cfide/administrator. Each time you go to the
05:49administrator, you will need to enter your administrator password which you've
05:52created during the installation process. Then you will be able to work with all
05:58the administrative options setting up data sources and other configurations.
Collapse this transcript
Installing and configuring a sample database
00:00In this video, I am going to describe how to import a database into ColdFusion
00:04that you will be able to use throughout the exercises about integration of
00:07ColdFusion and Flex. If you are following along with the exercises, start off
00:12in the Exercises folder. Navigate to the Assets folder and from there to
00:17ColdFusion. You will find a folder there named Flex3btb. This contains a
00:21variety of files including files that you are about to use to create a database
00:25and also some ColdFusion codes that you will be calling from Flex.
00:29Copy that folder to the clipboard. Now navigate to the web root of your
00:34ColdFusion server. On windows the ColdFusion root by default is
00:38c:\ColdFusion8\wwwroot on Mac OS X the location is
00:45\applications\ColdFusion8\wwwroot. This assumes that you have installed
00:51ColdFusion using the server configuration and the development web server. If
00:55you have another configuration, you will need to adapt these instructions as
00:59needed. Now, Paste that Flex3btb folder underneath the www root folder and now
01:06you are ready to create a data source to point to the data base.
01:10Go to the ColdFusion Administration, make sure that you have your ColdFusion
01:14Server turned on and then login to the ColdFusion Administration Login page. In
01:19the ColdFusion Administration interface go to the Data Sources section which
01:23you will find under the Data & Services section of the menu. Now add the Data
01:28Source Name. Set the Data Source name as you see on the screen.
01:32Flex3btbContacts and set the Driver type to Apache Derby Embedded. This is
01:39JAVA-based database that is used in ColdFusion for sample databases.
01:43It's compatible with all of the operating systems on which ColdFusion is
01:47delivered including Windows and the Mac. Click the Add button and then set the
01:52database folder using the flex3btb folder as the root. For example on Windows
01:58it's starts of with c:\ColdFusion8wwwrootflex3btb and on Mac it would be
02:04c:\application\ColdFusion8\wwwroot\flex3btb and then add a new contacts folder
02:12at the end.
02:13This folder doesn't already exist. It's about to be created by the
02:16Administrator. Select the option, Create Database and then click Submit and
02:23after a couple of seconds you should see the message data source updated
02:26successfully. And if you navigate back to the web root to the flex3btb folder
02:31you should find this folder contacts which has now been populated with number
02:35of files that are the database.
02:38Okay, now you are ready to actually create the database table and data. With in
02:42this flex3btb folder, there is a subfolder named database, which contains .CFM
02:48and a .CFC file. You are going to execute the CFM file which in turn will call
02:52functions of the CFC file. Go back to the browser and navigate to the following
02:57URL. 127.0.0.1:8500\flex3btb, you should see a listing of the folders under
03:07that folder. Click in to the database link and you will find the CFC and CFM
03:12file and click on CreateDatabase.cfm. It takes just a moment to execute the
03:18code and create the table.
03:20You should now be ready to move on to the rest of this chapter and start
03:22learning about integration of Flex applications with ColdFusion.
Collapse this transcript
Installing CFEclipse
00:00In this video I am going to describe how to install CFEclipse, a free plug-in
00:04for the Eclipse environment that allows you to easily Create and Edit
00:08ColdFusion code. CFEclipse is completely free and can be downloaded from
00:13www.cfeclipse.org. You can install it from directly within the Flex Builder
00:19environment, whether you have installed Flex Builder using the standalone or
00:23the plug-in architectures. To install CFEclipse go to the Flex Builder Menu and
00:27select Help SoftwareUpdates, Find and Install. On the Feature Updates screen
00:33select Search for new features to install and click Next.
00:36In the Updates Sites to visit screen you might see CFEclipse item listed
00:40already. This happens if you installed the ColdFusion extensions for Flex
00:45Builder, during the initial installation of Flex Builder or if you install
00:48those extensions later. If you do not see the CFEclipse item there, follow these steps.
00:54Click New Remote Site give your New Update Site a name such as MyCFEclipse and
01:00set the URL as follows www.cfeclipse.org/update, now the error message you see
01:10comes because Eclipse already knows that, that URL is being used by another
01:14update site and it won't let me enter it twice. So, I'll Cancel out of this
01:18dialog, but if you are able to click OK that means you need to add eclipse to
01:22your list of sites.
01:24Next make sure that your CFEclipse site is selected and click Finish. It takes
01:29just a moment for eclipse to go out of the site and check for available
01:32updates. Open the tree of available items, and then go to releases and you will
01:38see that there is an item listed as CFEclipse. The most recent version at the
01:42time with this recording was 1.3.1.6. Select the releases item and click Next.
01:49Then reviewed the license agreement which is based on the Eclipse Public
01:53Licenses and if you accept it, select the appropriate radio button and click
01:57Next again. Finally click Finish.
02:00On the high speed internet connection it takes just a few moments to download
02:03the CFEclipse code. You will then see a Feature Verification screen that asks
02:07you if you want to go ahead with the installation. Click Install All if you
02:11want to continue and after a few moments the installations should be complete.
02:16Whenever you install plug-in into the Eclipse Environment you should restart
02:19Flex Builder 3 and Eclipse. This ensures that when you restart the application
02:24you'll have all the features of the new plug-in. So, I'll click Yes, and Flex
02:29Builder closes and then restarts.
02:32Now, in the next video I'll show you how to create a new CFEclipse project that
02:36points to the code in your CodeFusion environment.
Collapse this transcript
Creating a CFEclipse project
00:00In this video I am going to describe how to create a CFEclipse project, that
00:04allows you to navigate and modify your ColdFusion code from within the Eclipse
00:08and Flex Builder environment.
00:10If you have been following along with the exercises in this chapter, you have
00:13already installed ColdFusion and created a database and a data source and
00:17copied code to the ColdFusion site.
00:19Now from the Flex Builder Menu follow these steps. From the Menu select File -
00:24New - Other. From the dialog that appears go to the CFEclipse section and open
00:31it and select CFML Project. Then click Next. Give the project a name of
00:37flex3btbCF. So that will be the name of the project for the ColdFusion code.
00:44Deselect the option, use default location, click the Browse button and then
00:49navigate to the location of the flex3btb folder under the ColdFusion webroot.
00:54On Windows that will under C:\ColdFusion8\wwwroot\flex3btb; on Mac that will be
01:04under \Applications\ColdFusion8\wwwroot\flex3btb.
01:12Click Finish. When prompted to open the CFEclipse perspective, click Yes.
01:17Now go to the Navigator view on the left and open the project. You will see all
01:22the folders within the project including the database folder that contain the
01:26files that created the database and a cfc folders that contains a couple of other files.
01:32Notice these other folders that are part of this directory. This particular
01:35directory and folder structure was created in Dreamweaver and as a result it
01:39has some additional directories that aren't relevant to the world of Eclipse,
01:43but that you will sometimes see in a ColdFusion site.
01:46Now open the file, PersonServiceTest.cfm. This file calls a function of a
01:52ColdFusion component called getPersonData. It calls it twice and dumps the
01:56results to the screen each time. The first time the ColdFusion is called, it
02:02executes a query and returns all of the data from the person table was created
02:06in our previous video.
02:08The second time it uses a lastname property to filter by a single character,
02:12and as a result it returns only those records for the lastname column of the
02:16record starts with the letter f.
02:18Now configure you project so that you can easily browse to pages from within
02:23Flex Builder. Go to the project root flex3btbcf, right-click on the project
02:29name or Ctrl+Click on the Mac and select Edit URL.
02:33Now enter the equivalent URL that will allow you to browse to the root of this
02:38project. It will be localhost:8500/flex3btb/ be sure to include the closing
02:49slash (/), otherwise the browsing won't work correctly.
02:52Click OK and then click back on the PersonServiceTest.cfm file. Now go to the
02:59toolbar where you will see a couple of buttons labeled 1 and 2. These buttons
03:03will allow you to browse to the page using one of the browsers.
03:07Click the number 1 and you should successfully navigate to the page and see all
03:12of the data dumped out on the screen. This is being executed using a
03:15combination of a cf query and a cf dump tag.
03:19Now scroll down to the bottom of the page and you will see a second record set,
03:22and in this record set only those records where the last name starts with the
03:26letter F are included.
03:27So if you have that much working you are now ready to integrate the ColdFusion
03:31code with your Flex applications, and in the next video I will describe how to
03:36set up a Flex application that integrates with the ColdFusion Server.
Collapse this transcript
Creating Flex/ColdFusion projects in Flex Builder
00:00In this video, I am going to describe how to create a Flex Builder project
00:04that's associated with the ColdFusion Server. When you create a Flex Project
00:08that's associated with ColdFusion, you provide information not only about where
00:12you are storing your flex source code, but also where your ColdFusion Server is
00:16and how you are going to test your application at runtime.
00:19If you are following along with the exercises, go to Flex Builder and create a
00:22brand new project from scratch. From the menu select File, New, Flex Project.
00:29Set the project name as Chapter07Begin. You can use the default project
00:35location for the location of your source code and leave the application type
00:39set to Web application.
00:41Now from the Application server type list select ColdFusion. Leave the option
00:46Use remote object access service selected and then also select ColdFusion Flash
00:50Remoting. Click Next, on this screen you indicate the location of your
00:55ColdFusion Server. The default settings are for the server configuration known
01:00here as the Standalone ColdFusion installation type.
01:03If you installed ColdFusion using the standard settings, you will be able to
01:06accept these default settings. On the Mac, check to make sure that the
01:10ColdFusion root is \applications\ColdFusion8 and check the same thing for the
01:15Web root. The Root URL should be exactly the same for either Windows or the
01:20Mac, http://localhost:8500. Make sure that your ColdFusion Server is running
01:28and then click the Validate Configuration button and you should see this
01:31message at the top of the screen, The Web root folder and root URL are valid.
01:36The next setting is for the Output folder. This is the location of the debug
01:41version of your application. Notice that when you create a flex project that's
01:45associated with ColdFusion, the output folder is placed under the web root. You
01:49can place this folder anywhere you like within the Web root and you can name it
01:53anything you want. The default name is the name of the project followed by -debug.
01:58Now I will click the Next button. This is the final configuration screen and
02:02it's the same as the one you see with non-ColdFusion projects. Set your main
02:07application file as FlexWithColdFusion.mxml and then click Finish. After a few
02:14moments your project and application are created. Now place the cursor inside
02:19the application text and create a label and set its text property to Hello from
02:25ColdFusion. I am going to set the font size of my label to 12 pixel, so it
02:33looks nice and large on the screen and also set the layout property of the
02:37application to vertical. Save your changes.
02:41Now each time you save your changes the application is built as it always is,
02:46but the bin-debug folder which is shown here as a linked folder that's what
02:50that little icon means, is actually a pointer to the physical folder under your
02:54ColdFusion Root, C:\ColdFusion8\wwwroot and so on. So now when you test your
03:01application, let's see what happens. I will run the application in normal mode.
03:06The browser opens and presents my application with the label Hello from
03:10ColdFusion and the location of the application from which I am pulling it is
03:14through the web server at localhost:8500.
03:18This is particularly important when you are working ColdFusion or other
03:21application servers because that allows you to download the application from
03:25the web server at runtime rather than opening it from the local disk and this
03:29way you will see exactly the same behavior during your testing as the users
03:33will see when they are actually using the application.
03:35So now we have our entire working environment set up and in the next set of
03:39videos, I will show you how to use the Remote Object Component of the Flex
03:43Framework to make calls to ColdFusion component functions.
Collapse this transcript
Calling CFC functions with RemoteObject
00:00In this video, I am going to describe how to use the Remote Object Component to
00:04make calls to ColdFusion CFCs over the web. A ColdFusion Component provide
00:09services that you can call remotely. The purpose of the remote object component
00:13in the Flex Framework is to make these calls using a Binary Protocol called AMF
00:18or Action Message Format. This Binary Protocol behaves in a similar fashion to
00:23a web service call, but unlike web service calls which use pure text to format
00:27the requests and responses, the AMF format being binary is much smaller and
00:32faster. AMF is directly supported by ColdFusion on the server and by the Flex
00:38Framework on the client. So what is the best way to make calls to ColdFusion
00:42functionality from a Flex Application.
00:44If you are following along with the exercises, you have already installed and
00:48tested a ColdFusion component called PersonService.cfc, which you will find in
00:53the flex3btbCF project, under the CFC folder. This component contains a single
00:58function called getPersonData. It executes a query wrapped in a cfquery tag and
01:04it has a conditional clause checking for an argument named lastname. If the
01:08argument is passed in then this query filters for only rows that start with
01:13whatever value you pass in and if not passed in, it executes a query and
01:16returns all of the data from the database table.
01:20Before you can call a ColdFusion component from a Flex application, you have to
01:24know the CFC address as it will be known to Flex. This is known in Flex as the
01:29source property and you can inspect the ColdFusion component in a browser to
01:33find out what that source property value is. Go to the CFC and then click the
01:38Browse button in Flex Builder CFE clips perspective. You need to enter your RDS
01:43or Administrator password. These are the passwords that you set up during the
01:47installation process for ColdFusion and after you have authenticated yourself
01:53to the ColdFusion service, you will see documentation for the ColdFusion Component.
01:58Noticed that the ColdFusion Component name is listed at the top in large
02:01characters but right above it is the complete path or source of the CFC as it
02:07will be known to Flex. So select that text which consists of the folder
02:11location of the CFC in dot notation starting from right after the web root,
02:16that's flex3btb.cfc and then the name of the CFC without the .CFC extension.
02:24Copy that to the clipboard. You will need that in your Flex Code.
02:28Now I will go back to Flex Builder and go to the Flex Project Chapter07Begin.
02:33Go to the source folder, right click on it or Ctrl+Click on the Mac and select
02:39New MXML Application. Name the application UseRemoteObject.mxml. Set the layout
02:47to vertical and click Finish.
02:49When the application code appears on the screen, place the cursor between the
02:55application tags and declare an instance of the RemoteObject component. The
03:01RemoteObject component is one of the three RPC components. RPC standing for
03:05Remote Procedure Call and again, this is the component that allows you to
03:09communicate very quickly with ColdFusion. Set its id property to myService.
03:15Each remote object component requires a destination property.
03:19The destination for ColdFusion CFCs is always the same, ColdFusion and then set
03:25the source property and paste in the value that you copied from the CFC
03:30documentation. It should be flex3btb.cfc.PersonService. Close the remote object
03:38tag. This is now the definition of the location of the ColdFusion component.
03:43Now you can call any of the components of the CFC using a syntax combining the
03:47id of the remote object plus the name of the method that you are calling from
03:51the CFC, in this case getPersonData.
03:54So now the next step is to add a Button, give it a label of Get Data and a
04:03click event listener that calls the remote CFC function, using the syntax
04:09myService.getPersonData. Be sure to include the opening and closing parenthesis
04:15at the end of the call and then close the tag of the Button. There are two ways
04:21to capture the data that's returned from the ColdFusion Server, Binding
04:25Expressions and Event Handlers. I am going to use a Binding Expression in this
04:29example because it's the simpler syntax.
04:33Create a DataGrid and set its dataProvider using the following binding
04:37expression, myService.getPersonData.lastResult. The syntax of the binding
04:48expression always follows the same pattern. You start with the id of the remote
04:53object component then the name of the method that you called and then last
04:58result as a property of the method object. Even though, ColdFusion itself is a
05:02non case sensitive environment, in the Flex environment it's critical that you
05:06match the case of how you called the method to the case of the binding
05:10expression reference to the method. So notice I am using exactly the same
05:14spelling of the method name in both cases and if you miss that, if you don't
05:18match them exactly, the data won't appear correctly.
05:21Now I am ready to test the application. I will run the application in normal
05:25mode and then I will click the Get Data button and after a few moments the data
05:29appears in the Data Grid. Noticed that you can now scroll up and down and see
05:34all of the data that's return from the ColdFusion Server. Now in the next
05:37video, I will show you how to use an Event Handler to capture the data, which
05:41gives you a lot more flexibility and power in how you deal with the date when
05:44it's returned.
Collapse this transcript
Handling the RemoteObject result event
00:00In this video, I am going to describe an alternative approach to handling data
00:04returned from an RPC component call such as the Remote Object Component. For
00:08these exercises, I will be using application files that are available in the
00:12Exercises folder.
00:13If you are following along with the exercises, go to the Exercises folder which
00:17I have installed on my desktop and navigate to the Chapter07 folder and from
00:22there to the folder Chapter07Begin. You will find three files there. Select
00:27them and copy them to the clipboard. Now I will go back to Flex Builder. Go to
00:33the source folder within the Chapter07Begin project and paste the files into
00:37your project. Then open the application file UseResultEvent.mxml. This is the
00:45same application that I worked on in the previous video where made a call to a
00:49remote ColdFusion component function called getPersonData and then used a
00:53binding expression to display the data in the DataGrid control.
00:57In this exercise, I am going to change the approach to handling the data to
01:00using the Result Event. Whenever you get data back from a remote server using
01:05any of the RPC components, that is Remote Object, Web Service or http service,
01:10the RPC component despatches the result event. The event object it's despatched
01:15is an instance of a class named Result Event and this class has a result
01:19property which points to your data. You can use this event to capture and save
01:23the data persistently, so that's then available to the entire application for
01:28the lifetime of the user session.
01:30Follow these steps. First create a Script section, below the Application start
01:35tag and above the RemoteObject. The next step is to declare a variable while
01:39you save the data persistently. Make it bindable by adding the bindable
01:43Metadata tag and then declare the variable using this syntax, private var
01:52myData and data type it as an ArrayCollection. The next step is to create an
01:58Event Handler function. Create a new function named resultHandler. Set its
02:05event argument, data typed as ResultEvent. Notice that with both the
02:10ArrayCollection and the ResultEvent class, as I select the class from the list
02:15of available classes, Flex Builder adds the required import statements. The
02:20resultHandler function will return void as to all good Event Handler functions.
02:25Now I will go to the Remote Object Component and add an Event Handler. Use
02:30this syntax, result="resultHandler and pass the event object. Now when the data
02:37is returned from the Remote Server, the event object will be passed into the
02:41resultHandler function. Add a break point on the last line of the function.
02:46That's the line that has the closing brace. Then save and run the application
02:50in debug mode. When the application appears click the Get Data button. If you
02:56see this request to switch to the Flex Debugging perspective, click Yes and
03:01then go to the Variables view, expand it to full screen and inspect the event
03:06object. You will see that the event object is data typed as result event.
03:11Navigate down to the result property which is an ArrayCollection and within
03:15that object you will see all the rows that are returned from the remote
03:19database through the CFC function. Whenever a CFC function returns a query
03:24object that is an object created by the cfquery tag, it's automatically exposed
03:28in the Flex environment as an instance of the ArrayCollection class.
03:32Now resize your variables view and terminate the debugging session. Then go
03:37back to your source code in full screen. Since we now know that the events
03:42result property is an Array Collection containing the data, we can assign that
03:47to the existing myData variable, like this, myData = event.result as
03:55ArrayCollection. We have to tell the compiler explicitly that the object being
04:00returned is an Array Collection. It won't know it without that syntax.
04:04Now I will go down to the DataGrid component and change its dataProvider, so
04:08that instead of using the full binding expression pointing to the name of the
04:12method and the last result property, we simply point to myData. So here are all
04:18the steps that we declare a Bindable variable, data typed as an
04:22ArrayCollection, we create a resultHandler function that passes the data to
04:26that variable and then the data is available for binding to visual controls
04:31such as a DataGrid.
04:33Run the application again, this time in normal mode. Click the Get Data button
04:39and you should see the data appear on the Data Grid, just like it did before.
04:43Using a result event handler takes a bit more code than a binding expression
04:47but there are enormous benefits. First of all, you have the opportunity in an
04:51Event Handler function to inspect, modify and massage data before you display
04:56to the user. Also, you have effectively decouple the visual controls such as
05:01the Data Grid from the component that's getting the data from the server, such
05:05as the remote object. This is a good software design architecture.
05:09By separating the components that get the data which we call the model from the
05:13components that present the data and allow the user to interact with it, which
05:16we called the view, you can more effectively manage and maintain your
05:20application in the future without it becoming brittle. When you have components
05:24that use binding expression that directly to the data acquisition components
05:29such as remote object, you are tightly coupling the components and that kind of
05:33application turns out to be very bugproof.
05:36So this is how we use the Result Event to separate the components and to allow
05:41ourselves to save data persistently after it's been returned from the server.
Collapse this transcript
Handling the RemoteObject fault event
00:00As I described in the previous video, when an RPC component such as remote
00:04object, sends a request to a Remote Server and the data comes back
00:08successfully, it despatches an event named Result. When things go wrong though
00:13it despatches another event called Fault and you can listen for an handle this
00:17Fault Event to react to problems that can occur during communication with the server.
00:22For this demonstration, I will use the application UseFaultEvent.mxml. If you
00:27are following along with the exercises, you will find this file in the
00:29Exercises folder under the Chapter07Begin area. Open the application and you
00:34will see that this is the same application I worked on in the previous video.
00:37It's currently listening for and reacting to a result event to handle and
00:42capture the data that's return from the Remote Server.
00:45In order to handle a fault event, add an eventHandler function that expects an
00:49event argument, data typed as the Fault Event class. Use this code, private
00:56function faultHandler and pass an event argument to the function, data typed as
01:02faultEvent and return void as with all event handler functions. As with the
01:08result event and ArrayCollection classes, the fault event must be imported and
01:13if you follow the steps that I did, Flex Builder will add the required import
01:17statement for you.
01:18Now go to the remote object declaration and then add a fault event listener.
01:23Put in a fault attribute and in the action script code call the faultHandler
01:28function and pass the event object. The next step is to debug and inspect the
01:33event object. Place a break point on the last line of the faultHandler
01:36function, that is the line with the closing brace. Then go down toward the
01:41bottom of the application and add a new Button component with a label of Cause
01:46Fault. Add a click event handler and this time call a remote CFC function that
01:54doesn't exist, using this syntax, myService.noSuchMethod. Because I am trying
02:04to call a function or a method that is not defined in the CFC, that will
02:08trigger in exception at the server level and that exception will bubble back up
02:12to the Flex application causing the fault event.
02:15Now save your changes and run the application in debug mode. Click the Cause
02:20Fault button and that will trigger the exception at the server due to trying to
02:24call function that isn't defined. Switch back to Flex Builder if necessary and
02:28if prompted go to the Flex Debugging perspective. Go to the Variables View and
02:34open the event object which is data typed as fault event. Noticed that it has a
02:39fault property which is data typed as a class named fault and this object has
02:43properties named faultCode, faultDetail and faultString. Each of these
02:48properties contains a string value and you can use any combination of these
02:52values to get information about the nature of the problem.
02:55Now to actually handle the fault, you have a number of options. Probably the
02:59simplest approach is simply to share the fault information with the user, using
03:03a pop-up window generated by the alert class. So restore the size of the
03:08Variables View and terminate your debugging session, then go back to the Flex
03:12Development Perspective and place the cursor inside the faultHandler function.
03:18Call the Alert class's show method. Pass in the following two arguments to the
03:25Alert.show method, event.fault.faultString is a longer message that you can
03:34display in the body of the pop-up window and event.fault.faultCode is a shorter
03:41value that will fit nicely into the title of the pop-up window.
03:46Check to make sure that Flex Builder has added the required import statement
03:49for the Alert class, if not, add it yourself. Save your changes and run the
03:54application, this time in normal mode. Click the Cause Fault button and you
03:59should see the pop-up window generated by the Alert class displaying the fault
04:03information. Click OK to clear the pop-up window and then click the Get Data
04:08button and you should successfully retrieve and display the data in your application.
04:13So these are the two most commonly used events of the Remote Object Component.
04:17The Result Event handle successful communication and retrieve all the data from
04:21the server and the Fault Event handles exceptions that can occur when something
04:26goes wrong either at the server or at the client level.
Collapse this transcript
Passing arguments to CFC functions
00:00In this video, I am going to describe how to use ColdFusion functions that
00:04require parameters or arguments. I will be using the application
00:08PassParameters.mxml. If you are following along with the exercises and you
00:12don't have this application, you can find it in the Exercises folder
00:16Chapter07Begin sub-folder. Open the application and take a look at it. It's the
00:22same application I have been working on in previous videos. It retrieves data
00:25from the server using a call to the CFC function getPersonData.
00:30Let's take another look at the CFC function that's being called. Go to the
00:34flex3btbCF project that references all of your ColdFusion code and opened the
00:39file PersonService.cfc. Here is the code for the getPersonData function. It
00:45executes a query and then has a conditional clause that looks for an argument
00:49called lastname. If that argument exists, it filters the return value based on
00:54the value that's passed in, only returning data where the value of the argument
00:58matches the beginning of the last name column of the row.
01:01So let's go back now to the application. There are three ways to pass in
01:05arguments to a ColdFusion function. The first is called explicit arguments. In
01:11this approach, you pass in values in exactly the same order in which they are
01:15declared in the CFC function. So for example, let's say that you only want to
01:19retrieve data where the last name column starts with the letter F. Go to the
01:24getPersonData function and pass in a value of the letter F wrapped in single
01:28quotes. Save your changes and run the application. Click the Get Data button
01:35and you will see that you only get back the data for the values that you
01:38wanted. Now it would also be nice to do this more dynamically and for this
01:42purpose I have provided a custom component that you can plug into the application.
01:48If you are following along with the exercises, go the Exercises folder to the
01:52Assets folder and look at a folder named Components. There you will find a
01:56component named CharacterSelector.mxml. Copy it to the clipboard. Go back to
02:03Flex Builder, to the Flex Navigator Project, go to the source folder and add a
02:07new folder there, named Components and then paste the component into the new folder.
02:17The CharacterSelector custom component presents two button bars, each populated
02:22with a button with a particular character on it. Combined they present the
02:26letters A through Z. Go back to the PassParameters.mxml file. Place the cursor
02:32after the DataGrid component and add an instance of this new custom component.
02:37Start off typing the less than character than char and you should see the
02:42CharacterSelector custom component is available. Select it to fill in the tag,
02:47set its id property to selector and then listen for an event that's despatched
02:51by this custom component called select. Use this syntax, select= and then when
02:59the event occurs call the following action script code,
03:02MyService.getPersonData and pass in a value of event.text.
03:11The text property of the event object for this component will contain the
03:15character that they clicked on. Close the tag and run the application. The
03:21CharacterSelector component displays these two button bars. You can still click
03:25the Get Data button, which in this case is still filtering on the letter F or
03:30you can now click on any of these buttons to see a filtered list of data passed
03:34back from the server.
03:37So that's one approach to passing arguments. Here is another approach. You can
03:41also pass arguments by name, by wrapping them inside an action script object.
03:46Go to your Script section and create a new function named getDataByLastName.
03:53Set up the signature of the function to receive an argument named filter, data
03:57typed as a string, returning void.
04:00Now within the function, you are going to create an action script object and
04:04then give it a named property that matches the name of an argument expected by
04:08the ColdFusion function. Here are the steps. We will create a variable named
04:13params, data typed as an Object and instantiated using the Object class's no
04:19arguments constructor method. Next, we will add a named property called
04:24lastname and that matches the name of the argument expected by the CFC function
04:29on the server and we will set its value to the filter value. Finally, we will
04:34make a call to the Remote CFC function using the syntax MyService.getPersonData
04:42and then we will pass in the params object.
04:46Now go back down to the CharacterSelector button and replace the action script
04:50code in the select event listener, so that now it's calling the method
04:55getDataByLastName and once again passing the event objects text property to
05:00indicate what we were filtering on. When you pass in a object with named
05:05properties into a ColdFusion function as its only argument, the object is
05:09broken apart into its individual named values and the arguments and their
05:13values are now matched by name rather than by order. Save and run the
05:17application and you should still be able now to filter by clicking on the
05:22buttons of the custom component.
05:25Let's make one more change to the application and then we will consider it
05:28complete. Go back to the Button labeled Get Data and change its label to Get
05:32All Data, then go to the call to getPersonData and remove the argument.
05:37So now you have two different ways of getting data from the server. If you call
05:41the getPersonData directly without any arguments, you will retrieving all the
05:45data because of the logic within the CFC function, but if you passed the
05:48function and object containing named properties, where the property names match
05:53the names of the arguments in the CFC, you are not passing the arguments by name.
05:57I will run the application one final time and show that if I clicking the Get
06:01All Data button, you will retrieve all the data from the server, but by
06:05clicking on the buttons of the selector component you are filtering on that
06:09particular character.
Collapse this transcript
Working with multiple CFC functions
00:00In this video, I am going to describe how to handle result events when you
00:04called multiple functions from the ColdFusion Component. For the exercises in
00:08this video, I will go back to the application UseResultEvent.mxml. Let's take
00:13another look at the ColdFusion component we have been calling, named
00:16PersonService.cfc. It has two functions named getPersonData and getPersonCount.
00:23The getPersonData function returns data from the database table. You can call
00:28the function without any arguments to get back all the data or pass in an
00:31argument to filter it.
00:32There is a also a function called getPersonCount, which returns a numeric value
00:38which is the total number of records in the database. When you want to be to it
00:42call more than one function from a single CFC, you have to distinguish in your
00:46result event handlers, which event of which function you are listening for. If
00:51you declare everything in MXML, here is how it's handled.
00:55First of all, change your Remote Object Component so that it's declare with a
00:59set of tags rather than a single tag. Then within the remote object component
01:04you declare as many mx method tags as there are functions you are calling from
01:09the CFC. Mx method is something called a compiler tag. It doesn't represent a
01:13true property or even an instance of a class, instead it's simply a way of
01:17instructing the compiler how to despatch and handle different events.
01:21So for example, when you call the method called getPersonData and you want to
01:25handle the result event for that particular method with a specific function,
01:29you add an mx method tag and you set the name property to the name of the
01:34method you are calling, getPersonData. As always this is highly case sensitive.
01:39You must match the value of the name property here to the name of the method as
01:43it's being called.
01:45Now add a result event handler which looks exactly the same as the version in
01:49the remote object tag and pass the event object to the appropriate event
01:53handler function. So I am going to call resultHandler and pass the event
01:57object. Now I am specifically handling this particular functions result event.
02:03So I will go back to the remote object tag and remove the result event from there.
02:09Now going back to the ColdFusion component, I would also like to make a method
02:13call to getPersonCount. So I will go back to the application and add another
02:18method tag, set its name property to the name of that remote method,
02:23getPersonCount and set a different result event handler called countHandler.
02:34Then I will go up to the Script section and create that function. As with all
02:39event handler functions for RPC result events, I will receive an event object
02:44data typed as resultEvent and as with all event handler functions are returned void.
02:51Now I am going to display the total number of records that was recorded by the
02:55database using an Alert class and I will call it show method and display the
03:01message There are and then our output event.result which will be total number
03:08of records and then another little string of, records in the database table.
03:14Then I will pass in the title of Record Count.
03:22Finally, I will go down to the applications visual interface and add a new
03:26button. I will set its label to Get Record Count and add a click event listener
03:34that calls the remote function getPersonCount. Be sure to include the opening
03:41and closing parenthesis at the end of the function called.
03:45So here are all the pieces of the puzzle. We have a distinct event listener for
03:49that particular remote function in the CFC. We have an mx method tag within the
03:54remote object that handles the event and despatches the event object to the
03:59correct function and a button control whose click event calls the function. I
04:03will save the changes and run the application and as before I can still click
04:11the Get Data button and I will get all the data displayed in the Data Grid, but
04:15now I can also click the Get Record Count button and I get back the report that
04:19there are 100 records in the database table.
04:21So this is one way of handling multiple functions that you call from a single
04:26CFC. Now in the next video, I will show you another approach that's pure action
04:30script code based, where you both instantiate the Remote Object Component and
04:34set up its event listeners using pure action script.
Collapse this transcript
Using RemoteObject with ActionScript
00:00In this video, I am going to describe how to use the Remote Object Component,
00:04initializing the component and setting up its event listeners using pure action
00:08script code. For this demonstration, I am going to create a brand new
00:11application. If you are following along with the exercises, go to the Flex
00:15Builder Menu and select File, New, MXML Application. Set the name of the
00:21application as RemoteObjectWithAS.mxml and set its layout property to vertical.
00:30Now I will place the cursor between the Application tags and add a Script
00:33section. The Remote Object Component is an Action Script Class which can be
00:38instantiated in action script code just as easily as in MXML. Between the
00:42Script tags, declare a new variable data typed as ro for Remote Object and then
00:49for its data type select Remote Object.
00:51When you select the Remote Object class from the list of available classes, you
00:55will see that there are two versions of the class. They are distinguished by
00:59their packages. Notice one of them ends with the package of .MXML and the other
01:03doesn't. Use the second one for action script code. There are couple slight
01:08differences in its properties, but its basic behavior is the same. Click OK and
01:13then ends the declaration with the semicolon.
01:16Next, create a private function named init. This function will be called upon
01:20application start up and return void. Then go back to the application start tag
01:25and add an applicationComplete event listener and call the init function. Now I
01:30will go back down to the init function. As the application starts up, here are
01:34the tasks you will need to accomplish.
01:36First instantiate the remote object and initialize it with its destination,
01:41that is the remote object on the server that you are calling, that will be a
01:44value of ColdFusion. So the code for that is ro = new RemoteObject and here we
01:51are calling the Constructor method of the RemoteObject class and then pass in
01:55the destination as the one and only argument. The destination as with the MXML
02:00version is simply ColdFusion.
02:02Now set the source property which is the address of the CFC on the server. Use
02:07this code, ro.source = "flex3btb.cfc.PersonService" and this is exactly the
02:17same value that you would put into the source property in the mxml version.
02:21Next, we need to set up an event handler function to handle the data that's
02:24returned, when you call one of the CFCs functions. Place the cursor after the
02:29init function and create a new function called resultHandler. The syntax for
02:35this event handler function is exactly the same as in the MXML version. It will
02:39receive the single event argument, data typed as ResultEvent and return void.
02:45Now to hold the data, place the cursor above the init function and declare a
02:50new Bindable variable using the syntax private var and name the variable myData
02:56and data type it as an ArrayCollection. Go back to the resultHandler function
03:01and fill in the value of that variable when the data comes back from the server
03:05with the syntax myData = event.result as ArrayCollection.
03:12Now we have just a couple more steps to do. Go to the init method again. As the
03:17application starts up, you have already instantiated and set the Remote
03:20Object's source property, now you will need to add an event listener using this
03:24syntax, ro.addEventListener and for the event name, use the constant
03:30ResultEvent.RESULT and then in the second argument, pass in a reference to the
03:35function you want to call, resultHandler.
03:38Finally and the last step in using the Remote Object, call the remote object's
03:43CFC function name using the same sort of syntax as you did in the MXML version,
03:48ro.getPersonData. So as the application starts up, we are handling everything
03:54within the init method. Constructing the remote object, setting its source, its
03:59destination and its event listener and then calling the remote method.
04:03Finally, create a visual control to display the returned data. Place the cursor
04:08after the script section and create a DataGrid and set its dataProvider using a
04:13binding expression to the ArrayCollection variable, myData. Save your changes
04:20and now as the application starts up, it will make the request to the Remote
04:23Server and the data should be displayed successfully.
04:27So you now have a working example of how to use the Remote Object Component in
04:31pure action script. Many developers prefer this approach to the mixture of MXML
04:36and action script code, but it's a question of style rather than function and
04:41you can make your own choice about how to architect the code for your application.
Collapse this transcript
8. Using the ColdFusion Extensions for Flex Builder
Installing the ColdFusion Extensions plug-in
00:00In this chapter of the video series, I am going to describe the use of the
00:03ColdFusion Extensions for Flex Builder, an Eclipse plug-in that provides many
00:08features that are valuable to ColdFusion developers including RDS connectivity.
00:13RDS stands for Remote Development Service and it's a protocol that's been used
00:18by various products including HomeSite and Dreamweaver in the past to connect
00:22to ColdFusion servers during development and provide information about database
00:26structure, services and other valuable features.
00:30The RDS connectivity is also used by the ColdFusion Extensions to create code
00:35generation wizards. These code generation wizards can inspect the structure of
00:39the database table and then generate both server and client-side code to create
00:44easy data connectivity functionality from a Flex application to ColdFusion at runtime.
00:50In order to use the ColdFusion Extensions you have to first install them,
00:54during the initial installation of Flex Builder you may have already installed
00:58the extensions because they are offered as an option during that installation
01:01process. If you would like to check whether you have the ColdFusion Extensions
01:05installed, go to the Flex Builder menu and select Window, Other Views and look
01:12for a set of views that are categorized under ColdFusion.
01:15You will see such views as RDS Dataview, RDS Fileview and others. If you don't
01:21see that group of views that means that the ColdFusion Extensions aren't
01:25installed on your system and you need to install them if you want to use them.
01:29So here are the steps for the installation. From the Flex Builder menu select
01:34Help Software Updates, Find and Install.
01:39Select Search for new features to install on the Feature Updates screen and
01:43then click next. The ColdFusion Extensions are provided as a zip formatted
01:49installer file in the Flex Builder installation. They are also provided as the
01:54same file in the ColdFusion 8 installation. Click the New Archived Site button,
01:59in the Update sites to visit dialog, and navigate to the Flex Builder 3
02:03installation folder.
02:06On Windows, this will be by default under C:\ProgramFiles\Adobe\FlexBuilder3
02:15and on Mac OS X, this folder will be \Applications\Adobe\FlexBuilder3. From
02:22that folder, navigate down to the Installers folder, from there to the
02:27ColdFusion Extensions for Flex Builder and then locate and select the file
02:32ColdFusion_Extensions_for_Eclipse.zip. This will bring you back to a dialog
02:37labeled Edit Local Site, the name that you supply for this site can be anything
02:42and you can accept the default value and the URL is set based on what you
02:46selected during the browsing process. Click OK to save the site definition.
02:51When you come back to the Update sites to visit screen, the new site will be
02:56selected, click the Finish button to continue. Now, I am not going to continue
03:01this process because I already have the extensions installed, but on your
03:05system if you need to complete the installation follow all of the rest of the
03:09prompts through the installation process. At the end you will be prompted to
03:13restart Flex Builder and you will want to confirm and do that and that will
03:17ensure that all of the new features would be available upon restart.
03:21Then if you are following along with the exercises and you have the exercise
03:24files available, before you continue with the rest of this chapter, you will
03:29want to make sure you have installed and started ColdFusion and that you have
03:33installed the sample database that's a part of the assets\ColdFusion folder
03:37within the exercises area, and from that point all of the rest of the exercises
03:42in this chapter will be available to you, because I am primarily going to be
03:46looking at how to use this ColdFusion Extensions plug-in to inspect data
03:50structure create queries and then generate both client and server code and
03:56integrate that into your Flex applications.
Collapse this transcript
Using RDS Dataview and the Visual Query Builder
00:00In this video I am going to describe how to configure and use some of the
00:04features of the ColdFusion Extensions for Flex Builder. I am going to be
00:08focusing in this video, on features that are enabled by RDS or the Remote
00:13Development Service Protocol. As I described previously, RDS has been
00:17previously implemented by other code development tools such as HomeSite and
00:22Dreamweaver, and allows you to connect to a ColdFusion server during
00:25development, to get information about database tables and their structures.
00:30Before you try to visit a ColdFusion Server through RDS, you first need to
00:34check and perhaps setup your configuration.
00:38Go to the Flex Builder Menu and select Window Preferences. In the Preferences
00:43dialog, open the Adobe category and select RDS Configuration. You'll see a
00:50single item listed here labeled local host. The default RDS Configuration
00:55labeled local host, is setup to look for a ColdFusion server installation on
00:59the local system, using the IP address 127.0.0.1 and port 8500, which means
01:08that it assumes that you are using the development or stand-alone web server.
01:12Now if your version of ColdFusion is installed differently, for example if you
01:16install ColdFusion using IIS and you are listening on port 80 instead of 8500,
01:21you'll need to make a change here.
01:23Similarly, if you are using a version of ColdFusion that works in the J2EE
01:28installation, under a different port number and with what's called a context
01:32root, you should fill that context route in here. The security information
01:37refers to the name and password under which your RDS system is protected on the
01:43ColdFusion Server. During the installation of ColdFusion, I describe the setup
01:48of an RDS password. You can add the password here and then deselect the prompt
01:54check box and then you'll be able to connect your ColdFusion Server through
01:57RDS, without having to reenter the password later on. I'll go ahead and enter
02:02my password here and deselect the check box and then click OK.
02:08Now to view the ColdFusion server's data information through RDS, go to the RDS
02:13Data view window. Select Window, Other Views and go to the ColdFusion section
02:20of the Views List. Locate the RDS Dataview, select it and click OK. The RDS
02:29Dataview appears at the bottom of the interface by default. I typically click
02:33and drag the tab up to the top right, because the tree lays out vertically and
02:39that gives me a little bit more space to look in the information. If you have a
02:42dual Screen Setup where you spanning two monitors alternatively, you might
02:47right click or Control+Click on the Mac on the tab and select Detached. That
02:52will allow you to undock the view, and drag it to the other screen.
02:57Now open the local host heading and because I already entered my RDS password.
03:02I can now see all the data sources of the ColdFusion server, without entering
03:06the password again. Here is the data source that I setup in the previous
03:10chapter, Flex 3 BTB contacts. Click the Tree Icon to open up the data source
03:17and you'll see a listing of four categories of items. Tables, Views, Synonyms
03:22and System Tables. Open the table list and you will see a single table there
03:27named ape.person, the Ape prefix is something that comes from the particular
03:33database driver that's used for this database.
03:36The Apache Derby database driver always adds the Ape prefix to every table name
03:41automatically, even if you haven't done it yourself. You can also replace the
03:46prefix with some other value, but you can't get rid of entirely. If you use
03:50another database such as SQL Server or MySQL, you probably won't see that sort
03:55of prefix there, but with Apache Derby it's a part of the database name. Now
04:00click the Tree Icon next to ape.person, the table name and you'll see the
04:05structure of the database appear and you'll see that this table has unique
04:09identifier column, person ID and variable character fields of first name, last
04:14name and so on. Now the next step is to take a look at the data in the table.
04:19Right click on the name of the table or Control+Click on the Mac and select
04:23Show Table Contents. A query is executed and another view named the RDS Query
04:30Viewer appears in the Editor region. I am going to double click the Tab for
04:34that view and you'll be able to see all of the data is returned from the
04:38ColdFusion Server. Now from this screen, you can go into another feature called
04:42the Visual Query Builder. Click the Visual Query Builder button and that will
04:47take you into a Visual Query Builder interface, that's very similar to the one
04:50that used to be used in a HomeSite. You can build your query in a variety of
04:53ways, here I am going to drag a table into the interface and then I am going
04:59double click on a couple of columns. I am going to set a sort order on one of the columns.
05:05Now if you are working on the Widows platform, you will see a button on the
05:09interface for Visual Query Builder. If you are working on Mac OS X,
05:13unfortunately this particular feature is not available. But for Windows users,
05:18you can click the Visual Query Builder button and you'll go into an interface
05:22that's very similar to the old Visual Query Builder that was available with the
05:26product named HomeSite or ColdFusion Studio. Then I am going to test the query,
05:32a window pops up displaying the data and you can confirm the query is working
05:36correctly. Then you can close the window and return to the Visual Query Builder Interface.
05:42Notice that the result of this visual interface is a well formed SQL statement.
05:47You can now use this SQL statement in many ways, including copying it and
05:52pasting it into your ColdFusion code. The interface doesn't provide a way to
05:56save the query, to disc in any fashion. Instead it's just a way of building and
06:00testing SQL code to get your database information. So I am going to cancel out
06:05of this screen and return to the RDS Query Viewer and restore it to it's
06:10original size. The RDS Query Viewer which is the Editor window that I am in
06:15right now, has a pull down list that lets you switch between different RDS
06:19connections if you have more than one and also that lets you switch to
06:22different projects if you need to.
06:25So that's an overview of some of the major tools of the ColdFusion extensions.
06:29The RDS data view, the RDS Query Viewer and on Windows, the Visual Query
06:35Builder. Now in the next video, I am going to show you how to use these tools
06:39to start generating both server and client side code for use in your Flex
06:44Applications.
Collapse this transcript
Generating code with the CFC Value Object Wizard
00:00In this video I am going to describe how to use the ColdFusion Value Object
00:04wizard. That's a part of the ColdFusion extensions for Flex Builder to generate
00:09both ColdFusion service side code and client side Flex ActionScript code, so
00:14that you can easily move data back and forth between a Flex application and a
00:18ColdFusion server at runtime.
00:21Before you generate the code, you need to create a Flex project that's
00:24associated with your ColdFusion Server. Follow these steps:
00:29From the Flex Builder menu select File, New, Flex Project. As in the previous
00:36chapter, you are going to create a project that's associated with ColdFusion.
00:41Name this project Chapter08Begin. Check your application and server type and
00:46make sure that it's set to ColdFusion, and that the Use remote object access
00:51service option is selected along with ColdFusion Flash Remoting.
00:56Click Next and then check your server location both the default disk location
01:01and the web root. Then making sure that your ColdFusion server is running,
01:06click Validate Configuration and you should see the verification message at the
01:10top 'The web root folder and root URL are valid.'
01:14Also select your output folder which should be a location under your ColdFusion
01:18server web root. The default is the name of the project followed by -debug, and
01:24this is where you output folder with the debug version of the application will
01:28be created.
01:30Click Next to go to the final screen and set the name of the main application
01:34file as UseCFWizardCode.mxml. Then click Finish.
01:39When the application code has been generated, check its layout property and if
01:47it's been set to value of absolute, change it to vertical. Then place label a
01:53control inside the application text and set its text property ColdFusion Wizard
01:59Code. Set the font size style to a value of 18 pixels, so it's nice and large.
02:08Save your changes and then run the application, and you will be able to varify
02:12that your ColdFusion server is running and that you are able to download and
02:16run your Flex application from the ColdFusion server. Then close the browser
02:20and return Flex Builder.
02:23The purpose of the ColdFusion Value Object Wizard is to look at a database
02:28table structure and create a set of ColdFusion components on the server and one
02:32ActionScript class on the client that will then allow you to easily pass data
02:37back and forth between the tiers of the application.
02:40To get to the wizard, go to RDS Dataview. Go to the menu and select Window,
02:46Other Views, and select RDS Dataview from the ColdFusion section of the view
02:51list, click OK. Now go to your RDS connection, which on my system is labeled
02:57localhost. Open the list of data sources; open the data source for which you
03:03want to generate code and open the table list. Locate the name of the table for
03:09which you want to generate code, right-click on it or Ctrl-click on the Mac and
03:15select ColdFusion Wizards, Create CFC.
03:19The CFC Value Object Wizard needs a lot of configuration before it will do what
03:23you want it to do. The first bit of information is the location of the folder
03:28where you want to generate your ColdFusion code. On my system I had previously
03:33created a CFEclipse project pointing to the location of my ColdFusion Server
03:38code. I am going to browse and select that project, which on my system is named
03:43flex3btbcf, and then I will navigate down to its CFC folder, which is where I
03:49am going to place the generated ColdFusion component code, and click OK.
03:54Now set the CFC package name. This part is not handled for you automatically,
03:59instead you have to figure out what the name of the package is based on the
04:03names of the folders starting at the web root. If you had followed the
04:07instructions chapter for creating this CFEclipse project, the package name will
04:12be flec3btb.cf, and again that matches an existing folder that starts from the
04:19web root on down.
04:21The next step is to select the primary key column of the target database table.
04:27By default, when you are working with a database table that already has its
04:30primary key defined, this will be selected automatically for you. You also need
04:36to indicate whether the primary key is going to be provided by the user or is
04:40going to be generated by the database table.
04:42In this example, the database table is designed to autoincrement or fill in the
04:47next value for any new record. So I'll leave this option deselected. The next
04:53option simply indicates whether you want to overwrite any existing files. I
04:57haven't created these files yet, so it doesn't matter what I select here.
05:01The next option has to do with what type of CFC you want to use. You can select
05:06either Active Record CFC with result in generating two ColdFusion components or
05:11Bean CFC & DAO CFC which generates three. I prefer Bean & DAO because it
05:18creates a better separation of code on the server, and there are also some
05:21incompatibilities in the code for the active record approach that you avoid.
05:27The Property scope indicates how data will be stored in what are called Value
05:32Objects on the server. If you use the default private, that means properties
05:37are stored within a Bean or a Value Object component on the server, and they
05:41are stored privately within that component, and can only be accessed through
05:46private setter and getter accessory methods, which will be generated for you.
05:50If you select the option public, those variables are then set in what's called
05:55THIS scope in the ColdFusion component and they can be referenced from other
06:00ColdFusion code using simpler dot syntax. I'll the Property scope to public.
06:06When you use the Bean & DAO architecture, there are three components generated
06:10on the server. They are the Bean, also knows as a Value Object that represents
06:15a single instance of a data entity mapping to the database table structure, a
06:20DAO component that actually handles communication with the database, and a
06:25gateway component which contains remote functions that you can call from your
06:29Flex Remote Object component.
06:31I will accept all of the file names, and then I'll select another option down
06:36here indicating that I want to create an ActionScript Value Object. This is a
06:41Value Object class that maps its properties to the same values as the Bean
06:46component or the Value Object component on the server. You always want to place
06:51this component in your Flex project and not in you ColdFusion project.
06:56So I'll click the Browse button, navigate to my Flex project, 08Begin, and
07:02select the source folder as the location of the Value Object class. Now you
07:06don't have the ability to create new folders during this operation. So if you
07:11want to move this to another folder later on, you'll need to handle that move
07:15manually after the code generation is done.
07:18I'll click OK, and then the ColdFusion Wizard gets a little thing wrong here
07:24that you have to adjust for it. Get things that the src folder in which I am
07:28creating the class is actually a subfolder of the source code root and it
07:32isn't. It actually maps directly to the source code root. So I am going to
07:36leave the package blank. That's a lot of information; let me review the steps.
07:41The CFC folder is a location on your ColdFusion server under your ColdFusion
07:46project. The CFC package name is how you address the folder on the ColdFusion
07:52server and it's the folder structure containing the CFCs starting from the web
07:57root using dot syntax.
08:00The Primary Key is detected automatically by the wizard. You select one of
08:04these two options for the CFC type, and I have a preference for Bean & DAO CFC,
08:09because it does a better job of separating code on the server and the functions
08:13it generates are completely compatible with Flex.
08:16I typically set the Property scope to public. That gives me a little more
08:19flexibility in the ColdFusion generated code. I always create an ActionScript
08:24Value Objects that maps to the ColdFusion Bean Object, and the package name has
08:28to be modified to account for the fact that in Flex Builder 3 the source folder
08:33maps to the source root and is not really a subfolder of the source root as the
08:38wizard expects.
08:40Those are all the settings. Now I'll click Finish, and after just a few moments
08:45all of the code is generated. I'll have four files that have been generated.
08:50The Bean component, PERSON.cfc; the DAO or Data Access Object component,
08:56PERSONDAO; the Gateway component that I'll call from Flex, PERSONGateway, and
09:02the ActionScript class, PERSON.as.
09:05Now and the next video, I am going to do a code review of all of this generated
09:08code and describe the purpose and use of each of the components and classes.
Collapse this transcript
Understanding the generated code
00:00In this video, I am going to review the code that was generated by the
00:03ColdFusion Value Object Wizard. As I described in the video, when you use the
00:09Bean and DAO architecture, there are three components for each database table.
00:14The value object or a Bean component, which in this case is called person, the
00:18same as the table name. The data access object which has DAO after the table
00:23name and the gateway component. Let's start with the value object, the Bean or
00:29Value Object Component, declares properties for each of the columns of the
00:33database table. The data type of the properties are declared in the CF property
00:38tags. The name and type attributes of the CF property tags dictate to the Flex
00:43environment, how that data will be translated in the Flex application.
00:47For example if you declare the column name in all upper case, as happens
00:52automatically with databases that are being managed by the Apache Derby
00:56Database Driver. That's the name of the property that will be seen in the Flex
01:00application and the same thing is true of the data type. Columns that have a
01:05type of numeric will show up as ActionScript numbers and strings will show up
01:09as ActionScript strings. The default attribute of the CF property tag, doesn't
01:14actually do anything in terms of functionality. Instead the defaults are
01:18explicitly set in a CF script section below the CF property tags and this is
01:24code that's outside of any of the functions and therefore executes
01:28automatically upon instantiation of this component.
01:31Because I selected an option to make these properties public, they are all
01:35prefixed with this, which in a ColdFusion component means that each of these
01:40properties is public and can be addressed directly using simple dot syntax from
01:45any other ColdFusion code on the server. There is a function named init which
01:50returns an instance of the current component and then there are set and get
01:55accessor methods for each of the properties. For example the getPERSONID
02:00function, has an access property of public and return type of any, but it's
02:05designed to return the current person ID value of the current instance of the
02:10component. Similarly the set method for this particular function receives the
02:16value which it names a Val as an argument name, examines the value to make sure
02:20it's of the correct type and isn't blank and then passes the value to the
02:25public property.
02:27Using setter and getter accessor methods, lets you be much more specific and
02:32capture any runtime errors on the server side a lot more easily. So you'll find
02:37one set and one get function for each of the properties that's declared at the
02:41top of the component. There is one other critical part of this component, that
02:45should be described, the CF Component tag has an alias property, which
02:50indicates not only the name of the component, but also the package in which
02:54it's stored. In this case Flex3btb.cfc.
02:59If you were to move this component to somewhere else on your ColdFusion server,
03:04you would want to make sure that you reset the alias in this location and
03:08everywhere, where it's referenced in the rest of the ColdFusion code and also
03:12in the Flex Code as I'll show you in a little bit. So that's the Bean
03:16Component. Now let's look at the DAO Component. DAO stands for Data Access
03:22Object, a Bean Component when it's generated using the Bean and DAO
03:27architecture has four functions named Read, Create, Update and Delete. Taking
03:33together they stand for CRUD, a conventional type of component, that's used to
03:37address database tables.
03:40The purpose of the Read function is to receive a single ID property and then
03:45query and return a single object to the requesting code because we are using
03:50strongly typed value object components, after it executes the query which is in
03:55this CF query tag, it then transform the returned data, into an instance of the
04:00Bean Component. Notice that the entire Bean Component is addressed in this call
04:05to the Create Object function in ColdFusion. This is an example of where if you
04:09were going to move this code on the ColdFusion Server, you would have to change
04:13quite a few references to where the components are stored.
04:16The next function is named Create. It receives a single instance of the Bean
04:20Object, saves its values to local variables after calling the get methods of
04:26the Bean Object and then executes an Insert statement to add the data to the
04:30database. There is a bit of odd code here, which is worth talking about. There
04:36is a following query that retrieves the record that was just inserted using a
04:41where clause that filters on all of the tables columns. Now that seems like a
04:45bit of overkill, but the reason the code is generated in this manner is
04:49because every database has it's own unique way of retrieving the most recently
04:54assigned auto incremented primary key value. You should select the approach for
04:58your particular database and modify this code accordingly. For example on SQL
05:03server you might change it to select the Add at Identity Value and assign it to a value.
05:09Again look at the documentation for your particular database to see how to
05:13retrieve a recently assigned auto increment value. The last two functions are
05:18named update and delete, the update function receives a Bean Object and
05:23executes a conventional update statement and the Delete function also receives
05:28a Bean Object and it executes a delete SQL Statement, to remove a record from
05:32the database. So that's the DAO component.
05:36Finally let's look at the Gateway. The Gateway component contains the methods
05:41that are designed to be called directly by the Flex Application. There is a
05:45method called Get ID that allows you to pass in a primary key value and
05:49retrieve a single object. There is a Safe Method that allows you to pass in a
05:54Bean Object and detects whether it's a new or existing data object based on its
05:59PERSONID value. If the value of the primary key is zero, it assumes as it's a
06:04new object and calls the DAO class' create method. Otherwise it assumes, it's
06:09an existing object and calls the DAO object's update method. Again notice that
06:14these functions have an access property of remote, which means that we can call
06:18them directly from the Flex Application.
06:21There is a function named deleteById, which receives a primary key value and
06:26calls the DAO Object's delete method and two methods for retrieving all the
06:31data from the table. One named getAll that executes a query against the entire
06:35database and then creates an array of instances of the value object or the Bean
06:41Object and returns that. Then another one called get all as query, that returns
06:46the query object directly. These are the two functions I am going to describe
06:51using from a Flex Application, now in the next video I am going to describe how
06:55to use these two functions getAll and getAllAsQuery and show you the
06:59differences between the functions and how they are actually handled, when the
07:03data is returned to Flex.
Collapse this transcript
Retrieving data with the generated code
00:00In this video, I am going to describe how to call public functions of the
00:04ColdFusion component generated by the ColdFusion value object wizard. I am
00:09going to use the application from the Chapter08Begin project that I created
00:13earlier named UseCFWizardCode.mxml. This application currently has only a label
00:20that displays the text ColdFusion Wizard Code.
00:24Start off in the application by creating RemoteObject component and set it's id
00:29to personGateway. This will be a RemoteObject component that refers to the
00:34Gateway component on the server. Set it's destination as I described in the
00:39previous chapter on using ColdFusion components from Flex. Set the destination
00:44to ColdFusion. Pay attention to the case and spelling. It should be spelled
00:49with an upper case C and F and no spaces.
00:53Now add the source attribute. The source is determined by the location and name
00:58of the ColdFusion component on the server. Go to your CFEclipse project which
01:03on my system is named Flex3btbCF. Open the CFC folder and then select the file
01:10PERSONGateway.cfc and double click to open.
01:14This again is the Gateway component that you will be calling directly from
01:17Flex. Now browse the component so that you can look at the component's
01:21documentation. Go to the CFEclipse toolbar and click the number 1 to open in an
01:28external browser. You will need to type in your RDS or Administrative Password
01:33for ColdFusion and then Login and then you should immediately see the
01:38documentation for the new component.
01:41Notice again that the component has five functions, each marked as remote and
01:46each describing what you pass in and what you get back. For example, the
01:48getAll function returns an array of Person components which you will see right here.
01:55The getAllAsQuery function returns a query object. The getById function returns
02:02a single instance of the being or value object component and the Save function
02:08receives a single object and either updates or creates that object in the database.
02:14Go back to the top of the documentation and locate the fully qualified name and
02:19location of the Gateway component as it's known to ColdFusion. Select and then
02:25Copy that to the Clipboard then close the browser and return to Flex Builder,
02:31go back to the Application and then Paste that information into the Source
02:36Property of the remote object component declaration. This is now a RemoteObject
02:41that points to the Gateway object.
02:44Next, create a Script section above the RemoteObject tag set. Within the Script
02:50section declare a new variable named acPerson data typed as an Array
02:55Collection. When you select the Array Collection class from the list of
02:59available classes, Flex Builder should automatically add an import statement
03:03for the class for you. Next, add a resultHandler function. Declare the function
03:10with the Syntax private function resultHandler. Set up the resultHandler
03:16function to receive an event argument typed as ResultEvent and return void.
03:23Now go down to the RemoteObject component and add a resultevent listener using
03:28an attribute and call the resultHandler function passing in the event object.
03:34The final step in this part of the process is to go to the Application tag and
03:38add an applicationComplete event listener and here, I am going to call one of
03:43the two functions that returns all of the data from the server.
03:47The first is going to be the getAllAsQuery function which returns an actual
03:51query object. Use this syntax personGateway.getAllAsQuery(). Remember to add
04:00the opening and closing parenthesis after the function name. I am going to
04:05reformat the code here, so we can see all of it on the screen at the same time.
04:09So as the application starts up, it's going to make a call to the ColdFusion
04:14server and when the data is returned this function named resultHandler will be
04:18triggered.
04:20Add a breakpoint at the line that contains the finally brace of the function on
04:25my system it's at line 16. Save and Run the application in Debug mode. So that
04:31you can inspect the data that returns from the server. When the data is
04:36returned from the server, you should be triggered to open the Flex Debugging
04:39perspective in Flex Builder.
04:42Now go to the Variables View and expand it to Full Screen by double clicking
04:45its tab. Go to the event object which is data typed as the ResultEvent class,
04:52Open it to see its properties and go to the Result. Notice that because the
04:57ColdFusion Code returned a query object, the result is data typed as an Array
05:02collection. The ArrayCollection contains multiple objects each of which
05:07contains the various properties from the database table.
05:11Now restore the variables view and terminate your Debugging session. On some
05:15systems that will also the browser and then expand the code to full screen and
05:20let's make a change. Go back to the application complete function and this
05:25time, instead of using the getAllAsQuery function call the Gateway components
05:29getAll function which returns an Array rather than a query. Save your changes,
05:36once again, run the application in Debug mode. As the application starts up it
05:42makes the call to the server and then because I am already in the Debug
05:45Perspective it brings me immediately to Flex Builder when I hit the breakpoint.
05:51The next step is to restore the size of the editors if they come up in this
05:55fashion. You can click this Restore right next to the tabs and then go to the
06:00Variables View and double click to expand and this time, you should see that
06:05the returned data comes back as an array rather than an ArrayCollection.
06:10Notice however, that the individual objects that are returned as the part of
06:14the array are typecast as object, rather than as that strongly typed Person
06:20class that we had seen created before and here is why. Once again, I will
06:25return to the code and terminate the debugging session. We have an action
06:30Script class named PERSON.as which was generated by the ColdFusion wizard.
06:35This value object component automatically has been populated with the
06:39declaration named RemoteClass which has an alias pointing to the component on
06:44the server including at both its CFC name and its package. This is a two-way
06:50mapping that tells Flex and ColdFusion, when you pass an instance of this
06:54ActionScript class ColdFusion, it should be transformed into the ColdFusion
06:58component of the same name and when an instance of that component comes back
07:02from ColdFusion, it should be transformed into the ActionScript class. So all
07:07the code in place, why isn't it working?
07:11The answer is because unless you have actually declared at least one instance
07:15of this ActionScript class in your Flex application, this mapping that I have
07:20selected isn't a part of the application. In order for the mapping and the
07:24action script code to be a part of the application, you must declare at least
07:28one instance of it.
07:29So I am going to come back to the main application code. I am going to return
07:33to the application and to clear one instance of the component using this code,
07:39private var currentPerson and then I will data type to PERSON which is the name
07:46of the ActionScript class that was generated by the ColdFusion wizard.
07:50Notice that I am not actually instantiating the class, I am just declearing an
07:54instance of it and that's enough to add the class definition to the compiled
07:58application including it's two-way mapping. I will Save the changes and run the
08:03application in the Debug mode one more time. Once again is the application
08:08start should makes the call to the ColdFusion server and upon the data is
08:12returned, we hit the breakpoint.
08:14I restore the size of the various editors and then go the Variables view and
08:19now notice that the Array contains multiple instances of the person class.
08:24That's exactly how you want to store the data in your Flex application. So one
08:30final step, I will terminate the debugging session and go back to the
08:33application code. Within the resultHandler function, I am going to fill in the
08:38value of array collection using this syntax acperson = new ArrayCollection and
08:46I am going to pass in the event.result property as an Array. I know that I am
08:54getting back in array because I debugged and inspected the data and because the
08:58compiler expects event.result to be an object, I have to exquisitely typecast
09:04it as an Array here and then I pass it into the ArrayCollections constructor
09:08method and now the data is an ArrayCollection that can manage the data at runtime.
09:13I place the cursor after the label and add a DataGrid component to display the
09:17return to data and I will set its data provider using a binding expression to
09:21the ArrayCollection, acPerson. I'll Save the changes and this time I am going
09:27to run the application in normal mode and as the application starts up, it
09:32retrieves the data from the server and displays it in the DataGrid.
09:37What you now have in memory is an ArrayCollection containing multiple instances
09:41of the strongly typed value object class person. In the next video, I will show
09:46you how to use that data that you now have in Flex application memory to allow
09:50the user to view and modify the data that's managed by the ColdFusion server.
Collapse this transcript
Modifying data with the generated code
00:00In this video, I am going to describe how to incorporate code that was
00:04generated on the server by the ColdFusion Value Object wizard, that allows you
00:08both to retrieve and display data, but also allows you to send commands to the
00:12server to modify the data in databases that are managed by the ColdFusion
00:16server. For the demonstrations in this video I will use some prepared code that
00:21you will find in the Exercises folder.
00:23If you have access to the Exercises folder and you are following along with the
00:26Exercises, go to the Exercises folder which I have installed on my desktop and
00:31from there to the Chapter08 folder and from there to Chapter08Begin. You will
00:37find three folder in one file named ModifyData.mxml. Select all three folders
00:43and the Application File and copy them to the Clipboard. Then go back to Flex
00:48Builder go to the source folder within the Chapter08Begin project and paste the
00:54folders in file. Then navigate to the ModifyData.mxml application file, right
01:01click on it or Control+Click on the Mac and select Set as Default Application.
01:05That will cause the application to be compiled and be ready to use. Then double
01:11click the file to open the application code in Flex Builder. This application
01:16already has an instance of the RemoteObject component that makes a call to the
01:20CFC function on the server to retrieve data.
01:23When the user runs the application, they see the data filled in and displayed
01:28immediately in a DataGrid control. They can then select a row from the DataGrid
01:32by double clicking on it and that results in presenting the data in a data
01:37entry form. The data entry form control itself is a custom component and it is
01:43stored in the Forms folder within the Project Source. When the user clicks the
01:48Save button any changes that are dispatched to the rest of the application in a
01:52custom event named the Person event and you can handle that event and send the
01:57data to the server.
01:59Let's take a look at the code. I'll close the browser and returned to Flex
02:03Builder. At the top of the application, there is a declaration of a State. This
02:10is how the data entry form is being presented. When the user double clicks on a
02:14row of the DataGrid that results in calling a method named editRecord and this
02:19method passes the selected item from the DataGrid into the form using its
02:23current person public property and changes the current state to detail.
02:28Let's take a look at the Form. In the Form component, there is a Metadata tag
02:34set that defines two events, one named save and other named cancel. When the
02:38user clicks the Save button, it calls the saveRecord functions, which saves all
02:43of the data from the input controls into a new instance of the person object
02:47and then wraps it inside a custom event object and dispatches it.
02:51This is the data that we want to send to the server. Go back to the application
02:57and locate the component named PersonForm, notice again that we are calling a
03:01method called saveRecord which is an empty method within the application. Place
03:07the cursor within that method. The event object that's dispatched to this
03:12function will be an instance of the person event class which in turn has an
03:16instance of the person object.
03:18So first declare a variable named person and data type it as PersonVO which is
03:25the version of the Value Object for this application and get its value from the
03:31expression event.person. Now place a breakpoint on the last line of the
03:35function that is the line with the closing brace and run the application in Debug mode.
03:40When the data appears, double click on one of the items, make a change such as
03:50changing the name Miriam to Mary and then click Save. That should take you to
03:56the breakpoint that you placed in the saveRecord function. Go to the debugging
04:02perspective and then to the Variables view and take a look at the value of the
04:07person variable.
04:08You will see that it's an instance of the personVO and whatever data values you
04:12changed in the form should be reflected. Now restore the variables view and
04:17then click the Resume button in the debug view, switch back to the application
04:22and click the Cancel button that will take you back to the list.
04:26This time, click the New button, you will see the form opens with blank values,
04:32click the Save button, that will take back to the breakpoint and once again,
04:36view the value of the person variable and this time, you will see it's starting
04:40off with blank values. Again, these are the values they are coming from the
04:44data entry form, but they are the Default Values of the value object.
04:48So here is how you are going to save the data to the server. Once again,
04:52restore the variables view and terminate debugging and then go back to the
04:57Code. The ColdFusion component that's designed as the Gateway on the server has
05:03a function called Save. It's designed to receive the single instance of this
05:07Value Object. So I am going to call that CFC function with this syntax,
05:13personGateway.save and then I will pass in the person object.
05:18Now let's go to the RemoteObject declaration. Notice that there is already a
05:23function saveHandler, it's an empty function that's already been declared and
05:27it receives an event object typed as ResultEvent. Break up the RemoteObject
05:32declaration into a begin tag and an end tag and then add an mx:method complier
05:37tag with the name of save and a ResultEvent handler that calls the method
05:43saveHandler and passes the event object.
05:47Now go to the saveHandler function and when the data has been saved to the
05:51server, you can react by refreshing the view of the data and making a call to
05:56get all records again, using this code, personGateway.getAll. Now here is the
06:02logic that we are using, the mx method tag declares a ResultEvent listener for
06:08that particular method, the Save method, but the getAll method doesn't have its
06:13own mx method tag at least at this point and so it's going to use the Default
06:17Result listener for the RemoteObject component.
06:21Let's watch the results. Save and Run the application this time in standard
06:26mode, select any item from the person list and just double click on it to open
06:33it in the Form and make a change. For instance, I am going to have this guy
06:37move from Syracuse to New York city and I click the Save button and then take a
06:44look up here in the Form and you will see that his city has changed to New
06:48York, but also notice that I haven't cleared the form or restored the ability
06:52to get to that List Control.
06:54So I have one more little bit of code to add in this saveHandler function. I am
06:59also going to Reset the current state back to the default or Base State using
07:04this code currentstate = null. You can set the current state either a blank
07:10string of "" (quote quote) or to null, that will have the same effect. I will
07:15run the code again and test again. I once again double click on Brad Lang, this
07:22time I will set his city back to Syracuse. I will save and after just a moment
07:29you will see that the data is refreshed from the server.
07:32Now let's try adding a new record. I will click New and I will add some data. I
07:37will set the Name as Adam and the Last Name as Aardvark and I will give him an
07:43address and you can type anything at this point and then click the Save button
07:50and then sort the data by Last name and you should see that the new row has
07:54been successfully added to the database.
07:57Now let's take a look at deleting data. If you go down to the bottom of the
08:01application, you will notice that there is a button with the label of Delete,
08:05which is calling a method called deleteRecord. Let's go to the deleteRecord
08:09method and you are going to call a remote CFC function called deleteById. It
08:14will look like this, personGateway.deleteById and then you are going to go get
08:19the selected item from the DataGrid and it's PERSONID property and pass it in.
08:24The code will look like this. PersonGrid.selectedItem.PERSONID.
08:32I am uppercasing the name of the property because that's how it's returned from the
08:35server and that's how it's stored within the component.
08:39I make those changes then notice that there is already a function here called
08:45deleteHandler. I'll add a new mx method complier tag for that method and I will
08:51set the name as deleteById and set the result to deleteHandler and once again,
08:59pass the event object. Going back to the deleteHandler, I will copy the code
09:03from the safeHandler function that refreshes the data from the server and paste
09:09it into the deleteHandler and now once again, after the data has been deleted
09:12from the server, I am going to recall the data from the server and display it all.
09:16I will run the application again. After the data has been loaded and has been
09:21displayed in the application, I once again sort on the Last Name column, select
09:26Adam Aardvark and Delete and you will see that the data is now gone and if I
09:32re-sort you will see that Adam Aardvark is no longer in the database. So this
09:37is how we use the code on the server. To retrieve all of the data, you use the
09:41getAll method, to save either new or existing data you call the Save method and
09:47to remove data from the server side database you call deleteById and passing
09:51the primary key value of the row that you want to delete.
Collapse this transcript
Defining RemoteObject channels at runtime
00:00In this video, I am going to describe how to define a channel at runtime
00:05through which you communicate with the ColdFusion Server. A Channel is a
00:08definition of how to communicate and where to communicate when you send a
00:12remote object request, using the remote object component in a Flex application
00:17and a CFC on the ColdFusion Server.
00:20By default, the Channel is defined in a file in the ColdFusion server called
00:24services-config.xml. Let's take a look at that file. I am going to select File
00:30Open and then I am going to navigate to the WWW root folder under the
00:34ColdFusion8 installation. Under that folder go to WEB-INF, from there to Flex
00:42and from there to a file named services-config.xml.
00:48This is the file that configures all of your ColdFusion functionality and in
00:52fact, this file is bound into your project in Flex Builder and it's how the
00:56ColdFusion destination is known to the remote object component in your Flex
01:01application. Within the services-config file there is a setup what are known as
01:07channel-definitions and the default channel-definition that you use with
01:11ColdFusion is down here under cf based endpoints. It's a definition with an id my-cfamf.
01:21The endpoint within the channel-definition defines the location of the server
01:25to which communications are sent at runtime as the same server from which the
01:29Flex application is downloaded. That's what these dynamic expressions are doing
01:33in the URI property, and then the URI ends with the URL pattern that is then
01:39used by ColdFusion to detect when a Flex communication is coming in as opposed
01:44to a conventional browser request.
01:47So it's possible to create your own channels within an application and not use
01:52the channels that are defined say, in the services configuration file. This can
01:56be especially important if you are working with an application that's delivered
02:00over AIR, the Adobe Integrated Runtime, as a desktop application, where you
02:04don't download an application from a server at runtime and don't have access to
02:08this dynamic information.
02:11So in this video I want to show you how to define one of these runtime channels
02:15in your Flex application using mxml code. I am going to return to the Flex
02:21Development perspective and then reopen the file ModifyData.mxml. This is the
02:27application that I worked on in the previous video, then I will navigate down
02:31to the remote object component which is about at line 74 in my version of file
02:36right now. In order to define a channel, you first create something called a
02:42channel set. It's actually possible to create a set of channels and then the
02:47RemoteObject component will try each channel in turn until it finds when it can
02:51communicate with.
02:54Place the cursor after the Remote Object start tag and make a little bit of
02:58space before the method declarations, then declare an mx channelSet property
03:04using child element syntax. That means we are using a paired tag. Now within
03:09the channelSet tag, declare another channelSet, but this is with an upper case
03:14C meaning that it's an instance of an actual class. Once again, declare this
03:19with a pair of tags and now you are ready to declare the actual channel that
03:25you will use to communicate with the ColdFusion server.
03:27We are communicating over AMF, Action Message Format, the binary messaging
03:33format that allows communication between a Flex application and ColdFusion to
03:37be very fast and very small. So we are going to use a class called AMFChannel.
03:44Declare the AMFChannel tag and then set its URI property.
03:49The URI property should start with the absolute address of the ColdFusion
03:53server with which you want to communicate like this,
03:56http://localhost:8500/flex2gateway/ and then end it with Flex 2gateway just
04:05like you saw in the services configuration file. Close the AMF channel tag,
04:13Save your changes and run the application again. As the application starts up,
04:19it should once again display the data, but this time we are configuring the
04:23location of the ColdFusion server as the application starts rather than
04:27depending on the version that's in the services configuration file.
04:32Now as I mentioned, there is a section in the Project Properties that indicates
04:36which configuration file is going to be used. Go to the Menu and select the
04:40Project, Properties and from there go to the Flex Compiler section. Notice in
04:47the Flex Compiler section there is a Services property that's pointing to the
04:52Service-config.xml file, that's in the WEB-INF folder under your ColdFusion
04:56document root.
04:58So that's how all the configurations are being bound together. This
05:02configuration file is actually compiled into your application. So the
05:06definition where of your ColdFusion server is a part of the application. By
05:11using runtime channel declarations, you can overwrite those settings and to
05:16clear at runtime which ColdFusion server you want to communicate with.
Collapse this transcript
Managing an asynchronous state with AsyncToken
00:00In this video, I am going to describe how to use a class called AsyncToken
00:04which allows you to track the state of objects between the time you send a
00:08request to a server, using a RPC components such as the RemoteObject Component
00:13and the time the response comes back. For this demonstration, I'll continue to
00:17work on the application file ModifyData.mxml.
00:21Right now in this application, whenever we save or update data and a response
00:25comes back from the server, we are reacting by refreshing all of the data from
00:29the database in the server by calling the Gateway components getAll method
00:32again. This is a bit of overkill.
00:35We have only modified one row of the database table and yet we are retrieving
00:39all of the data from the server. By using the AsyncToken class to track the
00:43State between the time you send the request and the time you get back the
00:46response, you can fine-tune in the way you react to these events and only deal
00:51with those single data objects that was modified or deleted. Here is how you
00:54use the AsyncToken class.
00:57Start off at the ActionScript code that's making the call to the remote CFC
01:01function. I am going to the saveRecord method which has a call to
01:05personGateway.save. Every time you make a call to a remote function using our
01:09RPC component you get back reference to an AsyncToken object. The nature of an
01:14AsyncToken is that it's a dynamic object to which you can add as many arbitrary
01:19named properties as you want.
01:21The first step is to get a reference to the token, like this. Place the cursor
01:25before the code personGateway.save, make an extra line and add this code var
01:31token data typed as AsyncToken = and then indent the next line of code because
01:39you are getting the reference from the call to the remote CFC function. Now you
01:43have a reference to the token and you can add as many named properties as you
01:47want. I only need to add one. I am going to add a reference to the actual value
01:52object that I send to the server. The code will look like this, token.person =
01:59person. Now I have saved a reference to that in memory data object and I'll be
02:04able to get it back when I get a result event back from the server.
02:07Go down to the saveHandler method. Right now we are recalling the getAll CFC
02:13function and refreshing all of the data. We don't need to do that, so I am
02:16going to comment out that line of code and then make a little bit of extra
02:20space between that and the change to the current state. Now, I am going to get
02:24a reference to the person object that I sent off to the server using this code,
02:29var person data typed as the value object class I am using for this application
02:35PersonVO = event.token.person.
02:41The token property is a member of the ResultEvent class. Every time an RPC
02:46comment dispatches a result event. You have a reference to the AsyncToken
02:50object that's associated with that event and because I had added the person
02:54property to the token earlier, when I sent the request to the server it's still
02:58there when the result event is dispatched.
03:01Now I am going to inspect the person object and find out whether I would send
03:05in a new object or an existing object using this conditional code. If
03:10person.PERSONID == 0. So if the PERSONID property is 0 that means it was a new
03:18object and then I'll add an else clause to handle existing objects.
03:23Now if I sent an object off to the server, it started off with a primary key of
03:280, but when it comes back from the server, it is actually going to have the new
03:32automatically assigned primary key that was assigned and created by the
03:35database. If you go back to the Gateway code, you will see that the Gateway
03:39code always returns an instance of the person object and if you called the
03:44Create method, you will get back to Person Object with the new primary key.
03:48So here is how I am going to handle new data, instead of using the existing
03:52person variable, I am going to use the version that comes back from the server.
03:56So I'll say person = events.result as PersonVO. Then I am going to manage the
04:04Datagrid's appearance. First, I am going to set at selected item to this data
04:09object because it's now in the Array collection which the DataGrid is
04:12presenting and then I am going to make the DataGrid scroll to the correct location.
04:16I'll use this code, personGrid.slectedItem= person and then in a separate
04:24statement personGrid.scrollToIndex and I will pass in the current selected
04:31index of the grid which is now already set because I already set the selected
04:35item. Now in the other condition where I passed the Value Object to the server
04:44to make a change, once again, I am going to get back that object from the
04:47server, but this time I am going to replace in the correct position in the
04:51Array collection using this code. acPerson.setItemAt, then I am going to pass
04:57an event.result as PersonVO and then I'll pass in the currently index of the
05:04grid to indicate where I want to put it, PersonGrid.selectedIndex.
05:13So I am replacing the old data in the local dataset with the version they came
05:17back from the server. I will save my changes and run the application and let's
05:21take a look at the result. I will select and double click on the first row of
05:26the DataGrid to edit it's details then I will change some of the data. This
05:30time I will change his name from Lang to Smith and I will Save and once again
05:37you see that the data has changed in the DataGrid, but this time, it didn't
05:40require another round trip to the server and it didn't require retrieving all
05:44the data from the database table.
05:47Now I will add a new item to the database. I will put in once again Adam
05:52Aardvark. I will click Save and this time notice that I scrolled to and
05:58displayed the row that I want the user to see. So I no longer have to sort or
06:03otherwise, navigate to the right row. Now handling Delete is very similar, I
06:07will go back to the code to the method deleteRecord and I am going to repeat
06:11the same pattern.
06:12When I call the remote CFC function I will get back a token. So I am going to
06:16once again declare a variable data typed as AsyncToken var token datatyped as
06:23AsyncToken = and then I am going to get that reference from the call to
06:30deleteById. Now I am going to add a property to the token object. In order to
06:35remove an item from the Array collection in the Handler, I am going to have to
06:39know the index of the currently selected row in the DataGrid. So here is the
06:43code for that, token.index = PersonGrid.selectedIndex.
06:50Now go down to the deleteHandler function. Once again, comment out the call to
06:54the getALL method, we won't need to do that anymore and instead put on a call
06:58to the acPerson, Array collection object and call it removeItemAt property and
07:04pass in event.token.Index and that's going to be the Index that was passed into
07:10the token object, when I made the call to delete the record from the database
07:13at the server level. Save your changes, run the application. When the
07:19application starts up, go to any row of the database. I am going to sort by
07:23Last Name and get to the row that I had created earlier. I will click the
07:27Delete button and you will see that the data is removed both from the server
07:31and from the client. But once again, without requiring that additional round
07:35trip to the server and without requiring loading all of the data from the
07:38server back in to the client.
07:40So that's a look at how you can use the AsyncToken class to manage information
07:45and state between the time you send a request to the server and the time you
07:48get back a response. You can add as many named properties that reference
07:52whatever kind of objects you need to track and use that information to manage
07:56the visual presentation of your application and reduce the number of calls you
08:00need to make to your server.
Collapse this transcript
9. Integrating with PHP
Installing WAMP on Windows
00:00In this chapter of the video series, I am going to describe strategies for
00:04integrating Flex Client application with PHP. In Flex Builder 3, Adobe systems
00:09has now provided tools that allow you to inspect MySQL databases that are
00:13exposed through PHP and then generate Server-Side PHP code, that you can easily
00:18integrate into a Flex Client application that in turn, allows you to view data
00:22and modify data on the server quite easily.
00:25For the exercises in this chapter, i'll be using PHP 5 in MySQL and I'll be
00:30using a bundle of server options known as WAMP on Windows or MAMP on the Mac.
00:36In this video I'll describe how to install up the Windows version knows as WAMP
00:40for Windows Apache MySQL and PHP and in this next video I'll describe how to do
00:45the same thing on the Mac with MAMP.
00:47The first step is to download the WAMP installer. You can find the WAMP
00:51installer and download it for free from this URL, www.en.wampserver.com. I have
00:58already downloaded the software to my desktop. The version I found was
01:02WampServer2.0C.exe. Before you install WAMP you should first make sure that you
01:08don't have any other web servers that are listening on Port AD that's the
01:12default port that's used for example by internet information services. When you
01:17install the WampServer bundle, the Apache Server that's a part of that
01:20installation will listen on Port AD and if you have a web server that's already
01:24listening on that port, it can generate a conflict.
01:26I am working on a system that does not have any other web services installed
01:30right now. So I am going to go ahead with the installation by opening the EXE,
01:35stepping through a set of information on warning screens and then coming to the
01:40welcome screen. After the welcome screen there is a License Agreement, which is
01:45based on the GNU, General Public License. Essentially, it means that you are
01:49free to use this server without having to pay any fees.
01:53After the license screen you are asked where to install WAMP. The default
01:57location is in a folder named WAMP under the C drive root. I am going to accept
02:02that default setting and throughout all of the demonstrations in this chapter,
02:05I'll be assuming that my code for the server is in this physical location. I'll
02:10go to the next screen and check a couple of options. I am not going to put in a
02:14Quick Launch Icon or Desktop Icon and I don't need them and I'll click through
02:18and complete the Installation.
02:20The installation of WAMP takes about two minutes. Once the installation is
02:24complete you will be ready to fire up the server which you will be able to do
02:28from System Tray Menu that you can click on in the lower right hand corner of
02:32the Windows interface.
02:35Once the primary installation is complete, the WAMP Installer looks for a web
02:39browser. If it finds Firefox, it asks if you want to use it as is shown here on
02:44the screen. I'll click Yes and now whenever I navigate to the Home or
02:48Configuration pages of the WampServer bundle, I'll be using the Firefox browser.
02:55The next step in the installation process is to enter an SMTP server and
03:00address an e-mail. If you want to be able to use the mail function on PHP. Now
03:04I don't have an SMTP server on this system and I don't really care what the
03:08primary e-mail address is because I won't be using that feature during these
03:12demonstrations. So I'll just accept the Default Settings and click Next. That's
03:16the end of the installation process. You have the option of launching the
03:19servers immediately. I am not going to do that because I want to show you how
03:23to launch the WampServer later on once you have installed it and need to get
03:26back to it again. I'll click Finish and now I'll go to the Windows Menu and I
03:32will click on All Programs and locate the folder WampServer. From there, I'll
03:38locate the Menu item start WampServer and select it.
03:41When you start the WampServer bundle, you will see a System Tray icon in the
03:45lower right hand corner of your screen. It looks like a gauge and when the
03:49pointer on the gauge is all the way over to the right, that means your server
03:52is ready to use. You can click the gauge and you will see this Administrative
03:56Menu that allows you to control the services and get into the various
04:00administrative tools. For example, I am going to first select Put Online, which
04:05means I am going to make the server available, then I'll go down to the System
04:09Tray icon again and this time I'll select Local Host.
04:14Local Host takes me to the Homepage of the WampServer Bundle, where I can see
04:18the status of all the various services an also I can find links to the some of
04:21the most important programs. I am also going to go back to the Menu and show
04:26you that you can easily get into a web application named phpMyAdmin which
04:30allows you to manage your MySQL server. I will be using this interface in a
04:35later video when I show you how to import a database from an SQL file that's
04:39the part of the exercises for this video series. Now in the next video, I'll
04:43show you how to do exactly the same steps using Mac OS X.
Collapse this transcript
Installing MAMP on Mac OS X
00:00In this video, I am going to describe how to install MAMP, the Server bundle
00:04that includes Apache, MySQL and PHP for Mac OS X. There are two versions of the
00:09MAMP server bundle, MAMP Pro and the simpler MAMP. MAMP itself is completely
00:14free and can be used without registration or paying any license fees. You can
00:19download the MAMP bundle from the website I am displaying on the screen.
00:22www.mamp.info From the home page, click on the Download now button and then
00:29download the DMG installer. This installer includes the installations for both
00:34the PRO and the Standard version. Then, after you have completed the download,
00:39open the DMG file, review the license agreement and then if you agree, you can
00:43click the Agree button to continue. That results in mounting the disk image in
00:48the DMG file. Now to install MAMP simply drag the MAMP folder into the
00:53Applications folder. It takes just a moment to complete the installation.
01:00Then navigate to the Applications folder on your Mac hard disk. Then from there
01:05locate the new MAMP folder. Open the folder and you'll find an application file
01:11named MAMP. To run the MAMP Server at any time just open the MAMP application.
01:16As long as you have the MAMP server running you will have access to MySQL,
01:20Apache and PHP. When you first install MAMP, it is configured with custom
01:26ports, typically you'll want to go back to the standard ports that are
01:29conventionally used with Apache and MySQL and here is how you do that. I am
01:34going to close the browser and all other windows and show you that there is
01:37actually a MAMP application window that's opened in the background. From this
01:41MAMP application window, I'll click the Preferences button. Then I will click
01:45the ports item at the top of the screen. Notice the custom ports that are
01:49assigned to both Apache and MySQL.
01:52In order to work seamlessly with Flex Builder, you'll want to switch to the
01:55standard ports that are normally associated with these applications. Click this
02:00button, set the default Apache and MySQL ports and then click OK, that will
02:06cause both Apache and MySQL to restart. You may at this point need to type in
02:11your administrator password to continue along.
02:15In order to check the progress of starting the Servers, watch the indicator
02:18lights on the screen. You can also make changes to the configurations in a
02:22number of different ways. Other options available in Preferences includes
02:27certain PHP options and also certain options for Apache. Notice for example,
02:32that by default the root documents folder for the Apache server is located
02:36under- /Applications/mamp/htdocs. This will be a critical bit of information
02:42that you will need later on, when you set up a Flex Builder project for use
02:46with PHP. I'll be mentioning in a later video that the document route which
02:51points here to /Applications/mamp/htdocs is the folder in which you create your
02:55PHP output folder, when building a Flex project. You can also start and stop
03:01the Servers from the screen. You can click the Stop Servers button and that
03:05will stop both Servers and then you can click the Start Servers button again to
03:09restart. It's also important to know how to get into a utility named
03:13phpMyAdmin. phpMyAdmin is a web interface that allows you to manage your MySQL
03:19server. To get into phpMyAdmin or any of the other web page utilities, click
03:24the Open start page button and then from there look at the links at the top.
03:29Here is the link to phpMyAdmin. I will click it and it will show the
03:33administrative interface for MySQL.
03:34You will be using this interface later on to import a database. When you are
03:40done with MAMP just quit the Application, that shuts down the Servers and
03:45allows you to continue with your other work. Here is one other important tip
03:50about working with MAMP. If you go to your System Preferences and from there to
03:54Sharing. Check the Web sharing option. Mac OS X, includes a copy of the Apache
04:00web server. If you have web sharing turned ON on your Mac, it might conflict
04:05with the MAMP server depending on how it's configured.
04:08So if you are having trouble getting the MAMP Server started, check this
04:11option, again it's under System Preferences, Sharing and make sure that you
04:15have this Web Server turned off and then your MAMP installation should work fine.
Collapse this transcript
Importing a sample database
00:00In this video, I am going to describe how to import a sample database into the
00:04MySQL Server that's a part of the WAMP or the MAMP Server bundles. If you have
00:09access to the exercise files and you have already installed the WAMP or MAMP
00:13servers, you will be ready to follow these steps.
00:15The exercises files contain a sub folder named Assets/PHP and within this
00:22folder you will find a file called contacts.sql. The contacts.sql file contains
00:27a set of SQL statements that first looks for a table named person and drops the
00:32table if it exists and then recreates it. The database structure is listed here
00:37in this SQL statement. There is a primary key named personid, that's an integer
00:41value and auto increments and then a set of variable character or string
00:45columns that allow you to enter various values. At the end of the file there is
00:50an insert statement that adds one 1000 rows of data. So we have a good
00:53significant amount of data to work with. Here is how you use this SQL file.
00:58First go to phpMyAdmin, this is a web based application that's included with
01:03both the WAMP and MAMP installations. That allows you to manage the MySQL
01:07Server, that's a part of the server bundle. To create a new database, click
01:11into the text field with the label Create new database and then type the name
01:15of the database you want to create. I am creating a database named contacts.
01:20Click the Create button and then once you reach the screen indicating that the
01:24contacts database has been created. Click the Import link at the top of the screen.
01:29Now create the database table using the SQL file, click the Browse button and
01:35navigate to the Assets/PHP folder within the exercises area. Select the file
01:40contacts.sql and click Open and then within the web based interface click Go.
01:47It takes just a few seconds to complete the import of the database table. Once
01:51the database table has been created and its data has been added, you will then
01:55be able to browse the database table using phpMyAdmin once again.
02:00To view the data go back up to the top of the screen and click the database
02:03link for the contacts database. You should now see the person table listed and
02:08you can click the first link next to the name of the table which is the Browse
02:11link and you will be able to see that the data that was listed in the SQL file,
02:15is now in the database and ready to use. So those are the steps for creating
02:19the database table and populating it with data. If you don't have access to the
02:23exercise files, you can create the same database structure using the phpMyAdmin
02:28interface and add some sample data. Now in the next video I will show you how
02:32to link up to this database from within Flex Builder and start to create PHP
02:36code that allows you to integrate these Servers with Flex Applications.
Collapse this transcript
Creating a Flex/PHP project in Flex Builder
00:00In this video, I am going to describe how to create a Flex Project in Flex
00:04Builder 3, that's integrated with the Application Server PHP. If you are
00:08following along with the exercises, first make sure that you have installed
00:11either WAMP on Windows or MAMP on Mac and then, that you have the Server running.
00:16Before you can create a project correctly, you must know where the root
00:20document folder is for your Application Server. This will differ depending on
00:24operating system and how you have PHP installed. On Windows, if you are using
00:29the integrated Server bundle WAMP, you'll find that the WAMP folder, where the
00:33product is installed, has a sub folder named www. This is the Root document
00:38folder for the WAMP installation.
00:41When you create a new Flex project, you'll want to create the output folder for
00:44that project, that is, the folder where you are outputting the Debug version of
00:48the Application into a folder underneath this www directory. If you are working
00:53on Mac OS X, with the Mac Server bundle, using the default directory, the
00:57location of the same document root is under /Applications/MAMP/htdocs. With
01:04both Server bundles you can reconfigure and point to a different root folder,
01:08but these are the default locations. So once you have that information, the
01:12document root of your Application Server and its hosting Web Server, then you
01:16are ready to create a new Flex project that's integrated with PHP.
01:20Here are the steps, from Flex Builder's Menu select File, New,Flex Project. Set
01:27the project name as anything you like. I am going to set the project name here
01:30as Chapter09Begin. The location of the project itself can be anywhere on disk
01:35and I am going to use the default location, which is a folder with the same
01:39name as the project, underneath the current workspace. Set the application type
01:43to Web Application. Now pull down the list of available Server Types and select
01:48PHP. Click the Next button.
01:51Now you have to provide the Web root folder and the Root URL. The Web root, as
01:55I mentioned is the location of your document root folder as configured under
01:59Apache and PHP. My root folder is c:\wamp\www. Now set the Root URL. Under
02:08WAMP, the listener port is port AD. So you can put in a Root URL of simply
02:12http://localhost. If you are working in the MAMP Server bundle, you'll either
02:18be using its custom port or more likely you'll have reconfigured MAMP to use
02:23port AD as well. Click the Validate Configuration button and you should see the
02:28message, the Web root folder and root URL are valid. If you see an error
02:32message of any type, check to make sure that your Server is running and also
02:35that you don't have another Web Server running on the same system, listening on
02:39the same port.
02:40Now check the recommended output folder. The output folder is placed by default
02:44as a sub folder of your Web Server document root. As usual the name of the
02:49output folder defaults to the same as the name of the project, in this case
02:52Chapter09Begin and ends with dash debug to indicate that this folder will
02:56contain the output version of the finished application. Click Next, and in the
03:02following screen,which looks the same as for all web based Flex
03:05applications,set the Main Application File. I am going to set the main
03:10application file to FlexAndPHP.mxml and click Finish.
03:16After the application of project have been created, I'll double click on the
03:20Editor tab to take it to full screen and then I'll add a Label control. I'll
03:24set its text property to "Hello from PHP!" its fontSize to 18, so we can see it
03:31very clearly and its fontWeight to bold.
03:34I will also change the layout property for the application from its default
03:40value of absolute to vertical. I will save the changes and run the application
03:47and you should see if everything is working correctly, that the application
03:50loads in the browser and you can say the label "Hello from PHP!" and most
03:55importantly, the application is being downloaded from PHP and Apache at run
03:59time, rather than load it from the local disk. This will become critical as I
04:03start to send messages from the Flex application at run time to PHP to retrieve
04:08data and modify data in the MySQL database.
Collapse this transcript
Using Flex Builder's PHP Data Wizard
00:00When you want to integrate a Flex Application with PHP, there are a variety of
00:04methods available. You can make simple calls using the Http service component,
00:08for Example, to a PHP page. Have the PHP page returned well formed XML and then
00:14deal with that XML content either as a set of objects or with E4X.
00:19Alternatively, you can install an AMF library, which enables Flash remoting in
00:24PHP. PHP doesn't have AMF capability natively. But there are a couple of great
00:29libraries out there that you can select from. To use PHP and Flex together in
00:33the simplest fashion, you can use the Data wizard that's a part of Flex Builder
00:373. The Data wizard has the ability to introspect and get information about the
00:41structure of a MySQL Database table that's hosted by PHP and then it will
00:46generate a complete application, including both client and server side code.
00:51The client side Flex application that the data wizard creates, is a fairly
00:55trivial application.
00:56It provides very simple data entry without any real visual design or other good
01:01user interactions. But the server side PHP code that it generates consist of a
01:06complete, create, read, update, delete interface for a particular Database
01:10table. You can use the Data wizard, to generate one set of code for each of the
01:14Database tables in a Flex application. You would then write your own custom
01:18Flex code on the client and use the generated Server code. So in this video, I
01:23am going to show you how to run the Data wizard, show you how to connect to a
01:26MySQL Database from within Flex Builder 3 and then how to generate all that
01:30code for a particular database table.
01:33Here are the steps: before you use the Data wizard, you must have already
01:36created a Flex Builder Project that integrates with the PHP Server and I showed
01:40how to do that in the previous video. Then with that project open, go to the
01:45Flex Builder Menu and select Data, Create application from database. In this
01:50screen you select a data source. When you are using PHP. You can only select
01:55the Data Source that uses MySQL. I am going to click the New button to create a
02:00new Data source and I will name it contacts and click Next.
02:04Now I provide a database name. I named the database contacts in MySQL, when I
02:10imported the database table into the MySQL server. So I will put that value in
02:14here and then I will set the user name and the password. If you are working on
02:19Windows, using WAMP in its default installation, the password will be blank, if
02:24you are working on the Mac OS X and you are using MAMP in its default
02:27installation, the password will be the word root. After you enter the password
02:31will be the word root. After you enter the information,click the Test
02:32connection button. You should get the message, the connection was successful.
02:36If so, click OK and continue. If you weren't able to connect successfully, go
02:41back to the MySQL admin, Web based application and make sure that the MySQL
02:45Database is in fact running.
02:48Now click Next and review the information for your Database connection and
02:52click Finish. You are now ready to select a Database table and generate the
02:57code. Pull down the list of available tables. My Database currently has only
03:02one table named person and that person table has a primary key column of
03:07personid. That information has been detected automatically by the Data wizard.
03:12Click the Next button and now indicate where you want to place your code. The
03:17PHP source folder should be set to the same folder as the one in which your
03:21Flex Application is being output, that is, the Debug folder. So the Default
03:26location for the PHP source folder is bin - debug and I am going to leave it at
03:31that default selection. The PHP file name defaults to the same name as the
03:36table itself with an upper case initial character. You can rename this file if
03:40you like. For Example, I think this as a service page. So I am going to name
03:44the PHP file that I am going to be making calls to PersonService.php.
03:50Then click Next and then in the Final screen, first indicate which columns you
03:54want to display in a Data Grid in the Flex Application and then at the bottom
03:59of the screen, you can select a single column under which you want to be able
04:02to filter. For example, I am going to set filtering to the city column. Now you
04:07may think, I would like to be able to filter on more than one column. Once the
04:11Flex application has been generated, you will have the opportunity to customize
04:14the code to whatever extent you like.
04:16But this is the limitation of the Data wizard, it only creates a filter for a
04:20single column initially. Those are all the steps. Click Finish to generate the
04:25application. The application is generated with the name set as the name of the
04:30Database table. For example we reworking with the Database table named Person.
04:34So name of the Flex application is person.mxml. In addition to the Flex
04:39application code, there are also a couple of ActionScript files that are
04:42generated. I will describe those in more detail in the following video. In the
04:47bin-debug folder, a number of PHP and supporting files have been created. For
04:51example, here is the PersonService.php file, that's been placed in the folder
04:56underneath the PHP directory and then there are other files such as
05:00contactsconn.php, a sub folder named PEAR and another one called
05:06functions.ink.php. These new files are now a part of the file set that you
05:11would upload to your PHP server in order to deploy the application.
05:16Place the focus into the application, person.mxml and then click the button to
05:21run the application. As the application loads, it makes a call to the PHP
05:26Server, retrieves data and displays it in a Data Grid. The Data Grid is set as
05:32being editable, which means that you can click into any row and any column and
05:35make a change. I will click into the last name column of the first row and
05:40change the name from Brad Lang to Brad Smith. Click out of the row and that
05:45actually causes a Server-side communication that saves the data in the Database
05:49Server. I will also do a search-by-city. I will click into the search by city
05:54field at the bottom of the screen and type in Houston, Click the Search button
05:59with the magnifying glass and you will see that its filtered based on that
06:03city. You can also create a brand new record by clicking the plus icon. You can
06:09add new data into this data entry form and save it and once again the
06:13information will be sent to the Server and the data will be saved in the
06:15Database. So in the next video, I am going to describe a little bit more about
06:19how this application works, show you where all the code is and describe the
06:23particular approach that is being used in sending and receiving messages
06:27between Flex and PHP.
Collapse this transcript
Understanding the generated PHP code
00:00In the previous video, I described how to use the PHP data wizard, that's a
00:04part of Flex Builder 3, to generate a complete Flex application including both
00:08client and PHP Server side code. In this video, I am going to review some of
00:13the generated code so you can understand how you might be able to use this code
00:16in your own applications. The generated client side application as I mentioned,
00:21is simple, even trivial. It presents a basic Data Grid that shows all of the
00:26data from particular Database table. Allows filtering on a single column and
00:30allows you to add new rows as needed.
00:32Most of the work of the application is being done in this file personScript.as
00:38which is included in the main application through a script tag. Lets take a
00:42look at that ActionScript file.
00:47The ActionScript file has a set of imports at the top and then an include
00:51statement that includes another ActionScript file called personconfig.as. This
00:55is the simplest of the files. It has a single declaration of a public constant
01:00named ENDPOINT_URL, which points to the location of the Service PHP page, which
01:05I named PersonService.php. Because the application is being downloaded from the
01:10PHP Server at run time, the ENDPOINT_URL doesn't have to include the entire
01:15URL, that is it doesn't have to start with HTTP and so on. All you need to use
01:20is the name of the actual PHP page because the PHP page is stored in the same
01:25folder from which the application downloads at runtime, that will be the
01:29location to which HTTPService requests will be send.
01:33Going back to the ActionScript file, the next critical bit of code declares
01:37variable named gateway data typed as in HTTPService Object. Now in previous
01:42videos of the Video series, I have shown how to use RPC components such as
01:46HTTPService or remote object and declare them most of the time using MXML code.
01:52This ActionScript file gives you a great model for how you can use the
01:55HTTPService class and declare it and manage it completely in ActionScript. The
02:00ArrayCollection, dataArr will contain all of the data that's retrieved from the
02:05Server and then in the initApp method, all of the configuration of the
02:09HTTPService Object, that is, the Gateway variable is handled.
02:13The URL is set to the ENDPOINT_URL, that's the constant set in the
02:17configuration file. The method is set to post. Use proxy is set defaults and
02:23here is the most critical part of the information. The gateway objects result
02:27format is set to E4X. The PHP Service page will return well formed XML and you
02:33will be able to look at that XML content and retrieve it when you integrate the
02:37PHP Service page into your own applications. There is a set of event listeners
02:41that are set up and then there is a call to a function called fill, which I
02:45will move to now. The fill function retrieves data from the database using the
02:50PHP page. It starts off by setting some properties including filtering and
02:54sorting and then set some parameters based on the filter that is been
02:58requested, and then finally calls a method called doRequest, where it passes in
03:04a string of FindAll. You will see when we look at the PHP service page that
03:08this is a fixed string that the PHP service page is expecting and it's a
03:13command that executes the server's select statement in SQL.
03:18From here we get into a more advanced architecture than we had seen before,
03:21when using RPC components. The name of the method that was passed in which was
03:25called FindAll in this example, is set to a property of a parameters object
03:29named method. That's then passed to the request property of the HTTPService
03:34Object known as gateway and then the request is sent. When the result event
03:39happens, that is, when the data is returned from the Server, its handled in
03:43something called a call back Object and the call back Object contains result
03:48and fault handlers to deal with those two particular events and save the data
03:52as needed to whichever predeclared variable such as the ArrayCollection is
03:56designed to hold it.
03:57Here is the more important code that I am interested in though. Go to the
04:02bin-debug folder and locate the service class, PersonService.php. Right click
04:08on the service class or Ctrl click on the Mac and select Open with text editor.
04:13Now if you simply double click on that file, within the Flex navigator view, it
04:17will result in opening whatever application on your system is associated with
04:21PHP files. On my system, Dreamweaver is associated with PHP, so double clicking
04:26would have resulted in opening Dream weaver.
04:30Here is the PHP file, it has a bunch of code at the top that I am not going to
04:34go through in a lot of detail. But I am going to point out that there is a call
04:37to a PHP class named XmlSerializer. This is a pre-built PHP class, that knows
04:43how to take any PHP object and serialize it into XML. The actual XML structure
04:49that's returned from this page, is documented in the comments at the top of the
04:53page. Whenever you get data back from the remote service, it will come back
04:57with the root element of response, a sub element named data and then repeating
05:03elements named Row. The child elements of the row element will be based on the
05:07names of the database columns of the table. Notice down here that when you
05:12retrieve data you also get a metadata section, which contains an element named
05:16totalRows which indicates the total number of items within the dataset that's
05:20being returned.
05:22There is some additional code that manages the filtering model. I am not going
05:26to go through that in detail. Although I do encourage you to review that code
05:29yourself. But I am more interested in what happens at the bottom of the page.
05:33Go down towards the bottom and locate a switch statement. Which on my screen is
05:37at line 384. The switch statement looks for a request parameter named method
05:43and then it goes through five possible values they can handle, FindAll, Insert,
05:48Update, Delete and Count. For each of those possible methods, it calls in an
05:53internal function and returns the appropriate data. You can make request to
05:57this PHP service page yourself by using an HTTPService component. Passing in a
06:02parameter named method, which has one of these values and that will result in
06:06calling that method on the Server and returning the appropriate data. So now in
06:11the next video, I am going to create a brand new application from scratch, that
06:15sends request to the PHP service, gets back the data and displays the data in
06:20the Flex application.
Collapse this transcript
Retrieving data with the generated code
00:00In this video I am going to describe how to make calls to the PHP Service page
00:04that's generated by the data wizard. In the previous videos I have generated
00:08the PHP code and now I am going to use an HTTPService component. I will be
00:13creating this application pretty much from scratch, so if you are following
00:16along with the exercises you can work in the same file I have open
00:19FlexAndPHP.mxml which was the default main application for this new project or
00:24you can create a brand new file.
00:26Start by creating an instance of the HTTPService component. Set its id to
00:32myService and the set its URL property to the name of the PHP file that you
00:37want to make the request to which I named PersonService.php.
00:44Next create a new script section above the PHP object and create a new private
00:49function named getData. In order to retrieve data from the PHPService page you
00:57pass in a property named method with a value of FindAll. The value of this
01:02parameter method is case sensitive and must match exactly the string that's
01:06expected in the PHP page.
01:08So here are the steps. First declare a new variable named params data typed as
01:13an object. And then fill in the value of this object using a pair of braces
01:20which in ActionScript creates a new object on the fly. Give the object a named
01:25property of method and set its value to FindAll. Next send the request to the
01:32HTTPService object using the syntax myService.send and pass in the parameters
01:38object, params.
01:40Now the next step is to create an array collection to hold the data when it's
01:43returned. Place the cursor above the function and declare a new Bindable
01:48variable named myData data typed as an ArrayCollection. Notice that the
01:55ArrayCollection class is automatically imported by Flex Builder as I select it
01:59from the list of available classes.
02:01Next create an invent handler function to deal with the data when it's returned
02:05from the PHPService page. Create a new function named resultHandler which
02:12receives an invent argument data typed as ResultEvent. Place a break point on
02:18the last line of the new function that is the line that has the closing brace.
02:23Now go down to the HTTPService component and add an attribute-based result
02:27event listener called resultHandler and pass the event object. Finally place
02:34the cursor after the existing label control and add a new button. Set its label
02:40to Get Data and its click event listener to called the method getData.
02:48So those where all the steps to retrieve the data so far. Before we actually
02:52display the data I am going to debug the application so we can see what's
02:56returned from the server. Save the changes and run the application in Debug mode.
03:11When the application appears in the browser click to Get Data button and when
03:16the data is returned from the server, you will hit the break point, come back
03:20to Flex Builder and switch to the Flex Debugging Perspective. Go to the
03:24Variables view and double click its tab to expand it to full screen.
03:28And then inspect the invent object which is data typed as ResultEvent. Open the
03:33event object and go down to its result property which you will see as data
03:37typed as the class ObjectProxy. Within the result object you will see that
03:41there is a sub-element named response. That represent the root element of the
03:46XML structure that returned from the server. Open the response property and you
03:51will see within the response property that there are two child objects named
03:54data and metadata and once again these represent XML elements that are returned
03:59by the PHPService page.
04:01Open the data element and you will see a row element which is data type as
04:05ArrayCollection. That's the actual data being returned from the server. And you
04:11open that and you will see that there are a 1000 rows of data being returned.
04:16Also take a look at the metadata element, this contains a value of pageNum and
04:21totalRows, where the totalRows represents the total number of data items
04:26returned in the ArrayCollection.
04:26So, now we know we are getting the data back correctly. Restore the size of the
04:32Variables view and then terminate the debugging session and go back to the
04:37code. I have already declared a bindable variable named myData as an
04:42ArrayCollection. So now to save the data persistently so that I can use it in
04:46my application, I will use this syntax, myData=event.result.response.data.row
04:56as ArrayCollection.
04:59Now again the reason I am using this particular data structure is because
05:03that's the structure of the XML that's returned from PHP and going back to the
05:08PHPService page that's been called, the documentation in the service page shows
05:12you a sample of that XML structure.
05:14I will go back to the application and now I am going to add a DataGrid
05:19component to display the returned data. I will place the cursor after the
05:23button and add a DataGrid and set its dataProvider property using a binding
05:28expression to myData. I will save the changes and run the application this time
05:35in Normal mode and when the application appears in the browser I will click the
05:41Get Data button and the data will be returned and displayed in the DataGrid.
05:46So, that's the first step in integrating your Flex application with the
05:49generated PHP code. Now in the next video I will show you a more complete
05:53example where we not only retrieve data but we also modify the data in the
05:57MySql database.
Collapse this transcript
Managing an asynchronous state with AsyncToken
00:00In this video I am going to describe the use of the AsyncToken class, a class
00:05from the Flex class library that allows you to track state between the time you
00:08send a request to a server function using the HTTPService or other RPC
00:13components and the time a resultEvent comes back.
00:16For the demonstrations in this and the next video I will be using an
00:19application from the exercises folder. If you have access to the exercises
00:23folder and you are following along, go there now. Go into the Chapter09 folder
00:28to Chapter09Begin, select all of the files and folders you will find there and
00:33copy them to the clip board. Then go back to Flex Builder, go to the source
00:39folder within Chapter09Begin and paste those files into place.
00:43Next open the application file, ModifyData.mxml and run the application. This
00:50application uses an HTTPService component instance and makes requests to the
00:56server side PHP code that I generated in a previous video. It presents the data
01:01in a Data Grid and when you double click on an item in the Data Grid you see
01:05the details of that data in the data entry form. You can cancel out of the form
01:09and click New and see the form with blank values. And you also have buttons for
01:15deleting and saving that right now aren't doing anything.
01:18Let's go back to the code. In the current version of the application as it
01:23starts up, it calls this function getData. As in the previous video, I am
01:28creating an object named params. Adding a method property which will be used as
01:32a parameter with the value of FindAll and then sending the request. And then
01:37with the resultHandler function I am receiving the data and saving it to a
01:40pre-declared ArrayCollection variable named acPerson.
01:44When this application is completed I will be making calls to many functions not
01:48just one, and I need a way to distinguish when a ResultEvent occurs, which
01:53operation was called and what data might have been associated with it. So I am
01:57going to use an AsyncToken class.
01:59In order to create an instance of an AsyncToken you get its reference when you
02:03call the request to the server. The send method of the HTTPService object
02:08always returns an instance of AsyncToken. The AsyncToken object then stays in
02:13application memory. It's a dynamic object which means that you can assign
02:17arbitrary named properties to it, and then when the ResultEvent occurs, the
02:22event object which is data typed as ResultEvent has a token property which will
02:27refer to the same instance of the AsyncToken class that you created when you
02:31made the call. You can then inspect the properties and you will know and their
02:35names and their values because you created them and determine when the
02:38ResultEvent happens, what operation you executed and what data might have been
02:42associated with it.
02:43So here's the first example, go to the getData method and place your cursor
02:48before the line that says myService.send. Within the same line of code declare
02:53a new variable named token data typed as AsyncToken and get its value from the
03:00call to the send method. Now in the next line add a new action property, this
03:05is not a property that's already known to the AsyncToken class, it's one we are
03:09creating arbitrarily. And then set the value of the action property to the same
03:14value as the method that you just created, FindAll.
03:19Now when the ResultEvent comes back from the server, the event object will have
03:23a token property and it will point to the same object. Go to the resultHandler
03:28function and add the following code, var token data typed once again as
03:35AsyncToken and then get its value from event.token.
03:40Now place a break point on the next line of code, this is the line of code that
03:44sets the value of the ArrayCollection, save and run the application in Debug
03:49mode. As the application starts up, it makes the request to the server and when
03:57the ResultEvent is dispatched we hit the eventHandler function with the break
04:01point. I will go to the debugging perspective and then to the variables view
04:06and you will see that the event object has this token property which you will
04:09find under the inherited section of the event object. And the token has the
04:14arbitrary named property action with the value of FindAll.
04:18So now we can look at that value and decide intelligently that in fact this
04:23resultEvent happened because we went and got all the data and now we can do a
04:27little bit of conditional processing. Terminate your Debugging session and then
04:33go back to the code. Place the cursor above the line of code that collects the
04:39data and saves it into the acPerson ArrayCollection and add a switch statement.
04:44Within the parenthesis following the switch key word inspect the value of
04:48token.action and then put in a pair of braces.
04:53Now add a case statement and look for the value FindAll, followed with a colon.
05:00Take the existing code that's saving the data and move it right after the case
05:04statement and then following that line of code, put it in a break command. This
05:09will ensure as we add additional cases to the switch statement that we don't
05:13continue executing all of them. Save your changes and run the application again
05:18this time in Normal mode. And this is now to test whether after making those
05:22changes, in fact the data still shows up in the application and it should.
05:26So now you have seen the basic structure of the AsyncToken object. You get a
05:31reference to an AsyncToken object upon making a call to a remote function. This
05:35architecture works whether you are using HTTPService, WebService or
05:40RemoteObject, any of the RPC components. You add whatever arbitrary named
05:45properties you want and then when the resultEvent is dispatched, you get the
05:49token back and you can expect its properties to find out what happened. In the
05:54next video I will extend this architecture and we will be able to edit, update
05:58and delete rows and react accordingly in the finished application.
Collapse this transcript
Modifying data with the generated code
00:00In this video, I am going to continue work on the application ModifyData.mxml.
00:05In this application I am using an HTTPService object to make a request to PHP
00:10and get data back and then using an AsyncToken object to track information
00:14between the time I sent a request to the server and the time the ResultEvent
00:18comes back.
00:19This architecture using the AsyncToken object will allow me to make multiple
00:23calls to the same service page on the server and handle the results in a single
00:27eventHandler. I am going to run the application again and show that when the
00:32user double clicks on a row, we see the details for that row in a data entry
00:36form or when the user clicks the new button we see the same data entry form,
00:41but this time with blank values.
00:44In the first part of the video, I am going to describe how to have set up all
00:48of the functionality you need to both create and update existing data. First
00:52take a look at the newRecord function, notice that it starts off by setting a
00:56property of the form component named currentPerson to an object with the
01:00property named personid with the value of zero. This is essentially saying,
01:04Create a new data object, but without using a strongly typed value object.
01:08Now when the user types values into the form and then sends the data back by
01:12clicking the Save button, we will receive that data and this method saveRecord,
01:16will be called. The event object which is data typed as this class PersonEvent
01:22has a property named person data typed as an object. The data entry form fills
01:26in this object with all of the properties from the form controls and we can now
01:30receive it and handle it within the function.
01:33Add this code to the saveRecord function, first of all, declare a variable
01:37named personObj typed as Object and get its value from the event object's
01:43person property. Now inspect the primary key property personid, if the value is
01:49zero that means the data came from this newRecord function and it's a new
01:53object, it should be added to the database. Otherwise it's an existing record
01:58that came from the actual database and it should be updated.
02:01So here's the conditional code. If personObj.personid, has a value of zero, add
02:09a method property to the object with the value of Insert. And this is the
02:14string that the PHP service page will be looking for, to determine what action
02:18it's supposed to take. Next add an else clause and within the else clause, set
02:24that same method property to a value of Update. Make sure you spell the words
02:30Insert and Update exactly as I have them here, with upper case initial
02:34characters because that's what the PHP service page is expecting.
02:38Now I am going to make the request to the server by calling the send method and
02:41passing in the object and I will get back a reference to the AsyncToken, just
02:45like I did with the FindAll method. I will declare token object typed as
02:50AsyncToken, I will get a reference for the token, by calling the send method of
02:56HTTPService component and I will pass in personObj, which now contains the
03:01actual data I am sending to the database plus the method property indicating
03:05what supposed to be done with it.
03:07Now I will add the action property as follows token.action = personObj.method.
03:14And now the action property is a part of the token and I will be able to
03:17determine what happened, when the data comes back from the server. Now let's go
03:22to the resultHandler. Within the resultHandler, we already have a switch
03:26statement that's examining the action property of the AsyncToken. Add two more
03:31case statements, the first for the Update action, and always add the break
03:35statement whenever you add a case statement, and the second will be for the
03:39Insert action. Then place the cursor after the case statement for the Update
03:45action but before the break. Whenever you call the Insert or the Update actions
03:50from the PHPservice page, you get back a response which is the actual data object.
03:56In the case of the Update statement, it's typically the same object that you
03:59passed into the action, but just in case anything happened on the server that
04:03modified the data, you always want to take that data and put it back into your
04:07local data set. So place the cursor above the switch statement and declare
04:12another variable named personObj data typed as an Object.
04:17Now move back down into the case statement, after case Update and fill in the
04:22value of that object as follows personObj = event.result.response.data.row, for
04:33as with the FindAll action we got back all of the data, this time we'll only
04:37get back one. Then replace the object within the local data set as follows
04:43acPerson.setItemAt and pass in two values, the first is the person object,
04:49personObj and the second is the index position where you want to put the item
04:54in. And we can get that value from the current position in theData Grid using
04:58the expression persongrid.selectedIndex.
05:04Finally set the currentstate property to a blank string and that results in
05:09removing the data entry form from the interface and re-enabling the Data Grid.
05:14The Insert statement code is very similar, place the cursor after case Insert
05:19and before the break and add the following code. Once again get the value of
05:25personObj using the same expression as before, event.result.response.data.row.
05:34Now because we added the item in the database on the server, we also want to
05:38add the item in the local ArrayCollection using this syntax, acPerson.addItem
05:45and add personObj. Now the next couple of lines are going to manipulate the
05:51interface and cause theData Grid to scroll to and select the newly added item
05:57as follows. personGrid.selectedItem = personObj, by getting a reference to the
06:05object and then passing it to the selected item of the Data Grid will now
06:09select the row of the newly added item. But because that item may not be
06:13visible on the screen currently, we also have to tell the Data Grid to scroll
06:17to that position, using this code, personGrid.scrollToIndex and pass in the
06:24value of personGrid.selectedIndex.
06:30Finally as before, set the currentstate property to a blank string and that
06:36will remove the data entry form and re-enable the Data Grid, save your changes
06:41and run the application and let's test the results. First we'll update an
06:47existing row, when the data appears double click on the first row which
06:51currently has the value of Brad Lang change Brad's last name to some other
06:56values such as Brad Smith, click save and after a moment, after the message
07:03goes back to the server and comes back to the application you will see that the
07:07data is updated in the application.
07:09Next create a new record, click the button labeled New, type in values in all
07:15of the columns on the PHPserver each of these columns are required. So I am
07:19going to type in a value of Adam Aardvark and put in just any kind of values in
07:26the rest of the fields. I will click the save button and after the request goes
07:42off to the server and comes back to the client application, the data is
07:45selected in the Data Grid as result of that scrolling code that I had put in.
07:50Finally let's add code for deleting data. Go back to Flex Builder and locate
07:54the deleteRecord function. Within the deleteRecord function use the following
07:59code, declare a variable named personObj data typed as an object and get its
08:04value from personGrid.selectedItem, so we are getting a reference to the
08:09currently selected object within the Data Grid. Then add the method property as
08:15we have before, this time the syntax will be, personObj.method = Delete, and be
08:22sure to use an upper case D because that's what the PHPservice page is expecting.
08:27Next make the call to the server and get an AsyncToken object and get the value
08:35of the token object by calling the service components send method passing in
08:40personObj and finally set the action property of the token to Delete. Now go
08:48back to the resultEventHandler, within the resultEventHandler, locate the
08:52switch and case statements and add a new case for the Delete action. And after
08:58the case statement for the Delete action, add this code acPerson.removeItemAt
09:05and then once again use the Data Grid's selectedIndex property to indicate
09:09which item you want to remove from the local collection
09:12personGrid.selectedIndex and even though it's not literally necessary here I
09:24always had a break statement at the end of every case clause.
09:27Save the changes and run the application one more time and as the application
09:32opens, it will once again show all of the data. Click the last name column to
09:36sort and you should see that new row Adam Aardvark appear at the top, select it
09:42and click Delete and after a moment you should see the data has been removed.
09:47And if you refresh the application, so that you are pulling all of the data
09:50from the server again and then once again sort it, you will see that in fact
09:54the data has also been deleted from the server side database. So that's a look
09:58at how to build your custom application code on the Flex client and to
10:02integrate it with the generated PHP code that's created by Flex Builder's PHP
10:07Data Wizard.
10:09As I mentioned at the beginning of this Chapter there are many other possible
10:12approaches to integrating Flex applications with PHP, for example, if you
10:16prefer the better performance of AMF and the Flash Remoting architecture, you
10:20might want to look at the component library named AMFPHP or another one called
10:25SabreAMF, both of these are completely free libraries that you can download and
10:30install into your PHP server installation and then you can use the RemoteObject
10:34component in the Flex framework to make calls that are similar to these, but
10:38get the benefits of the smaller size and faster communication of AMF or Action
10:43Message Format.
Collapse this transcript
10. Integrating with ASP.NET
Installing ASP.NET and SQL Server 2005 Express
00:00In this chapter of the video series, I am going to describe how to integrate
00:04Flex applications with ASP.NET. This chapter will be only useful on Windows,
00:09because the ASP.NET software only works on that operating system and is not
00:14available for Mac. Flex Builder 3 includes a new feature called the Data
00:17Wizard, which I have already demonstrated in a previous chapter in the context
00:21of PHP, but which also can be used to generate server side code in ASP.NET,
00:27that allows you then to link your Flex applications to SQL Server databases.
00:31Before you can use this Flex Builder feature, you must have the ASP.NET
00:35Framework installed and also the Data Wizard for ASP.NET only works with SQL
00:39Server databases. So if you don't already have the SQL Server, you'll need to
00:43download it and install some version of that. Finally, when you create a Flex
00:47Builder project for use with ASP.NET, you have the option of using something
00:51called the Development Web Server. This is a product that's included with
00:55another product called Visual Web Developer 2008 Express Edition and also with
00:59the full product Visual Studio.
01:01You can download Visual Web Developer 2008 and an incorporated installer for
01:06SQL Server from the web page that I am displaying now at
01:10www.microsoft.com/express/download/#webinstall. Go to the Visual Web Developer
01:192008 Express Edition section and click the Download link. Download the file
01:24which is relatively small only 2.6 megabytes. Then once you have downloaded it,
01:29it's started up. Here is what the installer looks like, it walks you through
01:32some informational steps including information about the license agreement.
01:36Visual Web Developer 2008 Express Edition is free for download and use. You
01:41will have to register to use it beyond 30 days, but it doesn't require any
01:45license fees.
01:46After you've read through the license agreement, if you accept it, click the
01:49appropriate radio button and then click Next. On this screen, you indicate what
01:54options you want to include in your Visual Web Developer 2008 installation. You
01:58will always be including the .Net Framework and Visual Web Developer and
02:04optionally you can also install SQL Server 2005 Express Edition, which is a
02:09free version of SQL Server and the Microsoft Server like Runtime. I don't need
02:14the server like Runtime, so I am going to deselect that option but I will
02:18select SQL Server 2005 Express. Then I'll click Next again, I'll review all of
02:24my options and then click the Install button.
02:26The downloaded installation of these products takes a little bit of time. After
02:30you are done, you'll probably need to reboot your system. But then once that's
02:33finished, you'll be ready to start using SQL Server ASP.NET and Flex Builder
02:38all together to go to Flex applications that integrate these products together.
Collapse this transcript
Installing SQL Server Management Studio Express
00:00After you have installed SQL Server 2005 Express, you might also want to
00:05install the Management User Interface, that's available from Microsoft for
00:09free. You can download this software from this web address,
00:12www.microsoft.com/express/sql/download/default.aspx. Notice the http prefix
00:22before this URL. If you have already installed SQL Server itself, then the only
00:27thing you need from this screen is the SQL Server Management Studio Express
00:31product. This is an application that will allow you to manage and create
00:34databases and import and query the data. Click the Download link to download
00:39the software and then save it to your local disc.
00:42Once the installer has been downloaded, you can launch it and walk through the
00:46prompts. The installation is fairly straightforward. Once the file has been
00:51downloaded, click Run and then continue through the security warning. Now
00:56follow the prompts to complete the installation, review the license agreement.
01:00As with SQL Server Express itself, the Management Studio Software is free to
01:05use without any license fees. Provide any other required information and then
01:10complete the installation.
01:12In the next video, I'll show you how to import a database using the SQL Server Management Studio Express.
Collapse this transcript
Importing a database into SQL Server
00:01In this video I am going to describe how to import a database into SQL Server
00:05that you can then use to experiment with the Flex Builder 3 Data Wizard for
00:09ASP.NET. Before you can do this exercise, you must have first installed ASP.NET
00:15and SQL Server 2005 Express and SQL Server Management Studio Express, which I
00:20am showing on the screen now. The first step is to create a database.
00:24Go to the Object Explorer panel on the left and locate the tree item labeled
00:29Databases. Right-click on it and select New Database. Name your new database
00:34contacts and click OK. The next step is to run an SQL Script, that's a part of
00:41the exercise files that come with this video series. If you are following along
00:45with the exercises that you have accessed to these files. Go to the Menu and
00:49select File, Open, File, navigate to the Exercises folder, which I have
00:54installed on my Desktop and from there go down to Assets, ASP.NET and you'll
01:00find the file there named, contacts.sql.
01:04Open the file, this file creates a table named person with the particular data
01:09structure, that's listed right here. Notice that there is a primary key named
01:13personid which is an IDENTITY field, which means that the value for this column
01:17will be assigned automatically for each new row. The rest of the columns are
01:21string or variable character values of different lengths. At the bottom, there
01:26is a set of INSERT statements, then inserted a total of 100 records into the
01:30database table. Once the file has been opened, you can check its syntax by
01:34clicking the checkmark icon on the toolbar and you should get this message,
01:37Command (s) completed successfully.
01:40Then to execute the file, click the Execute button on the toolbar. You'll see a
01:45series of messages indicating, how many rows were effected on each INSERT
01:49statement. Now to view the data, go back to the Object Explorer and open the
01:53contacts database and from there, open the Tables list. You should find the new
01:59table dbo.Person is listed there. Right-click on the table name and select Open
02:05Table. After just a few seconds, you should see that there are 100 rows of data
02:10to work with in this database table.
02:13Now if you don't have access to the exercise files, you can instead create the
02:17database table structure based on the script that I showed and then add your
02:21own data manually. Then you should once again have that data available to work
02:26with, in Flex Builder 3, using the ASP.NET Data Wizard.
Collapse this transcript
Creating a Flex/ASP.NET project in Flex Builder
00:00In this video, I am going to describe how to create a Flex Project in Flex
00:04Builder 3 that integrates with ASP.NET. You have a couple of choices for how
00:09you build this project. The most important is which WebServ you are going to
00:13use. If you use Internet Information Services that's the industrial strength
00:17web server that comes with Windows XP Professional and up and also with Windows
00:22Vista Business and up, then you can integrate your Flex Project with that web
00:26server. If you don't have Internet Information Services but you have installed
00:30either Visual Web Developer Express or Visual Studio then you will have access
00:35to a Development or a stand-alone web server, that's included with those
00:39products and Flex Builder will know how to use and launch that web server when
00:43you want to test your application.
00:45For this demonstration, I will be using that Development
00:48web server that's a part of Visual Web Developer Express
00:51because I have already installed that product on my system. Within Flex Builder
00:55to create the project, select File, New, Flex Project. As with all Flex Project
01:02you can name it anything you want as long as you don't include spaces or
01:06special characters. I am going to name my project Chapter10Begin.
01:11You can place the project anywhere you like and I will set the application type
01:14as Web Application. Now, I will select ASP.NET from the list of available
01:20application servers and click Next. On this screen, you indicate whether you
01:25are going to use the Development Server or Internet Information Services (IIS)
01:30as I indicated before. I installed Visual Web Developer, so I have the
01:34Development Server installed and I am going to use it in this demonstration.
01:39Next, you indicate the Output folder, if you use Internet Information Services,
01:44you will need to output your files to a folder that's available within the IIS
01:47document route. But if you are using the Development Server then the flex_bin
01:52folder which is the default Output folder is set up automatically as the
01:56document route for that special web server and that web server will start up
02:00automatically and will listen at Port 3000. Then when you test your application
02:05from within Flex Builder, Flex Builder will automatically know to pull the file
02:10from that web server using the same port.
02:12So I will leave the Output folder named at the default setting of flex_bin and
02:17click Next. Now, I will indicate the name of my main application file which I
02:22will call FlexAndDotNet.mxml. Again notice that the Output folder URL is set
02:30automatically to include Port 3000. Now I will click Finish and that creates
02:38the Application in the project. I will create a Label control within the
02:42Application text and I will say it's text property to Hello from ASP.NET! and
02:50then so we can see it clearly, I will set the fontSize="18 "and the
02:54fontWeight="bold"
02:56I will also set the layout property to vertical and then I will try running the
03:05application from within Flex Builder. When you run the application, it should
03:10be downloaded from the Development web server, notice the URL starting with
03:15localhost3000. And now you can see that the application is loading and running correctly.
03:21In the Windows System Tray in the lower right-hand corner you should now see an
03:25icon that represents the ASP.NET Development Server running on Port 3000. When
03:31you close down Flex Builder, the web server will shut down automatically but if
03:35you need to stop it for any reason just go to the System Tray icon, right-click
03:40and select to Stop. You can also select item such as Open In Web Browser and
03:44Show Details.
03:46The Open In Web Browser takes you to a directory listing which is your project
03:50route folder which is now also treated as the web servers document route. And
03:55you can also select the item Show Details and that brings up a dialog box
04:00indicating which port and which is the virtual and physical path for this web server.
04:06So now I will close the web browser and return back to Flex Builder and let's
04:10take a look at the couple of Project properties that have been set up
04:13automatically. In the Properties dialogue you will notice that there aren't any
04:18special settings in the Compiler arguments whereas when you are using the
04:22RemoteObject architecture with ColdFusion, when you work with ASP.NET in Flex
04:27by default Flex Builder expects you to work with that system using web services
04:32and so you don't need a services configuration file or any other special
04:36configurations. Essentially to this is just like any other client site
04:41application that's going to get and send data using standard web services and
04:46since this is ASP.NET we will be using SOAP-based web services which is
04:51something .NET does particularly well.
04:54So now that you have a project set up that integrates with .NET, the next step
04:58is to generate some code based on the SQL Server Database table that was
05:02previously imported.
Collapse this transcript
Configuring SQL Server for use with Flex Builder
00:01In this video, I am going to describe the steps to configure SQL Server that
00:05will allow you to connect to SQL Server from Flex Builder 3 and use the Data
00:09Wizard to generate client and server-side code. Starting off in SQL Server
00:14Management Studio Express, the first step is to create a special login. It is
00:19possible to use the built-in or default logins that SQL Server comes with, but
00:24good security practices dictate that you should create a special login whenever
00:27you are doing something special such as generating code.
00:31So the first step is to create a login. Go to the Object Explorer panel and
00:36open the Security section. From there double-click on Logins and you will see
00:41the list of built-in or default logins, right-click anywhere in that area and
00:46select New Login. Assign the login name flexUser. Set the authentication to use
00:54a password, enter a password of any type and enter it twice. Make sure you
00:59spell it the same both times. Next turn off password expiration and that will
01:06disable the other option, user must change password at next login. The next
01:10step in SQL Server is to map this login as a database user.
01:15Go to the list of pages and choose User Mapping and then check the checkbox
01:20next to contacts, the database you want this user to be able to use. Finally
01:26come down here and click OK and that will create the user and map the user to
01:30that database. There is one last step in mapping the user to the database and
01:36that's to provide them with the user role. Go to the Object Explorer to the
01:41Databases section and locate and open the Contacts database. Go to the Security
01:46section to Users and you should find your new login, flexUser listed as a
01:51database user for this database. Double-click on the User and then in the
01:56Database User property screen, go down to the Database role membership section.
02:01Scroll down to the bottom and select db_owner. This will allow you to
02:06interrogate the database and get for instance a list of database tables and all
02:10of the data structure that Flex Builder will need in order to generate both
02:14client and server-side code. Click OK to save your changes. The next step is to
02:19enable TCP/IP Connections from Flex Builder to SQL Server. SQL Server is
02:26initially installed without any TCP/IP connectivity. This is a security
02:30measure, but when you are doing development work and you are working with Flex
02:34Builder, you need to be able to connect over TCPIP, here is how you set it up.
02:40Go to the Windows menu and start up the application SQL Server Configuration
02:44Manager. This is an application that's installed at the same time as SQL
02:48Server. Go to SQL Server 2005 Network Configuration and from there to Protocols
02:55for SQLEXPRESS. Notice that the TCP/IP protocol is currently Disabled,
03:01double-click on it and on the Protocol tab, set the Enabled property to Yes.
03:07Then click the IP addresses tab and scroll all the way down to the bottom and
03:12locate the section labeled IPALL. Set the TCP Port to 1433 which is the
03:18standard default port on which SQL Server is typically configured and the one
03:23that Flex Builder will expect to use to connect.
03:26Click OK and you will see a warning that you must stop and restart SQL Server
03:31before you will be able to connect. Click OK, then come back up to the SQL
03:35Server 2005 Services label, select SQL Server, SQL Express. Then go up to the
03:43toolbar and click the Stop Service button. It takes a few seconds to stop the
03:48service, and then once that operation is complete, you should then be able to
03:52select the service again and click the Start Service button.
03:56Now SQL server will be able to listen for and respond to TCP/IP messages and
04:01you will be able to login to the SQL Server from within Flex Builder.
Collapse this transcript
Using Flex Builder 3's ASP.NET Data Wizard
00:01In this video, I am going to describe how to use the ASP.NET Data Wizard within
00:05Flex Builder 3 to generate client and server-side code based on the structure
00:10of the database table hosted by SQL Server. In previous videos, I installed SQL
00:14Server and configured it so it could be connected to from within Flex Builder.
00:19I set up ASP.NET along with the development server. I am now ready to start
00:23putting all of the tools together. Within Flex Builder I already created a
00:27project that's associated with ASP.NET, now I'll go to the Menu and select
00:32Data, Create Application from Database.
00:35The first step within this screen is to create a connection. This is very
00:39similar to the steps I followed in the previous chapter, when working with PHP
00:42and MySQL. I'll click the New button and give the Connection profile a name. I
00:47call the version in MySQL in a previous chapter contacts, so I am going to call
00:51this one contactsSQL. I'll click Next and then provide the connectivity
00:56information that Flex Builder needs. The Server Name should be set to
01:00localhost, assuming your SQL Server installation is on your own local machine.
01:05The Database Name matches the database name that you've assigned in the
01:08management console. The User Name and Password are the values that you add it
01:13when you created a login in SQL Server. I created a user name called flexUser
01:18and I assigned a password of simply password. So you enter those four values
01:23and then click Test Connection and you should see this message, The connection
01:26was successful.
01:27Now if you see a message indicating that there was a problem with connecting or
01:31there was a problem with security. You will need to go back to the SQL
01:34administrator and configuration applications and make sure that you follow the
01:38steps both for creating the user, giving them the access to the database and
01:42also make sure that SQL Server is listening and is ready to respond on the TCP
01:48iport number 1433.
01:50If you do see this message, The connection was successful, you can click OK and
01:53go on to the next step. Click Next and click Finish to save your connection
01:58information. If everything is healthy, you should immediately see a list of
02:02available tables in the database. We only have one table named person and it's
02:07indicated here. Also the Data Wizard automatically detects the primary key of
02:12the Table, which we created as personid, but it does allow you to select any
02:17other Primary Key if you will so desire. I'll leave it to the real Primary Key
02:21column, personid and click Next.
02:24Now the next step is to configure the server-side code that will be generated.
02:28On the server, we're going to be creating a class that's written in one of two
02:32languages. Either C-sharp or Visual Basic and either way this class will
02:36provide a service that you can call to exchange data between the server and the
02:41Flex client. I am going to name the Class, PersonService following a pattern
02:46that's very similar to what I used with PHP and MySQL, in a previous chapter.
02:51For the Server language, I'll use the default setting of C# with web services.
02:55But if you prefer Visual Basic, you can select that option. The resulting
02:59application will behave exactly the same, the only difference will be the
03:03actual language in which the server-side code written. Click Next after making
03:07those selections and in this screen you select which columns of the database
03:11table will be displayed on the applications primary screen.
03:15By default, all columns except for the primary key will be displayed. You also
03:20have the ability to filter the data on one column only. I am going to select a
03:24filter on the city column, then I'll click Finish and all of the code on both
03:29the client and the server will be created. It takes just a few moments for the
03:33code generation to be completed.
03:35In your project Source route, you will now have a file where the name of the
03:39application matches the name of the database table. This application is named
03:43person.mxml. If you then go to the New Folder that's created within the project
03:48named App_Code, you'll find the class that you configured which I called
03:52PersonService and it will have a file extension of either .cs for C-sharp or
03:58.vb for Visual Basic.
03:59I am going to open the CS file briefly by right-clicking on it and selecting
04:04Open With Text Editor. Don't double-click on it because if you have any other
04:09application on your system that's configured to work with CS files. The file
04:13will open in that application, instead of in Flex Builder. Here is the C-sharp
04:19class that's going to be doing all the server-side work, connecting to the
04:22database and getting information to the Flex client.
04:26The last step in this video is to test the application. Go back to person.mxml
04:31and run the application. As previously, the application is downloaded from
04:36ASP.NET at Runtime. As it starts up, it makes a request back to the server for
04:41data and when the data is returned over a SOAP-based Web Service, it's
04:46displayed in the data grid as shown here. You can apply a filter by clicking
04:51into the text field at the bottom right of the screen. I'll type a value of
04:55Houston and click the magnifying glass to perform the filter and I'll see only
05:00the data for people who live in Houston.
05:04I'll remove the filter and once again click the Filter button and that restores
05:08the view of all of the data coming from the server. There is also a data entry
05:12form that you can use to add rows, I'll Cancel out of that and there is also a
05:17trashcan icon, that you can use to delete rows from the database table.
05:21Now in the next video, I'll do a more thorough code review of all this
05:24generated code, so we can understand the nature of the web services that have
05:27been created in the ASP.NET environment.
Collapse this transcript
Reviewing the generated code
00:01In this video, I am going to review the generated code that was created by the
00:04Data Wizard, using ASP.NET and SQL Server. I'll start with the Flex
00:09application. The application name is the same as the table name, in this case,
00:13person.mxml. The application presents a DataGrid when it first appears. There
00:18is an included file called personScript.as, which contains all of the logic for
00:24the application and one of the first commands in that file is an include
00:28statement, that includes a configuration file, which in turn contains the
00:33location of the web service endpoint. The content that you download from that
00:38web service endpoint, is in a format known as WSDL or a Web Service Description Language.
00:44ASP.NET is capable of generating WSDL content based on requests, that end with
00:50a question mark, WSDL query string. The file that you make the request to, both
00:54for the WSDL and to make calls to the web service operations ends with a file
00:59extension of .ASMX. This file, PersonService.asmx is generated in the root
01:07folder of the project. Notice, it's not in the source code root, it's in the
01:11actual root. I'll open that file and you will see that this file contains a
01:16single statement, indicating that this a web service file written in C Sharp,
01:21where all of the logic in a form known as Code Behind, is in a file name
01:26PersonService.cs in the App_Code folder. Also note that there is a class
01:31declaration of PersonService indicating that, that's the class name as it's
01:35known to the .NET environment.
01:37Next, I'll take a look at the .CS file. This is the file where the actual
01:42activity of the web service happens, there are a number of operations that are
01:47defined. The FindAll operation receives three required arguments, the first
01:52argument is a filter string that allows you to filter the data, the second is
01:57also a string and indicates which field you want to sort on if any and finally,
02:02there is a boolean value, which indicates when returning data in a sorted
02:06order, which order you want to sort in, ascending or descending. The code
02:10within the FindAll operation, puts together a dynamic SQL Statement and then it
02:14creates an object known in ASP.NET as a DataTable. The remainder of the code
02:19fills the DataTable from the SQL Statement and returns the result directly to
02:23the caller, in this case, a Flex application.
02:26There are also functions for updating, inserting and deleting data. Notice that
02:31the name of the function for deleting is Remove and it receives only the id of
02:36the record that you want to remove from the database table. ASP.NET Web
02:40Services have a unique capability. In that, they can generate their own testing
02:44pages. Here is how you can try this out. First of all, go to the Flex
02:49application and start it up. This will make sure that you have your development
02:53web server running, take a look down at the system tray, in Windows it's in the
02:57lower right hand corner and you should see the web server icon up here.
03:01Now, go back up to the web address and trim the URL to end with Chapter10Begin.
03:08this should take you to Directory Listing of all the files in the project. Now,
03:13click on to PersonService.asmx. When you browse to the ASMX file directly from
03:18a web browser, a page is generated that lists all of the operations or
03:23functions of the service.
03:25Again, notice that the function names are FindAll, Insert, Remove and Update.
03:31Also, notice that there is a link for the Service Description and if you click
03:34on that link, that will take you to the WSDL address for this service, you will
03:39need this information, if you're going to call this web service directly later
03:43on. Taking a step back, from this screen you can click into any of the links
03:48and you can try out each of the operations. For example, I'll click into
03:52FindAll and I am asked for three values, the city that I want to filter on,
03:57which I'll put in as Houston, the orderField which I'll leave blank and the
04:02orderDescription, which I'll set to a value of true, I'll click Invoke and the
04:07result is that the data is returned in XML format.
04:10So, this is an easy way to test out and try the ASP.NET Web Service operations
04:15without having to write any Flex code yet. I'll go back to the list of
04:19operations and I'll click into the Insert operation. Both the Insert and the
04:24Update operations require individual values for each property that you need to
04:29set. With web services, all arguments or parameters are required and so if I
04:34wanted to execute this Insert operation from within a Flex application, I would
04:39have to send all of these properties to the web service. Unlike the
04:43RemoteObject environment, where you can use optional arguments, in the web
04:47service architecture, all arguments or parameters are required.
04:51Let's go back one more time to the Flex code and run the application again. As
04:57I mentioned previously, the Flex Client Application, that's generated is fairly
05:00simple, even trivial. What's truly valuable about this generated code is the
05:05server-side functionality.
05:07So, in the remaining videos in this chapter, I am going to describe ways to use
05:11those generated web services in your own Flex applications.
Collapse this transcript
Using the WebService component
00:00In this video I am going to describe how to use the generated WebService code
00:05and call it from a Flex application using the Flex class library's WebService component.
00:11Before you can use the WebService component you must know the WSDL address of
00:15the web service you want to call, which I am displaying on the screen now.
00:19Typically I will navigate to the WSDL address from the Browser to verify that I
00:24have the right address and that I am able to reach the WSDL address from the
00:27local machine.
00:29The Flex application requires this WSDL address and uses it to determine the
00:34names of the operations, what sort of data needs to be passed in, and what sort
00:38of data will be returned.
00:40After you navigate to the WSDL address just copy it to the Clipboard and then
00:44you will be able to paste it into your Flex code when the time comes.
00:48Now I will close the Browser and go back to Flex Builder. For this
00:51demonstration I am going to use the application file FlexAndDotNet.mxml. This
00:56was the beginning application that I created when I first created this project.
01:01Place the cursor after the application start tag and above the label in the
01:05application, and then declare an instance of the WebService component using MXML.
01:11As with all RPC components you always assign an ID so that you can refer to the
01:16object in your ActionScript code and binding expressions.
01:19I am going to assign an ID of myService. Now at a WSDL property. The WSDL
01:27property is the location of the WSDL address for this service, and then if you
01:33copy the WSDL address from the Browser you can paste it in here.
01:39As the application starts up the WebService component makes an initial request
01:43to this WSDL address, it downloads the WSDL content, parses it and then once
01:49it's understood the names of the operations and all of the other information in
01:53the WSDL, it dispatches an event named Load.
01:57The Load event tells you that the WebService component is ready for use and you
02:00can start making operation calls.
02:03You can also make start-up calls from the application complete or creation
02:07complete events of the application. Sometimes those events will be dispatched
02:11before the load event of the web service, but if that happens your calls will
02:16be queued, and the call to the remote operation will only happen once the load
02:20event has been dispatched.
02:21I am going to listen for the load event, and when it happens I will make an
02:26initial call to retrieve data from the web service. So put in a load event
02:31handler and within the load event handler call a custom function that will need
02:36to create named getData.
02:39Now place the cursor above the WebService component declaration, create a
02:43script section and create the new getData function. This function will return
02:49void and it will contain a single call to one of the remote operations of the
02:55web service. I am going to call remote operation name FindAll like this,
03:00myService.FindAll. And then I am going to pass in the operation's three
03:05required arguments.
03:07The first argument is the name of a city on which you want to filter. I will
03:11pass in a blank string meaning, I don't want to filter at all. The second is
03:15the name of a column on which you want to sort and I will pass in the last name
03:19column, and the third, is a boolean value indicating whether you want to sort
03:24in descending order. By passing in a value of False I am indicating that I want
03:29to use the default ascending order.
03:31The next step is to handle the result, just as with other RPC components you
03:37can handle the results of calls to remote functions using either binding
03:41expressions or the result event handler.
03:44In the case of an ASP.NET Web Service operation that returns an ASP.NET data
03:50table, the content that comes back is not a simple array or an array
03:54collection. So it's almost always better to use result event handler to handle
03:59the return data.
04:01Go to the Web Service tag and add an attribute paste result event listener and
04:07call function named resultHandler which we will need to create and pass the
04:11event object.
04:13Now create that function, place the cursor in the Script section and declare a
04:17new private function named resultHandler. It will receive an event argument
04:23data typed as ResultEvent and return void.
04:28Now, place a break point on the last line of the function that is the line with
04:32the closing brace. Save your changes and run the application in Debug mode. As
04:39the application starts up it makes the call to the remote operation and then
04:42Flex Builder should prompt you to open the FlexDebugging perspective.
04:47Open the debugging perspective, expand the Variables view and inspect the event
04:51object result property. The result property comes back as an ObjectProxy, it
04:57contains a property named Tables with an uppercase T which in turn contains an
05:02item named Table0 and within that object there is a property named Columns and
05:07another one named Rows.
05:09The full expression for the data that you want to retrieve is
05:13event.result.Tables.Table0.Rows and notice that each property has an initial
05:20uppercase character. Within the Rows ArrayCollection you'll find the actual data.
05:26So here's how we will now capture the data and save it persistently. Restore
05:30the size of the Variables view and terminate your Debugging session. Declare a
05:35new bindable ArrayCollection variable as follows. Place the cursor above the
05:39getData function. Put in the bindable metadata tag and declare a new private
05:44variable named myData data typed as an ArrayCollection.
05:48Now place the cursor inside the resultHandler function and save the data using
05:53the following code.
05:54myData = event.result.Tables.Table0.Rows.
06:03If you want you can add an explicit typecasting of as ArrayCollection. This
06:09isn't really necessary in this particular syntax, but it will make it clear
06:13later on exactly how you are saving the data.
06:16Now, place the cursor towards the bottom of the application after the existing
06:20label. Create a data grid and set its data provider using a binding expression
06:25to myData.
06:28So those are all the steps. As the application starts up we will make the call
06:32to the remote method. The result event listener calls the resultHandler
06:36function which saves the resulting data to the myData object which has already
06:41been declared as a Bindable ArrayCollection.
06:44Run the application in Normal mode this time, and you'll find that if the
06:48application starts up it loads and displays the data.
06:51So that's to look how you can work with the ASP.NET code that's generated by
06:56the Data Wizard. It's a standard SOAP-based Web Service. After you generate the
07:01code it's typically a good idea to inspect the results and then you can write
07:05your own custom web service code to integrate the web services into your own
07:10Flex application.
Collapse this transcript
11. Managing Data on the Client
Filtering data with the ArrayCollection class
00:00In this chapter of the video series I am going to demonstrate some advanced
00:04capabilities of the ArrayCollection class. We use the ArrayCollection class to
00:08manage data in Flex Client applications at runtime. The ArrayCollection is a
00:13wrapper class that contains an array and provides consistent dynamic binding
00:18capabilities so that any changes to the data it contains are broadcast to any
00:22part of the application. But the ArrayCollection class also implements a set of
00:26interfaces that allow you to filter, sort, search and bookmark data completely
00:32within the client application.
00:34These are features of your own applications that in a classic web application
00:38build purely say in ColdFusion or PHP or ASP.NET would require multiple round
00:44trips to the server and multiple requests to the database. In a Flex
00:49application you can handle a lot of these tasks completely within the client,
00:53eliminating a lot of round trips to the server, eliminating a lot of database
00:57usage and increasing the scalability in terms of numbers of concurrent users of
01:02your applications. For the exercises in this chapter I will use a Flex Project
01:07Archive that's available in the Exercise Files. If you are following along with
01:11the exercises, you can import this Project now.
01:14Navigate to the Exercises folder which on my system is on my Desktop. From
01:19there go to the Chapter11 folder and select the file Chapter11BeginProject.zip.
01:26Complete the import process, go to the Flex Navigator view and open the
01:30project. Open the Source folder and then open the application file
01:35FilteringData.mxml. This application retrieves and displays an XML dataset. The
01:43same dataset I have been using in many other parts of this video series, but
01:47this time rendered as a pure XML file.
01:49As the XML file was retrieved using the HTTPService component, it's data is
01:54then saved to persistent ArrayCollection object and displayed in this DataGrid
01:58control. In this application, there is a user interface that's going to allow
02:03us to apply a filter. As the user types in the name of a city, we will be able
02:08to filter the data completely within the Flex client application and we won't
02:12have to use a database on the server or any other server-side functionality to
02:16execute this filter.
02:19Let's go back to the application. In order to filter data on the client using
02:23the ArrayCollection class, you use a property of the class named the filter
02:27function. The filterFunction property points to a call back method that you
02:30create. Whenever you set the filter function and then call the
02:34ArrayCollection's refresh method, that causes the ArrayCollection to loop
02:38through it's data and call the callback function once for each of it's data
02:42items. It passes the data item into the function and receives back a Boolean
02:47true or false value. If the filter function returns a value of true that means
02:52that that particular data item should be exposed in a filtered view and if the
02:56filter function returns false that means that that particular data object
03:00should be hidden in the filtered view.
03:01Here are the steps. First of all let's create the filter function. A filter
03:07function always has the same signature. It receives a single argument which
03:11will be a data object and returns Boolean. I am going to create a function
03:16named filterByCity and I will set the name of the argument as item and it's
03:22data type as object and this function will return a value that's Boolean.
03:27Now when you execute the filter, again the ArrayCollection is going to call
03:32this function once for each data item. Your job is to get the value that you
03:36want to compare to, compare to something and return a Boolean expression. I am
03:41going to use the value from this TextInput control with an id of filerInput and
03:46compare it to the City property of the data object like this. If (item.city ==
03:54filterInput.text) and if the two values match, I will return true and otherwise
04:02I will return false.
04:05You can make the logic of the filter function as complex or as simple as you
04:09like. This is a simple example. Notice that the structure of the code though
04:13guarantees that we are always returning a Boolean value. Now to apply the
04:17filter function. Create a new function named doFilter. This is simple function
04:25that receives no argument and returns void.
04:28Now the next step is to examine the value of the filterInput control. If the
04:32user has typed a value into the filtered TextInput that means they want to
04:37filter. If they have left that TextInput control blank however, that means they
04:41don't need to do a filter at all. The most efficient approach here is to set
04:45the filterFunction property of the ArrayCollection to either the name of the
04:49filter function that you want to use or to null if you don't to filter at all.
04:54So, I will use this conditional logic. If filterInput.text.length is 0 then I
05:03am going to set the ArrayCollection's filterFunction property to null, meaning
05:07we don't to filter and we want to expose all of the data. The name of the
05:11ArrayCollection that we are filtering on is contacts and it's declared at the
05:15top of the Script section. So returning back to the dofilter function. I will
05:20use this code to eliminate any filters. Contacts.filter function = null. Then
05:28in the else clause, I will set the filter function to the name of the function
05:32that I want to execute for each data object, filterByCity.
05:36Now I am calling this the name of the function. In reality, we are passing the
05:40function as an object to the filterFunction property. Finally after the
05:46conditional clauses, call the refresh method of the ArrayCollection as follows,
05:50contacts.refresh(). Now to execute the filter, go down to the declaration of
05:58the Panel container that contains the DataGrid and all of the other user
06:02interface controls. Locate the button with the label of Filter add a click
06:06event listener and call the method doFilter. Save the changes and run the application.
06:14When the application appears, it displays all of the data. Now I am going to
06:18type in the name of a city, I will use Houston and click the Filter button and
06:24you will see that only the rows that have that value in the City column are
06:28displayed. Now I will remove the filter by deleting that value click the Filter
06:33button again and all of the data appears. Notice that even though we are
06:37filtering on a thousand records, the filtering process executes in an instant.
06:42This sort of filter is very, very fast and you can filter enormous amounts of
06:46data on the client without having to do a round trip to the server.
06:50To really thoroughly understand what's happening here, I am going to go back to
06:54the code, to the filterByCity and add a call to trace. I am going to output a
07:00literal string of Filtering on and then I will concatenate that to the city
07:05property of the current data object. I will save the change and run the
07:10application again. This time in Debug mode and then I will resize the
07:15application browser window, so that I can see the console of Flex Builder in
07:19the background.
07:20Now I will click into the City Filter and I will type a city name, this time I
07:24will type Jackson and click Filter and you will see in the console that the
07:28filter function has been called 1000 times in an instant. I will go back to the
07:33application and remove the filter, click the button again and this time you
07:39should see in the console that the filtering function isn't being called at
07:42all, because the filterFunction property of the ArrayCollection is set to null.
07:47So that's one of the advanced features of the ArrayCollection class. It allows
07:51you to filter data on the client using a very fast architecture without having
07:56to resort to using the database on the server. This can eliminate network
08:00traffic, database usage and all sorts of overuse of other shared resources and
08:05push the processing of this data filtering mechanism down to the client application.
Collapse this transcript
Sorting data with the ArrayCollection class
00:00In this video, I am going to describe another advanced feature of the
00:04ArrayCollection class that allows you to sort data on the client. Using this
00:08feature you can sort data on one or more columns of the data objects within an
00:13ArrayCollection, you will use a set of classes name Sort and SortField. The
00:18sort object is attached to the ArrayCollection through its sort property and
00:22you create one or more SortField objects to represent the fields on which you
00:26want to sort.
00:27For this demonstration, I will use the application SortingData.mxml. This
00:32application like the one in the previous video retrieves a set of data that's
00:36in an XML file in the project and then displays the data in a data grid
00:41component. This version of the application has a set of radio buttons at the
00:45bottom for sorting on the City column and on two columns Last Name and First
00:50Name and the action script class is that I described.
00:53I will close the browser and return to the code. The application already has a
00:57function called doSort. Here is how you create a sort, let's say for example
01:02that you want to sort on a single column or property of the data objects and
01:06the ArrayCollection, the first step is to create an instance of the SortField
01:11object like this, I will create a variable named Field data typed as a Sort
01:16Field class, and then instantiated using the classes constructor method.
01:23The SortField constructor method allows you to pass in a number of values. The
01:27first argument is the name of the property on which you want to sort. So for
01:31example, if I wanted to sort on the City column, I would type in the name of
01:35their property as its known in the ArrayCollection.
01:37I will type in the value of City, the next argument indicates whether you want
01:43to sort using a case insensitive or sensitive architecture. By default, the
01:48sort is case insensitive, if you want to make it case sensitive you pass in a
01:51value of true and the third value is the descending argument. By default the
01:57sort is ascending, if you want it to make descending you pass in a value of true.
02:01I am going to leave out that argument and the result will be a sort on the city
02:06property which is case insensitive. The next step is to create an instance of
02:10the sort class. I will call it mySort and data type it as the sort class. You
02:18instantiate the Sort class using the classes no arguments constructor method.
02:22Then you take your SortField objects and you pass them into an array and pass
02:28the array to the fields property of the sort object like this.
02:32I will use a bit of short hand mySort.fields =. Then I will add a pair of
02:38brackets to declare an ActionScript array and pass in the SortField object. The
02:43next step is to attach the sort object to the ArrayCollection. I will use the
02:48ArrayCollection and contacts and set is sort property to mySort. The final step
02:54in the process just as with filtering on the client is to refresh the
02:58ArrayCollection. I will call contacts.refresh(). Now, to trigger the sort
03:04operation, I listen for an event of the Radio Button Group named itemClick and
03:09I will call my function doSort.
03:12For the movement, I am always sorting on the City field. I will fix that in the
03:15later part of the exercise. I will run the application when the Data first
03:21appears it's returned in the same sort order as its declared in the XML file,
03:26but now when I click either of the radio buttons the result is to sort by City.
03:32Let's return to the Source code and I would also like to demonstrate how to
03:35apply a sort on more that one field at the same time.
03:39Notice that the radio buttons each have values of city and name. So within the
03:43doSort function I am going to add some conditional code that detects what kind
03:47of sort operation is being asked for. I will put in the conditional clause
03:51that's look like this if (sortGroup.selectedValue.toString() == "city") and
04:02now, I am going to move the code around a little bit. I will take the line of
04:06code that creates the sort object and I am going to move that above the If declaration.
04:11I moved the code up by the way by holding down the Alt key and pressing the up
04:15cursor key, once for each line I wanted to move it. Now, I will take the two
04:19lines of code that create the SortField object for the City column and set the
04:23array, and I will move those within the If clause. Now, I will add in else
04:30clause and I am going to copy the code from the first part and paste it into
04:37the else clause and then I am going to modify the version in the else clause as follows.
04:42The only other radio button in the radio button group request a sort by
04:47lastname and firstname. So I am going to change the code as follows, I will
04:51change the name of the variable to field1 and change the name of the property I
04:56am sorting on to lastname. Now, I will clone that line of code, change the name
05:01of the second variable to field2 and change the sort field to firstname.
05:06I am going to move the code around a little bit so we can see all of it on the
05:11screen at the same time, and then I will change the fields property of the sort
05:16object as follows, it will still be an array but this time it will contain two
05:22SortField objects, field1 and field2. So now the conditional code is working as
05:27follows, regardless of which sort, sort order is being used I am creating the
05:32sort object first, then i am applying some conditional logic and determining
05:37whether the user has asked for the single column sort on city and if so I am
05:41setting up the architecture for that and otherwise I am assuming that they are
05:44asking for the two column sort on Last Name and First Name and I am setting up
05:48the objects for that.
05:49At the end of the process, I am applying the sort object to the ArrayCollection
05:53and then refreshing the ArrayCollection. I save and run the application again.
05:58I will once again click the City radio button, and you will see that the data
06:04is sorted by city and then I will select the other radio button and sort by
06:08Last Name and then First Name and notice that there are multiple rows with the
06:13last name of Adams and within that data set they are sorted by first name
06:17alphabetically.
06:18So you can see that you are effectively doing a multi-property sort. So that's
06:22how you apply sort operations using the ArrayCollection, the Sort class and the
06:28SortField class. To review the architecture one more time, you create the sort
06:33object, you create SortField objects for each column or property on which you
06:38want to sort, you wrap those into an array, apply them to the field property of
06:42the sort object, apply the sort object to the ArrayCollection through its sort
06:46property and refresh the ArrayCollection.
Collapse this transcript
Finding data with the IViewCursor interface
00:02In this video, I am going to describe an interface known as a view cursor. The
00:06purpose of a view cursor is to allow you to reverse data in an ArrayCollection
00:11moving up, down bookmarking the data and locating data. I am going to describe
00:16one particular feature of the cursor interface in this exercise. For this
00:20demonstration, I will use the application FindingData.mxml.
00:24In this version of the application, once again we are retrieving a displaying
00:27data from an XML file. When the data first appears, it's already sorted on Last
00:32Name and First Name and there is a small data entry form at the bottom of the
00:36panel that allows you to type in a first name and last name value. I am going
00:41to show you how to use a cursor to search by particular values and locate data
00:46objects in ArrayCollection, unlike the filtering functionality that I
00:51demonstrated earlier in this chapter.
00:53In this example, I won't be filtering or reducing the number of rows that are
00:56displayed, instead I am going to locate a particular record and move data grid
01:01selector row to that record. You get an instance of a view cursor by calling
01:08the ArrayCollection's create cursor method. Go to the Source code and locate
01:14the existing function in this application named doFind. Notice two things about
01:19the way this application presents the data.
01:21First of all the doSort function is being called when the data is first
01:25retrieved from the XML file. So it's already sorted and then the data grid
01:30component in this application has its sortableColumns property set to false.
01:35This is because you can only use a cursor to locate data on a sorted view of
01:40the ArrayCollection and the columns on which you search must be a part of the sort.
01:46So the doSort function is already setup to sort on lastname and firstname and
01:51those are the columns on which we are going to search. In fact if you try to
01:55use the functions that I am going to demonstrate here and you try to search on
01:58a property that's not a part of the current sort order, a run time error occurs
02:02in Flex 3.
02:03Here are the steps for using a cursor to locate data. I am going to add all of
02:08this code to the doFind function and that function will be called when I click
02:12the button in the interface. The first step is to create a variable data typed
02:16as an IviewCursor. I am going to name the variable cursor and give it its data
02:21type of IViewCursor and then I am going to initialize the object by calling the
02:26ArrayCollection's create cursor method.
02:29Now, I am going to create a search object. The purpose of the search object is
02:34to indicate which properties you want to search on and what values you want to
02:38search for. You create it as a generic ActionScript Object. I will create a new
02:43variable name searchObj data typed as an Object, and then I will initialize it
02:49using the object classes no arguments constructor.
02:53Next, I am going to create named properties of the search object where the name
02:57of each property matches the property of the data objects I want to search on.
03:01I will get the values from the input controls at the bottom of the application.
03:06First, I will add a property named lastname and set its value to
03:10lnameInput.text and then I will do the same thing again for the first name
03:15field searchObj.firstname = fnameInput.text.
03:23Again the names of the properties here must match the names of the properties
03:27in the data objects you are searching. Now, I am going to use the search object
03:32by calling a function of the cursor named findAny. There are three functions
03:36that you could call in this location findAny, findFirst and findLast, they each
03:41take a search object as their parameter and they each return a boolean true or false.
03:46If you get back a value of true that means a data object was found and if you
03:51get back a value of false that means nothing was found. So here is the
03:54conditional code. if (cursor.findAny, and then now pass in the search object
04:04and then I will put in a pair of braces and an else clause and then I will go
04:11back to the first part the if clause.
04:14If the cursor finds an object and returns true then the cursor objects current
04:18property points to the data object that was found. I am going to take that
04:23reference to the data object and pass it to the data grids selected item
04:27property that will cause the data grid to select the appropriate row. The data
04:32grid's ID is myGrid. So I will its selected row as follows, myGrid.selectedItem
04:40= cursor.current.
04:43Now, after I set the selected item property I am also going to make the data
04:47grid scroll to that row using this code. myGrid.scrollToIndex and then pass in
04:54the currently selected index of the data grid using (myGrid.selectedIndex). In
05:03the else clause, I will simply report to the user that nothing was found. I
05:08will use the Alert class's show method and I will output a message of ("No data
05:13was found for this search", and I will add a title of "Not Found");
05:24So that's the basic functionality of a cursor when you use it to search for
05:28data. Once again, you use the findAny, findFirst or findLast functions. findAny
05:33will search any where in the ArrayCollection. findFirst goes to the top of the
05:37ArrayCollection and searches forward and findLast goes to the bottom of the
05:41ArrayCollection and searches backward. Save and run the application and when
05:46the data is displayed in the application, you can try searching as follows,
05:51let's say for example that you want to search for something that was way down
05:54at the bottom.
05:54I will search for Frank Young. So I will start of selecting a row, I will type
06:00in values of Frank and Young and click Search and you will see that the data is
06:06located correctly.
06:07Now if you type in a value that's not found and you click Search, you should
06:12get the message, no data was found for this search. So you can see that the
06:16cursor component is able to search for data and you determine which columns you
06:21are searching on and which values by creating a generic ActionScript Object
06:26which we call the search object and applying properties whose names match the
06:30properties in the data objects you are searching.
06:33This allows you to do a finally tuned search completely within the client
06:38without having to go back to the database and the application server and create
06:42unnecessary round trips across the network. The cursor component also has
06:47methods that allow you to get bookmarks to data and return to the data later
06:51on. The one important limitation to understand about the cursor interface when
06:55you are using it the find data is that the data that you are searching must be
06:59sorted and the columns on which you are searching must be a part of the sort order.
07:03If your particular application's functionality is able to work within those
07:07limitations then this is a great interface and tool that you can you use to
07:12allow server-side location of data without use of the server-side database.
Collapse this transcript
12. Working with Modules
Creating a Module component
00:00In this chapter of the video series I am going to describe how to use run time
00:04loadable modules. The module architecture in Flex allows you to create large
00:08scale Flex applications that have dozens or even hundreds of views or
00:12presentations and allows you to break down the views and functionality in the
00:16application in to a multiple SWF files.
00:19The main application file can be kept very, very small and then as the user
00:23navigates around to different bits of functionality in the application, you'll
00:26be able to download that functionality from the website as needed.
00:30As result the initial download is kept as small as possible. For the
00:34demonstrations in this chapter, I will use a Flex project archive that is in
00:38the Exercises folder. If you have access to the exercises files and you are
00:42following along you can import the project now.
00:45From the Menu select File, Import FlexProject. Click the Browse button next to
00:52archive file, navigate to the exercises folder and to it's sub folder Chapter
00:5612, and then select and Import the file Chapter12BeginProject.zip. In this
01:03video I am going to describe how to create a new module component. A module is
01:08a visual container, in fact it's derived from the Vbox container, but unlike
01:12them Vbox it has a Layout property that allows you to set a modules layout to
01:16either horizontal, vertical or absolute.
01:19Just like the panel container in the application. You typically create each
01:23module as an MXML component, but Flex Builder has its own distinct wizard for
01:28creating a module that has some other options from the standard component
01:32creation wizard. Go to the Flex Navigator view open the project and open it's
01:37source folder and you find that there is sub folder there named modules. That
01:41is where I am going to place all of the modules for this application.
01:45To create a new module right click on the module's folder or control click on
01:49the Mac and select New MXMLmodule. Notice that this is a different menu choice
01:55than MXML component. The new MXL module wizard asked for the file name which
02:01will be a .mxml file, just like any other component. I am going to name my new
02:06module ChartModule.MXML. Just like other components you can set the width and
02:11height in the wizard, I am going to set the width and height of the ChartModule
02:15to 100% each, so that the module component will expand to fill it's container
02:20and I'll set the layout value to vertical.
02:24The next option has to do with optimization of the SWF files size for the
02:28compiled version of the module. The default is to optimize the SWF file for use
02:33with the particular application. This allows you to eliminate redundant
02:38compellations meaning, that if you have a particular visual component or other
02:42class that's used both in the application and in a particular module by
02:46optimizing, you can minimize the size of the module and their by speed up the
02:51download and availability of the module when you need it. I am going to
02:54optimize my SWF file size for a particular application Use Moduleloaded.mxml.
03:00Then I'll click finish and that creates the module, just like any other MXML
03:05component. A module consists of a MXML file, but its root element is MXML: module.
03:12Now, to fill in the functionality of this module I am going to open an
03:15application from this project named Simple Chart.mxml. This is an application
03:21that displays a pie chart with some fixed data and then a legend at the bottom.
03:27I'll go back to Flex builder to the code for the application containing the
03:30chart. Now I am going to canabalize this application, I am going to take it's
03:35script and also all it's visual controls and copy them into the ChartModule.
03:39I will click at the beginning of the script section then scroll down to the
03:44bottom, hold down the Shiftkey and select everything inside the application
03:49tags. Now I will copy that code to the clipboard go back to the module and then
03:54paste the code with in the module tags. I'll save the changes and each time you
04:00make a change and save the code for a module it recompiles the module itself.
04:06Let's take a look at the resulting SWF file for this module. Go back to the
04:11Flex Navigator view to the bin-debug output folder. You notice within the
04:16output folder there is the module folder now and in that folder there is now
04:20file named ChartModule.SWF. This is the compiled version of your module.
04:25Let us take a look at the file size, right click on the SWF files or control
04:29click on the Mac and select properties from the Menu that pops up. Notice the
04:35size of the module because I am using charting components for the first time
04:40this file is fairly large 173k because it now has to compile in the definitions
04:45of all the visual controls I am using including the pie chart.
04:49Now, I am going to demonstrate optimization. I'll go down to the source folder
04:54and locate the application for which I optimized my module component. I will
04:59open the application and in this script section I am going to declare a single
05:04instance of the pie chart component. I will use this syntax private var chart:
05:11data typed as pie chart. I will save the changes now I am going to clean the
05:17project which will cause everything to recompile. From the Menu I'll select
05:22Project, Clean and then click OK and that will cause all of the applications
05:28and components to look at each other and we optimize as needed.
05:33Now I will go to back to the Output folder to the Module sub folder and once
05:37again take a look at the properties for the complied component and you'll see
05:41that the component has shrunken dramatically. On my system from about 170k down
05:46to about 46k. So, that's how optimization of modules works. By optimizing
05:52against a particular Flex application you eliminate redundancies in the
05:56compiled SWF files and you minimize the size of the modules.
06:00Now in the next video I'll show you how to use a component called the Module
06:04Loader to load this module at run time.
Collapse this transcript
Loading a module with ModuleLoader
00:00In this video, I am going to describe how to use a component called the module
00:04loader to load modules at runtime. Before you can use the module loader, you
00:08must have first created and compiled a set of modules. I have created one so
00:12far and I am going to add one more during this video. For this demonstration, I
00:16will use the application usemoduleloader.mxml. If you are following along with
00:21the exercises, you can open this file now.
00:24The module loader is a visual container. You place it in your application,
00:28where you want the module to appear. For example, if you want to place the
00:32module loader in an application that uses absolute layout, you can use the
00:36module loader's X and Y properties or constraint the properties to place it in
00:40a specific location on the screen. I am going to declare my module loader after
00:45the application control bar and then I am going to set its width and height
00:48properties to a 100% so that it fills the available space in the application.
00:53Place the cursor after the Application Control Bar declaration and declare a
00:57module loader. Set its ID to loader. Set its width and its height to 100% each.
01:08Now because you are not adding anything to the loader initially, you don't have
01:12to put in a pair of tags, even though it is a container. The next step is to
01:16actually load a module at runtime. This application already has a function
01:21called Load Chart module and this function is being called when you click the
01:24button labeled Load Chart. Place the cursor inside the function, there are two
01:29steps to loading a module.
01:30First you set the URL property of the module loader component as follows
01:36loader.url = and then you typically use a relative address pointing to the
01:41location and the file name of the compiled module SWF file as follows
01:47modules/chartmodules.swf. Be sure to use a forward slash here and not a back
01:54slash. On windows, the back slash might work for now, but when you load this
01:58application from the web, it wouldn't work. The next step is to call a method
02:03of the module loader component called load module. This function doesn't take
02:07any arguments, it simply uses the URL when you have already indicated where
02:11your module is and loads it from the web. I will use this syntax loader.load
02:16module, save the changes and run the application. As the application starts up,
02:24it doesn't display any modules initially. Now click the button labeled Load
02:28Chart and you should see the Chart Component appear, by clicking the button,
02:33you are downloading the SWF file from the web and it's being displayed. Now as
02:37with images, the SWF file will be cached on the local disk.
02:40So the next time that same module is loaded, you will be loading from the
02:44cached content rather than having to download it again from the website. Now
02:48modules are more impressive if you have more than one, and there is already
02:51another module component in this application. Take a look in the modules folder
02:56and you will see there's a file there named formodule.mxml. Notice that the
03:01icon on formodule.mxml doesn't look the same as Chart Module which has the
03:05little indicator indicating that this is a compiled module. That's because this
03:09module has not been made a part of the project yet.
03:13Here's how you add an existing module component source code file to your
03:17project and cause it to start compiling. Go to the menu and select the project,
03:22properties. Select Flex modules from the list of categories and you will see
03:28that Chartmodule.mxml is being built for this project. Click Add and then click
03:33the Browse button and navigate to the source folder within the project to the
03:38module's sub folder and select the file For Module.mxml. Click Okay, just as
03:45when creating a module from scratch, you have the opportunity at this point to
03:49optimize the module for this application. Click Okay and then click Okay again,
03:56now take a look at the Flex navigator view and you'll see that formoduele.mxml
04:00now has the icon indicating that the module is being built. And if you then go
04:05to the Bin Debug output folder, you'll see that formodule.swf has been created.
04:10Now go back to the application. Go to the loadformodule method and add code to
04:17load this module at runtime as follows, loader.url = modules/formodule.swf and
04:29then once again, make the call to loader.loadmodule. Save your changes and run
04:35the application.
04:38Now, you are once again able to load the chart component but you can also go
04:42over and click the load form button and that will load the form component and
04:46you can move back and forth between the modules as needed.
04:49So this is how you can maintain multiple modules in a Flex application and load
04:54each one as the user requests that particular functionality.
04:57Now in the next set of videos, I will talk about how to share information
05:01between multiple modules using a variety of approaches, including events,
05:05centralized model management and passing data directly to module instances.
Collapse this transcript
Handling Module Component events
00:00In this video, I am going to describe how to listen for and react to events
00:04that are dispatched by module components that are loaded by the module loader
00:08container. Just as with other MXML components, you can share custom information
00:13from the module component by dispatching a custom event.
00:16Let's start in the modules folder of the project. If you have access to the
00:20exercises and you are following along, go to the modules folder and open the
00:24file FormModule.mxml. Notice that this component defines a custom event named
00:30submit and it dispatches an instance of a custom event class named
00:34ChartDataEvent. At runtime, when the user clicks the button, a variable named
00:38data, data typed as an ArrayCollection is created and populated with
00:42information from the data entry form. The structure of this data is compatible
00:46with the pie chart used in the other component. That data object is then
00:51wrapped in to an instance of the ChartDataEvent custom event class. And then
00:55the event object is dispatched from the module, this is exactly how you would
00:59dispatch the custom event from any sort of MXML component to share information
01:04with the rest of the application.
01:06Listening for this event however is a little bit different, the module
01:09component instance is a child of the module loader at runtime and in order to
01:13listen for an event on this object, you have to wait until the object has been
01:17loaded into memory and only then can you add an event listener. I am going to
01:22work in an application named, ModuleEvents.mxml, this application starts where
01:27the last one left off. It loads two different modules, a chart and a form. When
01:32you load the FormModule, you are going to want to listen for an event called
01:36ready. The ready event which is dispatched by the module loader tells you that
01:41the module has been completely loaded and is ready for use.
01:44Start in the script section and create a new private function named
01:49readyHandler. The ready event dispatches an event data typed as the standard
01:56event class. Create the eventHandler function to receive an event object typed
02:03as event and return void, now go down to the ModuleLoader declaration, add a
02:09ready event listener and call this function, passing the event object. Now
02:16returning back to the readyHandler, once you have loaded the component instance
02:20into memory and you get the ready event, you can now listen for the custom
02:24events of the component instance.
02:26The Form component instance is going to dispatch an event named submit. So we
02:30are going to listen for that event, only if we have actually loaded a form. You
02:34can reference the component instance using the child property of the module
02:38loader. So first add this conditional code, if loader.child is FormModule, if
02:46this condition is true then that means that this ready event happened because
02:50we loaded the form module component and now you are ready to add an event
02:54listener for the custom event of the module. Place the cursor after this
03:00function and create another new function, this one called submitHandler. The
03:05event argument for this submitHandler function will be an instance of the Chart
03:10event class, that's the custom class that's constructed and dispatched by the
03:14form module component. As with all other eventHandler functions, it returns void.
03:19Now we have the eventHandler function and we can add an event listener for it.
03:23I will go back to the readyHandler function, place the cursor inside the
03:27conditional block and I will add the event listener using the following code
03:31loader.child.addeventListener and because we are listening for a custom event
03:37name, I'll type it in as a literal string, the name of the event will be Submit
03:42and then I will pass in the submitHandler function as an object to indicate
03:46that that's the callback method for this event. Next I'll place a break point
03:51on the last line of the submitHandler function, that's the line with the
03:54closing brace, I'll save the application and I will run it in Debug mode.
04:00Now I will load the form and when I load the form, the readyEvent is triggered
04:04causing the event listener to be added. I'll type some numeric values in of
04:092000, 3000 and 4000 for my chartData. I'll click the Submit button and that
04:17will cause me to hit the break point. I will click yes to open the Debugging
04:21perspective, go to the variables view and take a look at the event object which
04:27contains the data that I submitted into the form.
04:30The data comes back as an ArrayCollection. So now to save this data
04:34persistently and make it available for all components in the application, I am
04:38going to follow the pattern that I followed in the past, when working with
04:42individual components. I will come back to Flex Builder and terminate the
04:46Debugging session and go back to the code. At the top of the source code, I am
04:52going to declare a new Bindable variable named chartData, data typed as an
04:58ArrayCollection. Then I'll go back down to the submitHandler function and then
05:03I'll get the data out of the event object by referring to it's data property
05:07which hold the ArrayCollection that was shared by the FormModule component.
05:14This data object is already data typed as an ArrayCollection so I don't have to
05:18explicitly cast it and now when the user submits the form, the data will have
05:22been shared with the rest of the application.
05:25I'll once again run the application in Debug mode, I will load the form, type
05:33in some values, click the Submit button, come on back to Flex Builder, go in to
05:41the Debugging perspective and look at the variables view. And I will see that
05:46once again the data is available in the event object. But now I will go over to
05:50the expressions view and I will add a new watch expression for chartData, click
05:56OK and you should see that the chartData variable contains the same data that
06:01was just shared from the data entry form.
06:04It's now stored in a persistent variable at the application level, in a place
06:08where it can then be passed to other components. And in the next video, I'll
06:12show you how to take that data that is stored at the application level and pass
06:16it to a component instance that's loaded as a module.
Collapse this transcript
Passing data to a module
00:00In this video, I am going to describe how to pass data to a module component
00:04after it's been loaded into a module loader. For this demonstration, I will be
00:08using two files, PassData.mxml and ChartModule.mxml. ChartModule.mxml was
00:15created in an earlier video in this chapter and PassData.mxml is an application
00:20that includes the same functionality as the one I created in the previous videos.
00:24As the application starts up, no modules are displayed initially. When the user
00:29clicks either of the modules, such as the Load Chart module or the Load Form,
00:33we see those modules. And in this version of the application when the user
00:37types values in to the data entry form and then clicks submit, that causes that
00:42data to be wrapped into a custom event object and dispatch it to the rest of
00:46the application. In this video, I am going to show you how to take that data
00:50after it's been saved to a persistent variable at the application level and
00:54explicitly pass it to the new component that's just about to be loaded.
00:58I will close the browser and go back to the application. When the form
01:03component dispatches its data through an event object, that data is being saved
01:08into this chartData ArrayCollection. Now I am going to add code to the
01:12readyHandler function. Whenever a module is loaded into memory, the
01:17readyHandler function is being called because of the ready event listener on
01:21the module loader component declaration here.
01:24We already have a conditional block for the form module and now I am going to
01:28add another one for the chart module as follows; else if (loader.child is
01:35ChartModule). In this section of the conditional block, I am going to be taking
01:42the data from the form and passing it to the chart, so I also need to check
01:46whether the chartData variable is null. If the user has submitted data from the
01:51form module, then that data won't be null. So I will add a Boolean ampersand,
01:56ampersand as a Boolean And, and then I will examine the chartData variable and
02:00check to see whether it's null. So that's my complete conditional block.
02:06If loader.child is ChartModule and the chartData variable isn't null, now I am
02:12ready to pass data to the ChartModule object. The next step is to get a handle
02:17to the module object that was just loaded into memory. I will use this syntax,
02:22Var chart, data typed as ChartModule = Loader.child as ChartModule.
02:34The next step is to pass data to the ChartModule, right now though the variable
02:39being used within the ChartModule to manage the data for the chart component is
02:43private. I have to fix that, before I can continue with this code. So now I
02:48will go over to ChartModule.mxml and I will change the access modifier for the
02:53acExpenses Array Collection within the module from private to public. I will
02:58save that change and come back to the application. And then I will add a line
03:03of code to set that data as follows -- chart.acExpenses = chartData. So now as
03:13the chart module loads, we check to see whether that data is null, and if it's
03:17not, we pass it in.
03:18Now the final step in this process is to cause the chart to load when the form
03:23has been submitted. Go back down to the submitHandler function. This is where
03:27we are currently capturing the data from the data entry form module. Place the
03:32cursor after the existing line of code that's capturing and saving the data and
03:36then call the existing function load ChartModule. This will cause the
03:40ChartModule to be reloaded after the data has been saved to the persistent
03:45Array Collection at the application level. Save your changes and give it a try.
03:50Run the application. Click the Load Chart button and you will see that it loads
03:55with its default data. Now go to the form and fill in some numeric values, I
04:01will enter values of 111, 222 and 333. Click the Submit button and you should
04:09see that the chart is reloaded this time displaying the data from the data entry form.
04:14So this is one mechanism for sharing data between modules at runtime, because
04:19module component instances don't stick around in memory, that is, once the
04:23module loader opens another module, it has to discard the reference to the old
04:27one. You have to have a way to save the data persistently between module loads.
04:32In this example, I am using a custom event dispatched from the form module and
04:37a public property in the display or the ChartModule.
Collapse this transcript
13. Localizing Flex Applications
Creating resource bundles in ActionScript
00:00In this chapter of the video series, I am going to describe how to use Resource
00:04Bundles to localize Flex applications, that is, how to create sets of phrases,
00:09that you can then bind to a runtime and make your application easy to read and
00:14friendly to different international locations.
00:17Internationalization and locale management are built into the Flex framework.
00:21There are two primary approaches that you can use for creating what are known
00:24as Resource Bundles for different locales. In one approach, you create a set of
00:29compiled files and these Resource Bundles can either be compiled into the
00:33application or loaded at runtime.
00:35Creating compiled Resource Bundles is beyond the scope of this chapter. I am
00:39instead going to be focusing on how to create Resource Bundles and use them
00:43completely with the ActionScript programming language; this is something you
00:47can do completely in code without having to go out to the Command-Line
00:50Compiler, which you do have to use to create the compiled versions of the
00:54Resource Bundles.
00:55For the demonstrations in this chapter, I will use a Flex project from the
00:58Exercises folder. If you have access to the Exercises and you are following
01:02along, you can import this project now. From the Flex Builder menu, select
01:07File, Import, Flex Project, click the Browse button next to Archive file,
01:13navigate to your Exercises folder which I have installed on my desktop, then go
01:17to the Chapter13 folder and from there select and import the file
01:21Chapter13BeginProject.zip. Then go to the Flex navigator view, open the source
01:26folder of the project and then open the application, UseResourceBundle.mxml.
01:32This application currently has label in two buttons. The label has a text value
01:37of Localizing Flex Applications and a font weight of bold and the buttons have
01:41labels but aren't doing anything yet. In order to localize an application using
01:45ActionScript, the first step is to create an object named ResorceBundle, you
01:50create one instance of the ResourceBundle class for each locale that you want
01:54to support. For Example, in this application I am going to show you how to
01:57switch back and forth between showing English and French phrases in an application.
02:02So I would need two ResourceBundles, one's for each language. Initially I am
02:06going to put the code for creating the ResourceBundles in the init function.
02:10That's being called upon application startup but then I am going to move that
02:14code out to a separate ActionScript class. If you are following along, place
02:18the cursor inside the init function, declare a variable named myResources, data
02:23typed as the ResourceBundle Class.
02:26When you select this class from the list of available classes, Flex Builder
02:29adds an import statement for it. Finish the declaration and then go down a
02:34couple of lines. Now we are going to create a ResourceBundle for US English.
02:38The Code looks like this, myResources=new ResourceBundle and I am calling the
02:45ResourceBundle classes constructor method here. And now I pass in a locale identifier.
02:50Locale identifiers are typically made up of two alpha strings separated by an
02:55underscore. The first two character string is the language and the second two
02:59character string is the country. For example, for English in the United States,
03:04the correct locale identifier is en_US as a string. Also add a name for your
03:13ResourceBundle which we will call myResources. The bundle name and the variable
03:19identifier are two different things.
03:21The variable name is used to refer to the ResourceBundle, while you are
03:25manipulating it in a code. The Bundle string which you pass into the
03:28constructor will be used to identify the ResourceBundle when you want to use
03:32phrases from the bundle in your application. The next step is to add phrases.
03:37Each phrase is added as a named Object in the ResourceBundle's content
03:41property. In order to properly control each key that refers to a phrase, you
03:46use bracket style syntax to refer to the property name as follows,
03:51Resources.content, and then I will use a bracket and then the key for this
03:56phrase, which I will set as the word Open and then after an Equal As assignment
04:01operator, the string that you want to use for this key, when you are in the
04:05en_US locale. And I will put in the English word Open.
04:09Now for each phrase that you want to localize, you will add a new item to the
04:12content Object, so I will add one more. I will set another item in the content
04:19Object, this time with a key of close. You will continue on this phrase for
04:23each phrase that you need to localize. Now the next step is to add the new
04:27ResourceBundle to what's called the resourceManager. resourceManager is a
04:32property of the application component. It has a method called Add
04:36ResourceBundle, so after you have constructed the ResourceBundle in
04:39ActionScript code, you call this method and pass the ResourceBundle in as
04:43follows, resourceManager.addResourceBundle and then pass in your new
04:49ResourceBundle which I have named myResources.
04:52You will then repeat this for as many locales as you want to support. I am
04:57going to select this code, copy it and then paste it and now I will be able to
05:03create a second ResourceBundle for another language. This one will be for
05:07French which is the language French, fr_ in the country France, FR. Now I will
05:17change the strings that will be used when I am using that locale. The French
05:21word for Open is Ouvrez and the French word for close is Fermez.
05:30So my application is now enabled with two completely separate ResourceBundles,
05:34the final step is to update your resources. You do this by calling a method of
05:39the resourceManager Object named Update. I will move the cursor below all the
05:44ResourceBundles creation and I will call resourceManager.update and that causes
05:51these resources to become immediately available to the application. So that's
05:55how we create the resources. In the next video, I will show you how to create
05:59labels that get their text values by binding to these items in the
06:04ResourceBundles.
Collapse this transcript
Using ResourceBundle binding expressions
00:01In this video, I am going to describe how to use resource bindings to use the
00:05resources in the resource bundles that you have created. The resourceManager
00:08object or class has methods to retrieve strings, numbers and other data types.
00:13When you call the method you pass in two values, the name of the bundle that
00:17contains the resource you want and the key for the resource. This results in
00:22outputing the associated string or other value that goes with that resource. I
00:27am going to continue working in the application, UseResourceBundle.mxml. And I
00:31will go down to the bottom of the application to where the visual controls are
00:35and I will place the cursor after the label with the text Localizing Flex
00:39Applications. I will create a label control and I will set it's text property
00:44using a binding expression as follows.
00:46I am once again going to refer to the resourceManager object, which is a
00:50singleton property of the application. I will use this syntax,
00:55resourceManager.getString and then I will pass in the name of the bundle that
01:01contains my resources, myResources and then the key that's associated with the
01:06string I want to output. I will refactor the code a bit so we can see it all on
01:15the screen at the same time. So I am calling the getString method, passing in
01:19the name of the bundle and the name of the resource key.
01:22Now this application starts up by default with the English United States
01:27locale. The reason this happens is because when you create a brand new Flex
01:32project using Flex Builder, the version that's released in the United States,
01:35the locale is automatically set in the compiler arguments for the project. Flex
01:41builder 3 is delivered with 2 pre-built locales. One for English and one for
01:45Japanese. The Localized versions of Flex Builder of course come with locales
01:49for French or German or whatever other locale the product has been localized for.
01:54But the version that's released in the United States only has this one English
01:58language locale, so that's the only one that you can put in the compiler
02:01arguments. I will show you in a later video, how to switch to a different
02:05locale at runtime though.
02:07So now that we understand that we are working with the en_US locale and that we
02:13have added these resources to the locale in the myResources bundle, we can now
02:18run the application and you should see that the label displays the string
02:22associated with the key open. I will close the browser and return to Flex
02:27Builder and then clone the label and I will change the key for the second
02:32resource to the word close. I will save the changes and run the application and
02:38once again you can see that the associated string is displayed.
02:42Right now I am creating all of my resources in the application's init function,
02:47it will be nice to take all of these code and put it in a separate ActionScript
02:51class. I have prepared a class named ResourceUtility, that's in the utilities
02:56folder of the source root. Open that ActionScript class now. Notice that this
03:02class has a static function named setResources that receives a single argument
03:06named resourceManager, datatyped as an interface named iresourceManager. At
03:13application startup, I am going to call this function and pass in a reference
03:17to the application's resourceManager object. I am going to move the code from
03:21the application level into the static function first.
03:24I will go back to the application, and I will select all of the code in the
03:29init method and I will cut it to the clipboard. I will then go back to the
03:33ResourceUtility class and then I am going to paste that code into the
03:38setResources static function and I will un-indent it a little bit so it looks
03:43right in the context of that code.
03:46Now I will save the changes to that code and you will see that there are some
03:49compiler errors that are generated because I need an Import statement for this
03:53ResourceBundle class. I will place the cursor after the class name and press
03:57Ctrl+Space and Flex Builder adds the required Import statement. I will save the
04:02changes again and the errors go away.
04:06Now we will go back to the application, UseResourceBundle.mxml. Within the init
04:12function, I will call the ResourceUtility class's setResources method and pass
04:18in the application's resourceManager Object.
04:21Now, if the application starts up, I am once again executing all of the code to
04:26create my resources in ActionScript. It's all now encapsulated though in the
04:31static function and as the functionality of my application grows and I have to
04:36add new phrases, I have one place to go and do the work, the static function of
04:41this class. I will go back to the application save the changes and run the
04:46application one more time and you will see that once again the strings are
04:50being correctly displayed.
04:52Now in the next video, I will show you how to switch from one locale to another
04:55at runtime, so you can switch from one complete language to another.
Collapse this transcript
Setting locales at runtime
00:01In this video, I am going to describe how to change from one locale to another
00:04at runtime, so that you can display the values or resources in a resource
00:09bundle that are associated with the new locale.
00:12In order to change locales, you set a property of the resourceManager object
00:16named localeChain to an array of locales. You put the locales in, in the order
00:22of preference. Then for each resource that you bind to using the resource
00:26manager's method such as getString, the resource manager will go through the
00:30locales one at a time and as soon as it finds the key that you have requested,
00:35it will return the value that's associated with it. This allows you to combine
00:39resources where in some cases, the resource maybe translated in every language
00:44and in other cases the resource may only occur in one language. And it allows
00:49you to add your locales in the desired order.
00:52For this demonstration, I will use an application named SwitchLocales.mxml.
00:58This application is in the same state as the previous video. It sets up
01:02resources using the resource utility class's setResources static function.
01:07There are two resource bundles, one for English and one for French. The
01:11application in it's default state is using the English locale because of the
01:15compiler arguments that I showed in an earlier video. For this demonstration,
01:21add a new function to the application. Name the function changeLocale and
01:28design it to receive a single argument named locale, datatyped as a string. And
01:35the function will return void.
01:37Now within the function set the localeChain property of the resource manager as
01:41follows, resourceManager.localeChain = and then a pair of brackets indicating
01:48that we are creating an array and then pass the locale argument into the array.
01:53So now we have a single function that we can call and we can pass the locale
01:57into the function and that locale will be triggered instantly. Now go down to
02:01the bottom of the application, there are two buttons labeled English and
02:04French. Add a click event listener to the first button and call the new
02:10changeLocale function and pass in a string of en_US. Add a click handler also
02:19for the button with a label of French, and once again call the changeLocale
02:23function and pass in the appropriate locale id fr_FR, save your changes and run
02:31the application.
02:32Once again as the application opens, it shows the English phrases, but now you
02:38can click the French button and the values change instantly and you can click
02:42the English button to go back to the original phrases. Resource bundles work
02:46throughout the entire application including in any component instances that are
02:51a part of the application.
02:53To demonstrate this, I am going to make a copy of the code for these two
02:56labels. I will select the lines of code that declare the label objects and copy
03:01them to the clipboard. Now I will go to the components folder of the project
03:06where there is a MyComponent.mxml component. This is a simple component that
03:10just contains a Vbox. I will paste in the labels and then so I can really
03:17clearly see where the component is, I am going to add a background color style
03:21of yellow. I will save the changes to the component and I will return back to
03:26the application SwitchLocales.mxml. Now I will place the cursor after the
03:31buttons and using MXML I will declare an instance of the component, my
03:36component. I will save the changes and run the application.
03:41So, you will see in the application that the locale strings are working both at
03:46the application level and in the nested component level and when you change
03:51locales by changing the localeChain property of this singleton resource
03:55manager, the new values will appear right away regardless of where they are
03:59used in the application. I will click the French button and you will see it
04:02changes both in the application and in the component and then I will go back to
04:06English. So this is a very simple way of implementing a localization
04:11architecture in your application.
04:14Again, it's not the only approach, you can also use compiled resource bundles
04:19and as an application becomes larger and more complex, it's worth checking out
04:23the compiled resource bundle architecture and create complete resource bundles
04:27for each of the locales that you have to support.
Collapse this transcript
Conclusion
Goodbye
00:01Hi, David Gassner here again. Thanks for sitting with me through this video
00:04series on building and deploying applications with Flex Builder 3 and the Flex 3 framework.
00:10In this series I showed how you can extend your Flex application development
00:14skills and use more of the great tools that this development platform offers.
00:18If Flex development appeals to you, checkout my other titles on lynda.com that
00:23describe how to use Flex Builder to create desktop applications that run on
00:27multiple operating systems including Windows and Mac using AIR, the Adobe
00:31Integrated Runtime and in the mean time, happy programming with Flex.
Collapse this transcript


Suggested courses to watch next:



Are you sure you want to delete this bookmark?

cancel

Bookmark this Tutorial

Name

Description

{0} characters left

Tags

Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading
cancel

bookmark this course

{0} characters left Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading

Error:

go to playlists »

Create new playlist

name:
description:
save cancel

You must be a lynda.com member to watch this video.

Every course in the lynda.com library contains free videos that let you assess the quality of our tutorials before you subscribe—just click on the blue links to watch them. Become a member to access all 100,984 instructional videos.

start free trial learn more

If you are already an active lynda.com member, please log in to access the lynda.com library.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Access to lynda.com videos

Your organization has a limited access membership to the lynda.com library that allows access to only a specific, limited selection of courses.

You don't have access to this video.

You're logged in as an account administrator, but your membership is not active.

Contact a Training Solutions Advisor at 1 (888) 335-9632.

How to access this video.

If this course is one of your five classes, then your class currently isn't in session.

If you want to watch this video and it is not part of your class, upgrade your membership for unlimited access to the full library of 1,945 courses anytime, anywhere.

learn more upgrade

You can always watch the free content included in every course.

Questions? Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com.

You don't have access to this video.

You're logged in as an account administrator, but your membership is no longer active. You can still access reports and account information.

To reactivate your account, contact a Training Solutions Advisor at 1 1 (888) 335-9632.

Need help accessing this video?

You can't access this video from your master administrator account.

Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com for help accessing this video.


site feedback

Thanks for signing up.

We’ll send you a confirmation email shortly.


By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

Keep up with news, tips, and latest courses with emails from lynda.com.

By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

   
submit Lightbox submit clicked