Flex Multi-List Selector using List Control, DataGrid, and the Accordion

Exclusive offer: get 50% off this eBook here
Flex 3 with Java

Flex 3 with Java — Save 50%

Develop rich internet applications quickly and easily using Adobe Flex 3, ActionScript 3.0 and integrate with a Java backend using BlazeDS 3.2

$23.99    $12.00
by Keith Lee | October 2009 | Open Source

The idea of a Multi-List Selector is not a new one. Apple implements something very similar to it in its Mac OS Operating System. Simply put, its a method of selecting an item by filtered hierarchical categories on a list by list basis. This structure is often seen while traversing files in directories, but can be applied with other data sources as well. This article by Keith Lee will demonstrate how to build a Multi-List Selector.

Instead of files and directories, I'm going to use States, Counties and Cities. Essentially this application will be used to give the user an easy way to select a city.

Flex offers many components that can help us build this application. The controls I immediately consider for the job are the List Control, DataGrid, and the Accordion (in combination with the List). The List is the obvious control to start with because it represents the data in the right way - a list of states, counties, and cities. The reason I also considered the DataGrid and the Accordion (with the List) is because the they both have a header. I want an easy way to label the three columns/list 'States','Counties' and 'Cities'. With that said, I selected the Accordion with the List option. Using this option also allows for future expansion of the tool. For instance, one could adapt the tool to add country, then state, county, and city. The Accordion naturally has this grouping capability.

With that said, our first code block contains our basic UI. The structure is pretty simple. The layout of the application is vertical. I've added an HBox which contains the main components of the application.

The basic structure of each list is a List Control inside a Canvas Container which is inside of an Accordian Control. The Canvas is there because Accordians must have a container as a child and a List is not a part of the container package. We repeat this 3 times, one for each column and give the appropriate name.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
horizontalGap="0"
layout="vertical">

<mx:HBox width="100%" height="100%">

<!-- States -->
<mx:Accordion id="statesAccoridon" width="100%" height="100%">
<mx:Canvas width="100%" height="100%" label="States">
<mx:List id="statesList"
width="100%"
height="100%"
dataProvider="{locations.state.@name}"
click="{selectCounties()}"/>
</mx:Canvas>
</mx:Accordion>

<!-- Counties -->
<mx:Accordion id="countiesAccoridon" width="100%" height="100%">
<mx:Canvas width="100%" height="100%" label="Counties">
<mx:List id="countiesList"
width="100%"
height="100%"
click="selectCities()"/>
</mx:Canvas>
</mx:Accordion>

<!-- Cities -->
<mx:Accordion id="citiesAccoridon" width="100%" height="100%">
<mx:Canvas width="100%" height="100%" label="Cities">
<mx:List id="citiesList" width="100%" height="100%"/>
</mx:Canvas>
</mx:Accordion>

</mx:HBox>

<!-- Selected City -->
<mx:Label text="{citiesList.selectedItem}"/>

<mx:Script>
<![CDATA[

public function selectCounties():void{
countiesList.dataProvider =
locations.state.(@name==statesList.selectedItem).counties.county.@name
}

public function selectCities():void{
citiesList.dataProvider =
locations.state.(@name==statesList.selectedItem).counties.county.
(@name==countiesList.selectedItem).cities.city.@name;
}

]]>
</mx:Script>

</mx:Application>

I've set the width and height to all containers to 100%. This will make it easy to later embed this application into a web page or other Flex application as a module. Also notice how the dataProvider attribute is only set for the statesList. This is because the countiesList and the citiesList are not populated until a state is selected. These dataProviders are set using ActionScript and are triggered by the click event listeners for both objects.

Here is what the start of our selector looks like:

Flex Multi-List Selector using List Control, DataGrid, and the Accordion

Flex 3 with Java Develop rich internet applications quickly and easily using Adobe Flex 3, ActionScript 3.0 and integrate with a Java backend using BlazeDS 3.2
Published: June 2009
eBook Price: $23.99
Book Price: $39.99
See more
Select your format and quantity:

The Data

The data for our selector is an XML Object:

<!-- Data -->
<mx:XML xmlns="" id="locations">
<states>
<state name="Florida">
<counties>
<county name="Broward">
<cities>
<city name="Fort Lauderdale"/>
<city name="Coconut Creek"/>
<city name="Plantation"/>
<city name="Pompano Beach"/>
<city name="Cooper City"/>
<city name="Hollywood"/>
<city name="Davie"/>
<city name="Weston"/>
</cities>
</county>
<county name="Palm Beach">
<cities>
<city name="Boynton Beach"/>
<city name="Lake Worth"/>
<city name="West Palm Beach"/>
<city name="Greenacres"/>
<city name="Delray Beach"/>
<city name="Boca Raton"/>
<city name="Palm Springs"/>
<city name="Lake Clark Shores"/>
</cities>
</county>
</counties>
</state>
<state name="Georgia">
<counties>
<county name="Macon">
<cities>
<city name="Barrons Lane"/>
<city name="Bartlett"/>
<city name="Clearview"/>
<city name="Cutoff"/>
<city name="Fields"/>
<city name="Five Points"/>
<city name="Hicks"/>
<city name="Spalding"/>
<city name="Winchester"/>
<city name="Ideal"/>
</cities>
</county>
</counties>
</state>
</states>
</mx:XML>

As you can see above, I did not enter all 50 states. For this example it is only required to get a few states working and populate the remaining ones at a later time. Now, lets look at the structure of the XML object.

The root node is called 'states'. Within each 'states' you will see a 'state' node which contains all the information about a particular state. Within each 'state' node there is a 'counties' node and within each 'counties' node there is a 'county' node. As you can guess, there is a 'cities' node inside of each 'county' node. This a hierarchical breakdown of the data which will make getting the states, cities or counties from an external source easy.

Connecting the controls to the dataProviders

As I mentioned earlier the statesList has a dataProvider from the moment the application creation is completed. The countiesList and citiesList do not have dataProviders until a state is selected. This makes less confusion for end users who may see all three columns populated without having selected anything.

To populate the counties list, we use the click event listener. Our click event is tied to the following code:

public function selectCounties():void{
countiesList.dataProvider =
locations.state.(@name==statesList.selectedItem).counties.county.@name
}

If you haven't heard of E4X, now is a perfect time to introduce it to you. E4X is a specification that has been implemented in Action Script. It allows easy access and manipulation of XML nodes and attributes. It is exactly what we are using here in order to find the counties which belong to a selected state. Lets break down the dataProvider assignment statement.

  1. First we have the Left Hand Side (LHS) of countiesList.dataProvider. This is the dataProvider property of the countiesList. We want to assign it to the counties of the currently selected state.
  2. Next we have locations.state.(@name==statesList.selectedItem). This E4X expression simply says: in our locations XML object, find the state node which has a name attribute of statesList.selectedItem. statesList.selectedItem is the name of the currently selected State (from the statesList List). At this point we have access to all the information we need about the state. This is a lot of information which includes all the counties and all the cities. What we really want is just a list of counties. To get the counties we need to use a bit more E4X.
  3. Finally, get the counties from the state we are viewing. We simple add .counties.county.@name to our E4X. This says, for each state that we find, extract the county names. In more detail, find the counties node of the state, and for every county found extract the value for the name attribute. Notice the @ symbol of front of 'name'. I don't want to dive too much into E4X - see the links at the end of this article for more information.

To get the citiesList populated, we follow the same principal. We find the selected county and get a list of the all the cities in the county. Here is the selectCities method which is called once a county is selected:

public function selectCities():void{
citiesList.dataProvider =
locations.state.(@name==statesList.selectedItem).counties.county.
(@name==countiesList.selectedItem).cities.city.@name;
}

Now we have a basic working multi-list selector. Here is what it looks like:

Flex Multi-List Selector using List Control, DataGrid, and the Accordion

This is a good example of how to leverage Flex to create powerful apps. A real world app may do some things slightly differently. For instance, we've only loaded two states and a subset of counties and cities for those states. Chances are, the end user would not need all the states data to be loaded at the start of the program. In this instance, we would use something like the HTTP SERVICE tag to retrieve the data from a web server. This keeps the Flex app as light as possible. Getting the data from a web server is a bit out of scope for this article, but I've listed some links below that can get you on your way.

Selecting a City, and Cleaning Up the Navigation

Now that we have the selection of the state, county and city working, we want something to happen once the user does select a city. What we will do is open a new web page once a city is double clicked. For now, the page will be a yahoo.com search page for the city selected. For this task we will use the NavigateToUrl method.

We will need to import the classes needed for navigation.

import flash.net.navigateToURL;

We will also have to enable the double click on the citiesList and add an event listener for double clicking. Here is what the citiesList looks like:

<mx:List id="citiesList" width="100%" height="100%" 
doubleClickEnabled="true" doubleClick="showCityPage()"/>

Our new function showCityPage looks like this:

public function showCityPage():void{
navigateToURL(new URLRequest("http://search.yahoo.com/search?p=" +
citiesList.selectedItem));
}

Cleaning up the Navigation

This is where the real magic of navigating to a new URL happens. The navigateToUrl method takes as a parameter a URLRequest object. This object essentially is the link we wish to visit. We create this object on the same line that we call navigateToURL for convenience. As you can see, we are sending the user to "http://search.yahoo.com/search?p=" concatenated with the city which was selected. This will direct us to the yahoo search result for the city we double clicked.

That pretty much takes care of our setting an action once a city is selected. No we can turn our attention to a minor UI problem that happens when a user selects a different state. If a user is viewing a list of cities from a particular state and they change the state, the list of cities is not updated. It should return to a state of being blank since no cities are selected. To combat this problem we will set the dataProvider to null for citiesList whenever a state is selected. Setting it to null effectively removes all data from the control. We can add this single line of code inside the selectCounties method. In his way, it automatically removes the dataProvider any time a state is selected. Here is the new selectCounties function:

public function selectCounties():void{
countiesList.dataProvider = locations.state.
(@name==statesList.selectedItem).counties.county.@name
citiesList.dataProvider=null; // clear the cities list
}

Summary

Well, that's it. We've created a simple to use Flex app that can be expanded for many uses. This type of app is 115 lines long including the data. Not bad. Here are some links that relate to this article. Enjoy!

Related links:

navigateToURL: http://livedocs.adobe.com/flex/3/langref/flash/net/package.html#navigateToURL%28%29

URLRequest: http://livedocs.adobe.com/flex/3/langref/flash/net/URLRequest.html

HTTPService: http://livedocs.adobe.com/flex/3/html/help.html?content=data_access_2.html

Accordion: http://livedocs.adobe.com/flex/3/html/help.html?content=navigators_5.html

Canvas: http://livedocs.adobe.com/flex/3/html/help.html?content=layouts_03.html

List: http://livedocs.adobe.com/flex/3/html/help.html?content=dpcontrols_2.html


If you have read this article you may be interested to view :


Flex 3 with Java Develop rich internet applications quickly and easily using Adobe Flex 3, ActionScript 3.0 and integrate with a Java backend using BlazeDS 3.2
Published: June 2009
eBook Price: $23.99
Book Price: $39.99
See more
Select your format and quantity:

About the Author :


Keith Lee has been a software developer since graduating college in 1999 with an MS in Systems Administration and Computer Networking. He has developed in many languages, but more recently in Flex/ActionScript and PHP. Presently he is a contributing author for the Developer Shed Network of sites and consults on private projects. Keith currently serves as Senior Software Developer of Special Projects for Ziff Davis Enterprise.


Books From Packt


Ext JS 3.0 Cookbook
Ext JS 3.0 Cookbook

Flash with Drupal
Flash with Drupal

ASP.NET 3.5 CMS Development
ASP.NET 3.5 CMS Development

Joomla! 1.5 Development Cookbook
Joomla! 1.5 Development Cookbook

Unity Game Development Essentials
Unity Game Development Essentials

Apache Maven 2 Effective Implementation
Apache Maven 2 Effective Implementation

Drools JBoss Rules 5.0 Developer's Guide
Drools JBoss Rules 5.0 Developer's Guide

Alfresco 3 Enterprise Content Management Implementation
Alfresco 3 Enterprise Content Management Implementation


Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software