Showing posts with label example. Show all posts
Showing posts with label example. Show all posts

Flex Template Component

english mobile

This week on InsideRIA, I blogged about Flex Template components. My mandate for that blog is to talk more about ideas than showing code, but I had a feeling that someone would ask to see code on this one, so I put together an example of code that is similar to the component I show a screen shot of in that post for the curious.

The example linked to below has View Source enabled:



Example of casting contents of swfLoader to an interface

english mobile

Last weekend, someone asked for ane example of being able to load a swf generated from a Flex Application that implements an interface and being able to load a Flash swf that implements the same interface. Once the swf's are loaded, the poster wanted to be able to cast them to the interface and then use the interface to call methods on the loaded swf.

So, I've posted an example of casting swfLoader content to an interface.



I chose to go pretty generic with this example, so the interface just enables you to make the component "blush" and stop blushing. However, this could have a lot of uses, for instance, you could write an interface that allows you to stop all animation within a swf.

Moving from Authorware to Flex

english mobile

I started out as an Authorware developer, and one reason I am now doing Flex is that Adobe announced the End of Development of Authorware just over a year ago. I saw that Flex offered a lot of the advantages of Authorware--it does a great job of integrating various media into a cohesive whole and you can make an application that runs from the web or the desktop from approximately the same code.

Adobe's decision left many people scrambling to figure out where they would go, so Randy Nielsen from the Flex documentation team worked with a few Authorware developers to get a stub page up when Flex 3 was released so that Authorware developers could document what their experiences have been to help ease the process of making the migration for those who felt that Flex was the best Authorware replacement for them.

At long last, I managed to make some time to add my 2¢ worth to the document. So I'm happy to announce that the Moving to Flex from Authorware page at the Flex documentation wiki has been updated. There is one section that I wrote that for some reason isn't included, and I feel it may be useful to some people, so I'm posting it here:

Using Flex files inside Authorware
In large existing projects, it might not be feasible to migrate the entire project to Flex over night. One strategy is to create new functionality in Flex and embed that in Authorware. When Authorware finally is abandoned, the Flex functionality will still be useful.

Flex Side
Flex and Flash have an object, ExternalInterface, that allows them to communicate with whatever application contains the swf file. Normally, this is used in a swf embedded in the browser to communicate with javascript that is written in the HTML page.
At the moment that the swf loads, the child components of the swf don't yet exist, so any attempt to set any properties on them will cause an error, which will probably stop your Flex application from proceeding any further. So you should wait until everything is created before initiating communication with the container. This means that you should run a function on creationComplete that will use ExternalInterface to call out to the container and tell it that it is ready to receive data. This function should also set up the callback functions, which are the functions inside your Flex application that are accessible to the container.
The container should then respond by calling a function and providing data your Flex application needs as an argument. This can be a user name, lesson status, or XML that represents a menu. The function should perform whatever parsing is needed on the data and set object properties based on the data.
When the user interacts with the swf, it should again use ExternalInterface to tell the container what happened.
Once you have created your Flex file, you should make sure to export a release build by going to Project>Export Release Build. This file will be smaller and run more efficiently than the debug build that is built by default.

Authorware Side
The Authorware file will have a Shockwave Flash Object ActiveX control icon in it. The development machine should have Flash Player version (Randy, what's the minimum version of the Flash Player for Flex 3?) on it, and you'll need to make sure that the users have at least that version installed.
Next, you'll need a calculation icon that sets up the path to your swf file so that Authorware can find it. This will start the loading process, which will culminate in the creationComplete event.
Once the creationComplete event fires, the swf will generate an event that can be seen in Authorware by using ExternalInterface. To catch this event, you'll need to use an Event Response on an Interaction icon. The response should be set up to respond to the FlashCall event. This seems to work best as a perpetual response on an Interaction that is below the ActiveX Sprite on the flow line, but above the calculation that sets the path to the swf.
The information contained in the #request property of the EventLastMatched variable will be an XML formatted string, so you'll need to use an XML parser object to access its contents. The same event response will trigger every time the Flex Application calls ExternalInterface.call, so you'll need to look at the name of the root element to see what "function" the Flex file thinks it is calling and branch based on that.
In the branch that you set up for the initial call where the swf tells you it is started, you should respond by issuing a CallSprite command to the Flash ActiveX Sprite icon that calls a function in the swf with the data you want to see in Flex. Other branches should contain logic to respond to different calls the swf sends with ExternalInterface.

Download the example files.

GroupingCollection example featuring GroupingFunction

english mobile

Several months ago, I built a dashboard example for a client that featured a calendar with a month view like you'd see in a paper calendar on one side and a week view on the other side. I wound up writing some fairly complex classes to handle the different breakdowns in how the data displayed. I also wrote a custom renderer for the calendar page and a different one for the week view.

And then I had to do some work with the AdvancedDataGrid and fell in love with the way this component "thinks" about data, with its HierarchicalData, HierarchicalCollectionView, and GroupingCollection. And, of course, I adore its styleFunction, as you might have guessed from my earlier TileList_withStyle and DataGrid_withStyle classes.

A few weeks ago, someone posted an example that showed a way to use GroupingCollections with controls that were not AdvancedDataGrid or Tree components. Let me tell you, that got my little cogs twirling. If only (thought I) you could use a function to decide how the items in a GroupingCollection grouped. Then you could use it to group dates into years, months, weeks, whatever floated your boat. So I went digging into the docs, and found that the GroupingField actually does have such a property.

And so the GroupingFunction example was born. This example illustrates how you can create a single array of objects that contain the dates to use for a Calendar application, then group and filter the data in different ways by using that array as the source for multiple ArrayCollections and GroupingCollections. These allow you to display that data in several different ways without a lot of manual parsing.





It also illustrates the following concepts:



  • Using a single itemRenderer with the TileList_withStyle component to present different appearances based on the styleFunction you use.

  • Using a Repeater to populate an Accordion control based on a data source

  • Using a single child component that gets reused between the children of
    the Accordion


I'd also like to point out that I'd have never been able to create this example if I weren't still looking for work. I'm sure you're probably loving being the recipient of all these free examples, but please return the favor by passing my name on to anyone you know who is hiring :-).



Updated October 21, 2008:

I changed the itemRenderer to show how you can set the blendMode on text to apply effects to it without embedding the font. I only set the blendMode on the lower label , so that the difference would be apparent.

Extended DataGrid with StyleFunction Example Posted

english mobile

A few weeks ago, I posted an example of an extended TileList that adds the styleFunction I've become so fond of with AdvancedDataGrid. I decided I'd look and see if I could do the same with DataGrid, and I found that, while it was challenging, I was able to do it. So I've posted my new extended DataGrid_withStyle and StyleableRenderer classes for you to use and enjoy. As always, View Source is enabled.

TileList with styleFunction

english mobile

Recently I had a requirement to have buttons displayed in a grid with different color backgrounds based on the underlying data. Thus, the TileList_withStyle was born. The TileList_withStyle is simply a TileList extended to have a styleFunction. Note that I mostly just copied and modified the styleFunction code from the AdvancedDataGrid control. You can probably use the same technique to add a style function to pretty much any List-based control.

At the same time, I also needed to set the icon on the button based on the iconFunction that TileList already had. Unfortunately, the Button class does not have hte inherent capability to use the icon as it is passed in through the iconFunction. Thus, the IconFunctionableButton was born. I've posted an example file demo-ing these two classes. Right-click and select View Source to get the source code.

Comparing XML nodes of the same name with E4X

english mobile

I recently found a situation that the Flex E4X documentation didn't cover, and I couldn't find an example for ActionScript 3 or JavaScript that covered it. Essentially, I had XML in the data property of an itemRenderer that looked something like this:

<question id="1>
<selected>
1
</selected>
<selected>
5
</selected>

</question>

Essentially, my itemRenderer has five buttons (A-E), any or all of which can be selected. If the user clicks one of the buttons and it is already selected, it should be deselected. Or, in other words, if there is already an element in the data XML's "selected" collection with the same value as what the user clicked (assuming A=1 and E=5), then that element should be deleted.

I had a challenge, though, in that I didn't want to use a for loop. I was using XML, and E4X should be able to handle this easily. The problem I had was that every E4X example I found that referenced the contents of the nodes of an XML node presumed that there would only be one of each node of the same node. So if my XML structure had been

<question id="1>
<selected>
1
</selected>

</question>

then life would have been easy. I could have used data.(selected==userSelection) and away I'd go. But the problem when you have multiple nodes named "selected" is that data.selected returns an XMLList that contains all of the nodes. Hence, it cannot be equal to any single number, even though when there is only one node it works fine.

So, after much research, I came up with something like this:

myXMLNode:XML="<selected>"+userSelection+"</selected>";
if (data.selected.contains(myXMLNode){
//loop through and delete any nodes with that value
} else {
//add a node of that value
}

I wasn't really happy with this, and I posted to the Flex Coders mailing list. Tracy Spratt suggested that I use the text() method of the XML object, so I wound up with something like this in my final logic:

if (data.selected.(text()==userSelection).length()==0){
//add the selected node to the data object
data.prependChild(myXMLNode);
} else {
//remove the selected node from the data object
for (i=data.selected.length()-1; i>=0; i--){
if (data.selected[i] == userSelection){
delete data.selected[i];
}

I hope this will help someone else solve this problem without having to waste as much time as I spent on this!