Accessibility

Table of Contents

Understanding Flex itemRenderers – Part 4: States and transitions

States

The Flex <mx:State> is a very good way to change the appearance of an itemRenderer. States are easy to use, and when combined with transitions, give the user feedback and pleasent experience.

In this example, you'll create a new MXML itemRenderer (and remember, you can do this completely in ActionScript if you prefer) for the list. All this itemRenderer shows is the image, title, author, price, and a Button to purchase the book.

<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:mx="/2006/mxml">
 
      <mx:Image id="bookImage" source="{data.image}" />
      <mx:VBox height="115" width="100%" verticalAlign="top" verticalGap="0" paddingRight="10">
            <mx:Text text="{data.title}" fontWeight="bold" width="100%"/>
            <mx:Label text="{data.author}" />
            <mx:HBox id="priceBox" width="100%">
                  <mx:Label text="{data.price}" width="100%"/>
                  <mx:Button label="Buy" />
            </mx:HBox>
      </mx:VBox>
</mx:HBox>
          

What you want, however, is, if the book is not in stock (the data has <instock> nodes that are either yes or no) the price and "Buy" Button will be invisible. I've made things a bit convenient for coding here by giving the HBox parent of the price and Button an id property. This allows me to change the visibility of both of those items by changing the visibility of the HBox, priceBox.

You can do this by overridding the set data function, which you'll do, but instead of directly changing the visibility of priceBox, you'll use this state defintion:

      <mx:states>
            <mx:State name="NoStockState">
                  <mx:SetProperty target="{priceBox}" name="visible" value="false"/>
            </mx:State>
      </mx:states>

Place this just below the root <mx:HBox> tag.

This example is a bit far-fetched in that it is overly complicated to do a simple task, but it shows how to use states. There are two states:

  • The base state: this is the normal state of a component. Components that do not use states simply have this base state. In this example, the base state has the priceBox visible property as true (the default). This is the case when instock is yes.
  • The NoStockState: this is the state when the value of instock is no. When this state is active, the SetProperty instructions are carried out. The target property determines which member of the class is in question, the name property is the name of the property to change on the target, and value is the new value for the property.

The set data function determines which state to use by looking at the value of instock:

            override public function set data( value:Object ) : void
            {
                  super.data = value;
                  
                  if( data )
                  {
                        if( data.instock == "yes" ) 
                              currentState = "";
                        else
                              currentState = "NoStockState";
                  }
            }

The currentState is a property of all UIComponent controls. It determines which state is the active one. When switching between states, the Flex framework begins with the base state and then applies the rules for the given state.

Note: Remember that itemRenderers are recycled, so you must always restore values; never leave an if without an else in an itemRenderer.

If you are feeling adventurous, you can do away with the set data override in this example. Instead, set currentState directly in the root tag by using a data binding expression:

<mx:HBox xmlns:mx="/2006/mxml" width="400" currentState="{data.instock == 'yes' ? '' : 'NoStockState'}" >

The currentState's value is set by examining data.instock right inline with the root tag–a nice trick, but it might be harder to maintain.