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

Flex 3 with Java

June 2009


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

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"

<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"

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

<!-- 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%"/>


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


public function selectCounties():void{
countiesList.dataProvider =

public function selectCities():void{
citiesList.dataProvider =



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

The Data

The data for our selector is an XML Object:

<!-- Data -->
<mx:XML xmlns="" id="locations">
<state name="Florida">
<county name="Broward">
<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"/>
<county name="Palm Beach">
<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"/>
<state name="Georgia">
<county name="Macon">
<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"/>

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 =

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 =

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=" +

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.
citiesList.dataProvider=null; // clear the cities list


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 :

Books to Consider

comments powered by Disqus

An Introduction to 3D Printing

Explore the future of manufacturing and design  - read our guide to 3d printing for free