Rambling Developer

Recent Posts


Archives


Rambling Developer

CookBooks

ComboBox ItemRenderer Cook Book

One of the first things that is created or envisioned before the need for a DataGrid and ComboBox itemRender is a collecton of data. Some example data that will be used for this cook book is shown below:

<s:ArrayCollection id="usStatesCollection" source="{[Alabama,Georgia,Massachusetts,New York,Rhode Island]}"/>
<s:ArrayCollection id="userCollection">
    <fx:Object userName="mikejuly24" usState="Massachusetts"/>
    <fx:Object userName="leonthepro" usState="Alabama"/>
    <fx:Object userName="mathilda" usState="New York"/>
</s:ArrayCollection>

Notice above that two ArrayCollection have been created. One is a collection of my favorite US States and the other is a collection of Objects that map a userName to a usState.

Now, we will want to create a Datagrid with two columns that can display this information. Our first column will display a userName as a Label and the second column will display the usState in a ComboBox. The usState column renderer/editor will be a ComboBox so that the end user can ultimately change the US State that is mapped to each userName. Below we create our DataGrid in MXML:

<mx:DataGrid id="myDataGrid" dataProvider="{userCollection}">
  <mx:columns>
    <mx:DataGridColumn headerText="User Name" dataField="userName" editable="false" width="200"/>
    <mx:DataGridColumn headerText="Home State" rendererIsEditor="true"editable="true" dataField="usState" width="200">
      <mx:itemRenderer>
        <fx:Component>
          <mx:ComboBox dataProvider="{outerDocument.usStatesCollection}" change="{outerDocument.comboBoxChanged(event)}"/>
        </fx:Component>
      </mx:itemRenderer>
    </mx:DataGridColumn>
  </mx:columns>
</mx:DataGrid>
<s:Label id="updateLabel" x="425" y="10" text="No Changes Have Been Made Yet."/>

Notice several important points in the above code:

  1. The dataGrid is bound to the userCollection so that all changes to the userCollection will be reflected in the DataGrid.
  2. We have defined a column for userName which displays the userName attribute with dataField=”userName” and sets the column header text to “User Name”.
  3. We have created a column which uses “usState” as its dataField, sets up the renderer to be the editor, and allows the renderer to be editable.
  4. We define an itemRenderer Component for the “usState” column which is comprised of a ComboBox which uses the usStateCollection ArrayCollection as the dataProvider and calls a comboBoxChanged() method when the associated data changes.
  5. Lastly, we create a label with id of updateLabel which we will use to display changes that are made to the ComboBoxes.

Having the ComboBox renderer call a method upon change is important since this will allow us to detect and handle changes which are made to each individual ComboBox renderer.  Here we define the comboBoxChanged() method:


public function comboBoxChanged(e:Event):void{
  //Create a string denoting the newly selected state along with the related username
  var updateString:String = "Selected state is: " + ComboBox(e.currentTarget).selectedItem +" for user: " + ComboBox(e.currentTarget).data.userName;
  //Print out the newly selected state along with the related username
  trace(updateString);
  //Display the newly selected state along with the related username in the UI label
  updateLabel.text = updateString;
}

In the above method, we are first creating a string which will represent the change made by using the information passed into the method by the Change Event. The passed in event contains the newly selected State in the selectedItem attribute and also contains the data for the row (ie. the Object in the usersCollection). Once the string is created using the information retireved from the event, we use trace() to output the string and set the text of the updateLabel to the string.

This concludes all of the logic required to retrieve the data changes which are being made to the comboboxes, but we may also want to programmatically change the values displayed by the ComboBoxes. To achieve that goal, we will need to add an input source to allow programatic changes to the Boxes, like so:

<s:Button label="Make Everyone From Georgia" click="setAllUsersToGeorgia()" x="425" y="50"/>

As the label of the button aptly describes, the button will be used to switch all of the users in the DataGrid to be from Georgia. To do that, we register a method called setAllUsersTOGeorgia() to the click event which is implemented below:


public function setAllUsersToGeorgia():void{
  //Loop through our user collection and set every users state to Georgia
  for each (var user:Object in userCollection) {
    user.usState = "Georgia";
  }
  //Refresh the grids dataprovider so that the renderers update with the new data
  myDataGrid.dataProvider.refresh();
}

We can see in this method, that we are looping through the userCollection and changing all of the Users states to be “Georgia”.  We then ensure that the DataGrid updates all of its renderers correctly by calling the refesh() method on the dataProvider.  

Thats it!  That is everything we need to do in order to get and set values from a ComboBox in a DataGrid!

To view a demo of this code go to: http://ramblingdeveloper.com/storage/flex-examples/datagridcomboboxexample/bin-debug/DataGridComboBoxExample.html

To get the source to the demo: http://ramblingdeveloper.com/storage/flex-examples/datagridcomboboxexample/DataGridComboBoxExample.mxml

adminadmin