Now that you have an idea of how to create basic Flash movies and how to place them in your CFML pages, we can move on to the fun part. If you haven't guessed, the fun part is getting your Flash movies to interact with ColdFusion. This allows the movies to do things like display information from a database, collect information from users, or perform other processes that would normally only be possible via HTML forms or links. The advantage, of course, is that you can use all the animation and interactivity tools in Flash's arsenal to make data presentations, navigation widgets, and data-collection tools that are far richer and more interactive than is generally possible with HTML alone. You can combine these tools to create user interfaces that are more intuitive and usable than with HTML pages alone, and which look and behave exactly the same with any browser. What makes all this possible is the Flash concept of Remoting, which allows the Flash Player (which is running on the user's machine) to contact and interact easily with ColdFusion pages (which are running on your server) in real time, without needing to reload the page. Going from the Flash world of old to the new world of Flash Remoting is like going from static HTML pages to ColdFusion. All of a sudden, you can create a new kind of Flash movie that provides a rich, interactive, data-aware experience for your users. This has been possible with previous versions of Flash, but it has always meant jumping through a series of hoops. Flash Remoting makes it easy and sustainable. NOTE Our examples will make use of the Flash Remoting classes for ActionScript 1.0. This is a simpler version of the Flash Remoting classes that will work with Flash 6. ColdFusion Pages as ServicesNormally, you use ColdFusion to communicate with Web browsers. In turn, the ColdFusion pages you normally write are about generating HTML code, which the browser interprets and displays. The idea is similar with Flash Remoting, except that you use ColdFusion to communicate with the Flash Player instead of with a Web browser. And instead of generating HTML code, your ColdFusion pages just output data that should be sent back to the Flash Player. The data is made available to ActionScript, which means you can write code (usually very simple code) that causes your Flash movie to display or respond any way you see fit. One of the key concepts in the Flash Remoting framework is the notion of a service. For purposes of this discussion, a service means any directory on your ColdFusion server. Within each directory, each individual ColdFusion page that knows how to talk to Flash is referred to as a service function. There's a bit of an assumption that these service functions for each service (that is, the .cfm files in each directory) have some kind of conceptual relationship to one another, but if not, that's OK. In other words, a service is a collection of functions, and the code to power each one of those functions is written in CFML, as an ordinary ColdFusion page. You just change a few things about the code so that it knows to send information back to Flash instead of generating HTML. Hey, come to think of it, you learned about another concept recently that can be thought of as a collection of functions: the ColdFusion component. So if it's easy for Flash to consider a directory of.cfm pages as a set of service functions, maybe it's just as easy for it to consider the methods in a CFC as a set of service functions. Hmmm. More on that a bit later!) NOTE Actually, Flash Remoting is about more than just connecting Flash to ColdFusion. You can also use it to connect Flash to Macromedia's JRun server and Microsoft's.Net platform. So, the term service really refers to any directory on any server that supports Flash Remoting, regardless of what application server is powering it. For this chapter, though, the assumption is that you are using Flash Remoting to connect to ColdFusion. Your First Flash Remoting ProjectThis section will walk you through the process of creating a user interface with Flash that connects to a ColdFusion page through Flash Remoting. This first example is pretty simple, but it will help you understand how everything works together. Getting StartedAs you may already know, the Flash IDE includes a number of templates that you can use to get started with certain types of projects. There's one for pop-up ads, one for navigation menus, one for a photo slide show, and so on. Flash also includes a template for creating a movie that communicates with a server via Flash Remoting. To use the template for Flash Remoting, follow these steps:
In most respects, the Flash Document created with this template isn't much different from what you get if you just create a totally blank document. The only difference is that a layer called Actions is present in the timeline. The first frame of this layer contains some skeletal ActionScript code that you can adapt to interact with a ColdFusion page. Your timeline is probably docked near the top of the Flash workspace. Within the timeline, you will see a series of small gray and white rectangles, which represent the frames of your movie. The first frame should be marked with a lowercase A, indicating that the frame contains ActionScript code. When you click this frame, the skeletal ActionScript code added by the template appears in the Actions panel. (If the Actions panel isn't visible, choose Window > Actions from the main menu). The first line of the code reads #include "NetServices.as" (Figure 26.3). Figure 26.3. You use ActionScript code to interact with ColdFusion via Flash Remoting.Listing 26.1 shows the skeletal ActionScript code produced by the Basic Remoting template. As you will soon see, it's easy to adapt this code so it interacts with ColdFusion pages of your choosing. Listing 26.1. Template ActionScript Code for Flash Remoting#include "NetServices.as" // uncomment this line when you want to use the NetConnect debugger //#include "NetDebug.as" // -------------------------------------------------- // Handlers for user interaction events // -------------------------------------------------- // This gets called when the "aaaa" button is clicked function aaaa_Clicked () { // ... put code here // For example, you could call the "bbbb" function of "my.service" by doing: // myService.bbbb(123, "abc"); } // -------------------------------------------------- // Handlers for data coming in from server // -------------------------------------------------- // This gets called with the results of calls to the server function "bbbb". function bbbb_Result ( result ) { // ... put code here // For example, if the result is a RecordSet, you could display it in a ListBox by doing: // myListBox.setDataProvider(result); } // -------------------------------------------------- // Application initialization // -------------------------------------------------- if (inited == null) { // do this code only once inited = true; // set the default gateway URL (this is used only in authoring) NetServices.setDefaultGatewayUrl("http://localhost:8100/flashservices/gateway"); // connect to the gateway gateway_conn = NetServices.createGatewayConnection(); // get a reference to a service myService = gateway_conn.getService("my.service", this); } stop(); NOTE When you create the new document in Flash, the automatically added code erroneously uses a URL that refers to port 8100 instead of 8501, as shown in this listing. You will need to change it to 8501 before the code can work (you'll see this change in the next listing). Or, if you're not using ColdFusion in stand-alone mode, you should omit the port reference altogether. In other words, the first part of the URL should be the same as what you use to display the other examples in this book. Drawing a Simple Search InterfaceYour first Flash Remoting project will be a simple search interface for searching the list of Orange Whip Studios films (Figure 26.4). (With all this great Macromedia technology at its disposal, why does the studio keep churning out the same kinds of applications over and over again? That's Hollywood for you.) Figure 26.4. Flash Remoting makes it easy to power this simple search interface.NOTE If you don't want to follow the steps listed below, just open the completed SimpleSearchMovie.fla file. It's included with the listings for this chapter on the CD-ROM. To create the visual part of the search interface, follow these steps:
Adding ActionScript CodeNow that you've created a new Flash Document from the Flash Remoting template and have drawn the simple search interface on its Stage, the next thing to do is to edit the ActionScript code generated by the template. With this simple example, the necessary edits are quite minor. Take a look at Listing 26.2, which is the original template code (shown in Listing 26.1) with the appropriate additions and changes to power this simple example. Since this code is in the first frame of the movie, it will execute when the movie first appears. Listing 26.2. ActionScript Code for the First Frame of SimpleSearchMovie.fla#include "NetServices.as" // uncomment this line when you want to use the NetConnect debugger // #include "NetDebug.as" // -------------------------------------------------- // Application initialization // -------------------------------------------------- if (inited == null) { // do this code only once inited = true; // set the default gateway URL (this is used only in authoring) NetServices.setDefaultGatewayUrl("http://localhost:8501/flashservices/gateway") // connect to the gateway gateway_conn = NetServices.createGatewayConnection(); // get a reference to a service // In this case, the "service" is the /ows/26 directory in web server root myService = gateway_conn.getService("ows.26", this); } // -------------------------------------------------- // Handlers for user interaction events // -------------------------------------------------- // This gets called when the "SearchButton" button is clicked function SearchButton_Clicked () { // ... put code here // For example, you could call the "bbbb" function of "my.service" by doing: // myService.bbbb(123, "abc"); // In this case, we want to use the SimpleSearchProvider service function // (in other words, we want to execute SimpleSearchProvider.cfm) myService.SimpleSearchProvider({SearchString:MySearchString}); } // -------------------------------------------------- // Handlers for data coming in from server // -------------------------------------------------- // This gets called with the results of calls to the server function "bbbb". function SimpleSearchProvider_Result ( result ) { // ... put code here // For example, if result is a RecordSet, display it in a ListBox by doing: // myListBox.setDataProvider(result); // In this case, we will simply set the SearchResults variable to whatever // was returned by ColdFusion. Because the SearchResults variable is bound // to the multiline text box in the search UI, the result will display there SearchResults = result; } stop(); I don't have room here for a complete introduction to the syntax and semantics of ActionScript here. If you know JavaScript already, you'll find that this is essentially the same language. If not, you may need to consult a book on JavaScript to make sense of how the curly braces and parentheses are used, and how the function statement works. TIP There are some excellent resources in the Flash's online help that will get you up to speed with ActionScript concepts and syntax. For an introduction, choose Help > Learning Flash from the Flash's main menu, then read the "Writing Scripts with ActionScript" and the "Understanding the ActionScript Language" sections. For a reference guide, choose Help > ActionScript Dictionary. What I can do, assuming that you understand the basic form of JavaScript or ActionScript, is explain what each line of code does. Let's get started. The first line of Listing 26.2 reads: #include "NetServices.as" The purpose of this line is to include the functions created in the NetServices.as file, so they're available to the current document. The NetServices.as file is an ActionScript filethe.as extension stands for ActionScriptthat was placed on your computer when you installed the Flash Remoting Components. NetServices.as is where nearly all the other objects and functions used in Listing 26.2 are defined. If you think of the NetServices.as file as similar to a file of user-defined functions, as discussed in Chapter 22, "Building User-Defined Functions," then this #include statement is like a <cfinclude> tag that lets you use the functions in the current document. Connecting to the Flash Remoting GatewayIf we ignore comments, the next line of Listing 26.2 code is: if (inited == null) This simply tests to see if a ActionScript variable called inited currently exists. If it doesn't exist (that is, if it's null), the code inside the block that follows (enclosed by the {} braces) executes. The first line of code inside the block sets the inited variable to TRue. In other words, the code in this block only needs to execute once to initialize the rest of the movie. You can use this technique whenever you want certain code to run just once, when the movie first appears. The next line, which executes only once, reads:
The NetServices object referred to here is defined in the NetServices.as file included at the top of the listing. The NetServices object provides a number of functions (or, if you prefer, methods) related to Flash Remoting. The first one used here is the setDefaultGatewayUrl() method, which expects a URL to the Flash Remoting Gateway on whatever server you are connecting to. This simply tells the Flash Player which server it should try to talk to. Change the localhost or the :8501 parts as appropriate for how you installed ColdFusion. NOTE Assuming that you want to connect to the Remoting Gateway on your ColdFusion server, the default gateway URL should always point to flashservices/gateway as shown above. I am assuming that you are mostly interested in using Flash to access a ColdFusion server. If connecting to a different type of Remoting Gateway, such as a.NET server or a JavaBean, the default gateway URL might be slightly different. The next line reads: // connect to the gateway gateway_conn = NetServices.createGatewayConnection(); This uses the createGatewayConnection() method, also provided by the NetServices object, to establish a conceptual connection to the Flash Gateway part of ColdFusion. The method returns a gateway connection object named gateway_conn. You can read all about connection objects in the ActionScript reference in the Flash's online help; for now, just think of gateway_conn as representing your ColdFusion server. The next few lines read: // get a reference to a service // In this case, the "service" is the /ows/26 directory in web server root myService = gateway_conn.getService("ows.26", this); Any gateway connection object exposes a number of properties and methods. The most important method is getService(), which establishes a conceptual connection to a particular service on the gateway. Keep in mind that the gateway is just the ColdFusion server, and the service is the directory where the relevant ColdFusion pages are located. Because the code listings for this chapter are located in the ows/26 location in your Web server's document root, the service's name is specified as ows.26 (use dots instead of slashes to specify the path to the correct folder). The method returns a service object, which can now be used to execute the ColdFusion pages in the ows/26 directory. NOTE There is no need to provide a complete URL that includes http:// or the server's name, because that was established earlier by setDefaultGatewayUrl(). At this point, a connection to the ColdFusion server has been established. It only required three lines of code, which can be used as the first part of nearly any ActionScript code that needs to use Flash Remoting. Executing a ColdFusion Page and Passing ParametersContinuing this line-by-line tour of Listing 26.2, the next line reads: function SearchButton_Clicked() This creates a function called SearchButton_Clicked. If you recall, SearchButton_Clicked was specified as the Click Handler for the Search button in this simple search movie (see "Drawing a Simple Search Interface," earlier in this chapter). This simply means that the code in the SearchButton_Clicked function block will execute when a user clicks the Search button. There is just one line of code in SearchButton_Clicked, which reads: myService.SimpleSearchProvider({SearchString:MySearchString}); This line of code executes a ColdFusion template called SimpleSearchProvider.cfm. You will see this ColdFusion file shortly, in Listing 26.3. If you want, go ahead and take a look at it now, but for the moment all you really need to know is that it's a fairly ordinary page that takes a parameter called SearchString, runs a query to find a matching movie, and returns the title and summary of that movie. For now, it just returns a simple string, not anything fancy like a query object or an array or structure. Remember that myService is a service object that essentially represents the ows/26 folder on the ColdFusion server. Any ColdFusion page in this folder can be executed as a service function, simply by using its filename like a method, which is why SimpleSearchProvider.cfm becomes SimpleSearchProvider() here. To pass parameters to the ColdFusion page, you can provide them as name-value pairs within curly braces. This is similar conceptually to passing URL parameters in a normal HTML link, except that instead of separating the name and the value with an equals (=) sign, you use a colon. And if you need to provide multiple parameters, you separate them with a comma instead of an ampersand (&). If you don't need to send any parameters to SimpleSearchProvider.cfm, you would use: myService.SimpleSearchProvider() To provide ColdFusion with a parameter called SearchString, where the value of the parameter is the current value of the Flash variable named MySearchString, you'd use: myService.SimpleSearchProvider({SearchString:MySearchString}) If the name of the ColdFusion page were BuyItem.cfm instead of SimpleSearchProvider.cfm, and it needed parameters called ItemID and Quantity, you could use this, assuming that Flash variables called MyItemID and MyQuantity exist and contain sensible values: myService.BuyItem({ItemID:MyItemID,Quantity:MyQuantity}); You can also provide numbers or strings instead of variables in the name-value pairs. If SimpleSearchProvider.cfm accepted an optional parameter called MaxRows, you could provide the parameters like so: myService.SimpleSearchProvider({SearchString:"Tori Amos",MaxRows:100}); It's also possible to create an ActionScript object to represent the set of parameters you want to set. You then add properties to the object to represent each parameter, and supply the object to the service function call. The following fictional function call: myService.SimpleSearchProvider({SearchString:MySearchString,MaxRows:100}); would become: var myParams = new Object; myParams.SearchString = MySearchString; myParams.MaxRows = 100; myService.SimpleSearchProvider(myParams); Accessing the Returned ValueNow that you know what code to use for executing a ColdFusion page, you may be wondering how to access whatever data the ColdFusion page sends back to the Flash Player. To access the data, you need to create a special function called an event handler that executes when ColdFusion's response is received. Basically, the idea is this: Depending on what it does, it's possible that the ColdFusion code your movie is connecting to might take a few seconds to complete its work. Rather than halting the movie (which could be animated) while the ColdFusion template is working, the Flash Player lets the movie continue playing normally while the ColdFusion page is working. Then, when the ColdFusion page is completed and sends back whatever result it generates, your event handler is called and takes care of displaying the information or doing whatever else is appropriate. To create an event handler to receive data sent back from a ColdFusion page, you create a function that follows this basic form: function serviceFunctionName_Result(result) { // do something with result, which is what ColdFusion returned } Replace the serviceFunctionName part of the function name with the name of the service function that you are calling. In other words, the name of the event handler is simply the word _Result tacked onto the name of your ColdFusion page (without the .cfm extension). That's why the last function in Listing 26.2 looks like this, comments notwithstanding: function SimpleSearchProvider_Result(result) { // do something with result, which is what ColdFusion returned SearchResults = result; } Inside the event handler, the result variable will hold whatever value the ColdFusion page called SimpleSearchProvider.cfm returns. If the page returns a string, the result will hold that string. If it returns an array, that result will hold an ActionScript array, and so on. Structures and query objects can be returned as well. For now, assume that result is a string created dynamically by the ColdFusion page, based somehow on the SearchString parameter provided when the page is called. The SearchResults = result statement within the event handler just sets the value of the Flash variable named SearchResults to the string sent back by the Remoting gateway. Because the larger, multiline text box in the Search user interface from Figure 26.4 is bound to the SearchResults variable (this was one of the steps you performed while drawing the interface), it will display the value of the string as soon as a response has been received from ColdFusion and this event handler is called. NOTE If a specific event handler isn't found (that is, if there is no corresponding function whose name ends in _Result), the Flash Player will look for a function named onResult() to pass the results to. This means you can create a function with function serviceFunctionName(result) if for some reason it doesn't make sense to write separate handlers for each ColdFusion page you will be executing. You might do this if you were going to execute different pages based on some kind of option the user selects, but want the results to be treated the same way no matter which page is executed. See the Flash Remoting reference in the Flash's online help for details. Whew! That was a lot of explanation for just the short amount of code shown in Listing 26.2. But as you can see, each individual line is quite simple, and hardly anything needed to be changed from the code that the Flash template automatically included in the first frame of the movie. Now the only thing left to do is to create the SimpleSearchProvider.cfm page to which the Flash movie refers. Creating the ColdFusion CodeNow that the Flash side of the search interface example is done, it's time to create the server side part of the application with ColdFusion. Creating a ColdFusion page that interacts with Flash is much like creating the normal ColdFusion pages you already know and love. You can run queries with <cfquery> and then loop over the records with <cfloop>. You can send dynamic email with <cfmail>, interact with custom tags, user-defined functions, CFCs, or whatever you like. The only real difference is that instead of outputting content to the browser with <cfoutput>, you return the content by setting a special variable called FLASH.result. Introducing the FLASH ScopeColdFusion includes a scope called FLASH, which contains several special variables that you can use to respond to the Flash Player when it executes one of your ColdFusion pages via Flash Remoting. Table 26.1 provides an explanation of the FLASH scope.
NOTE There is also an array in the FLASH scope called FLASH.Params, which provides an alternative way to access the values of parameters. In general, it's easier to ignore the FLASH.Params array and just refer to the parameters by name in the FLASH scope directly. See the Flash Remoting documentation for details. Listing 26.3 is the SimpleSearchProvider.cfm template to which the SimpleSearchMovie.fla movie refers. Notice how ridiculously easy it is to accept the user's search string, run a query, and return a result to the Flash Player. Listing 26.3. SimpleSearchProvider.cfmSending Data Back to the Flash Player<!--- Filename: SimpleSearchProvider.cfm Author: Nate Weiss (NMW) Purpose: Provides a simple film search service for a Flash movie ---> <!--- We are expecting a SearchString parameter from Flash ---> <cfparam name="FLASH.searchString" type="string"> <!--- Query the database for any matching film records ---> <cfquery name="searchQuery" datasource="#APPLICATION.dataSource#" maxrows="1"> SELECT * FROM Films WHERE MovieTitle LIKE '%#FLASH.searchString#%' </cfquery> <!--- Set the FLASH.Result variable to the summary of the returned film ---> <!--- This will be available as the "result" variable in the ---> <!--- SimpleSearchProvider_Result handler within the Flash movie ---> <cfset FLASH.result = searchQuery.summary> That's really all you need. Because my example Flash movie is providing the user's typed keywords as a parameter called SearchString, there will be a corresponding variable called FLASH.SearchString that holds the user's search criteria. The <cfparam> tag at the top of the page makes sure this parameter is passed. Next, an ordinary <cfquery> tag queries the Films database table for matching records. The user's actual search criteria is used in the WHERE part of the query by referring to the FLASH.SearchString variable. Note that a maxrows="1" attribute makes sure the query returns only one record (at most). Of course, you would normally want to return multiple records; I am just trying to keep the example as simple as possible for now.
If you wanted a more full-featured search mechanism, allowing the user to run AND versus OR searches and the like, you could use the Verity search engine by replacing the <cfquery> tag with a <cfsearch> tag. See Chapter 35, "Full-Text Searching," for details. Note that this is almost the same as how one would respond to a similar request from a traditional HTML search form. One could even argue that it's easier to interact with Flash than with a regular Web browser, because you don't even have to learn about HTML or the slightly different ways various browsers may interpret HTML. Testing the ExampleAt this point, the simple search example should be ready to use. To test it out, you can do either of the following:
In either case, you should now be able to type a film's title or part of its title in the search blank in the Flash movie. When you click Search, the ColdFusion code in Listing 26.3 will execute. When Listing 26.3 sends the result string back to the Flash Player, the SimpleSearchProvider_Result() event handler in Listing 26.2 will execute, which in turn causes the summary of the matching film (if any) to be displayed (Figure 26.5). Figure 26.5. The Flash Remoting Gateway is contacted when the user clicks the Search button.More About Returning Data to FlashYou've now learned the basic concepts involved in sending data back to ColdFusion. This section explains with a bit more detail exactly what kinds of data you can return to Flash, and how. The good news is that you can send almost any type of data native to ColdFusion (including structures, arrays, and recordsets) back to the Flash Player as effortlessly as you can send strings. Returning Multiple Values to FlashIn Listing 26.3, only one piece of information was returned to the Flash Player: the summary of a matching film, which is a simple string. But you aren't stuck with sending back one measly piece of information at a time. In fact, you can send back as much information as you want. Just treat the FLASH.Result variable as a structure, using dot notation to create subvariables within FLASH.Result. Each of the subvariables will be available to your Flash movie as corresponding subvariables of the ActionScript result variable. For instance, instead of this line from the end of Listing 26.3: <cfset FLASH.result = searchQuery.Summary> you could use the following: <cfset FLASH.result.title = searchQuery.MovieTitle> <cfset FLASH.result.summary = searchQuery.Summary> <cfset FLASH.result.currentDate = dateFormat(now())> Then, in the ActionScript code in the Flash movie, you would change this line: SearchResults = result; to this: SearchResults = result.Summary; You could also use the result.Title and result.CurrentDate variables however you wanted. In fact, result is now an ActionScript object, as I'll discuss next. Returning Structures to FlashIf you send a CFML structure back to Flash in the FLASH.Result variable, the information will be made available to your movie as a native ActionScript Object variable. It's not possible to explain everything about how to work with objects, but here is a quick example. Say you created a structure with two values called FirstName and LastName your ColdFusion page, like so: <cfset s = structNew()> <cfset s.firstName = "Nate"> <cfset s.lastName = "Weiss"> <cfset FLASH.result = s> In your Flash movie you could then refer to the first and last names as result.FirstName and result.LastName. You can find out how many values (or properties) the result object included by accessing result.length. You can loop through the values in result using a for..in loop, like so: for (Prop in result) { // Within this loop, refer to Prop for the current property name // refer to result[Prop] for the value of the current property } Returning Arrays to FlashIf you return a CFML array to Flash in the FLASH.result variable, a corresponding ActionScript array will be created. You can use the array just like any other ActionScript array. Keep in mind that ActionScript arrays (like JavaScript arrays) are zero-based, which means that the array positions start at 0 rather than at 1. Say you have this in your ColdFusion code: <cfset ar = arrayNew(1)> <cfset ar[1] = 3> <cfset ar[2] = 1> <cfset ar[3] = 4> <cfset FLASH.tesult = ar> The Flash movie could access the first element in the array as result[0], and the value of result[0] would be 3. The number of elements in the array is available as result.length, and you can add, remove, or sort elements in the array using result.push(), result.pop(), and result.sort(), respectively. See the ActionScript dictionary in your Flash documentation for details on arrays. Returning Queries to FlashYou can also return query objects to Flash using the FLASH.Result variable; the query becomes available in ActionScript as a Flash Remoting RecordSet object. This is discussed shortly, in the "Working with Recordsets in Flash" section. Rich Text in Flash Text BoxesIt's worth taking a moment to point out that the Flash Player allows you to use very simple HTML tags to format text displayed in a text box. Flash only supports basic character-formatting tags: <a>, <b>, <font>, <i>, <p>, and <u>. While this doesn't give you the ability to lay out pages (you're meant to use the Flash environment for design and layout work), you do have the ability to manipulate text that you send back from ColdFusion by making certain parts of it bold, italic, or the like. To experiment with this, go back to the simple search movie in Flash and use the Property panel to enable the Render Text as HTML option for the multiline text box that shows the search results. Then go back to Listing 26.3 to and remove the maxrows attribute so the query can return multiple records. Finally, change this line: <cfset FLASH.result = searchQuery.summary> to this: <cfsavecontent variable="Flash.result"> <cfoutput query="searchQuery"> <p><b>#MovieTitle#</b><br>#Summary#<br></p> </cfoutput> </cfsavecontent> Now test the movie again, typing in something like the as the search criterion so that you see multiple records (Figure 26.6). As you can see, the <br> and <p> tags are interpreted as ends of lines, and the <b> tags are interpreted as bold, similar to how a browser would interpret these tags. Figure 26.6. The Flash Player allows you to mark up text with simple HTML tags.NOTE In Figure 26.6, I also added a scroll bar to the text area to make it possible for a user to look through the records. You do this by dragging the ScrollBar from the Flash UI Components part of the Components panel. Refer to your Flash documentation for details about scroll bars. NOTE The SimpleSearchProvider2.cfm template on the CD-ROM is a revised version of Listing 26.3 that includes the changes mentioned here. |