itemEditors – Part 3


The previous article in this series discussed item editing events. Using events can make your application respond to what the user enters and help the user make fewer mistakes.

This article is about using itemRenderers as itemEditors – one class to do both display data and edit the data. I tend to think of it more as an itemEditor used as an itemRenderer. But that’s just me.

Download source for these examples.

Further, I have to be honest and say I am not a big fan of the renderer-as-editor; I think renderers should present data and editors should edit it. There are a few occasions when I think it is a good idea to use a single class for both, but those times are very few in my opinion.


Here is an example of over-using the itemRendererAsEditor. The DataGrid on the left is a nice, clean DataGrid. All of the cells are editable and when you click or tab into a cell its editor appears. The DataGrid on the right uses itemEditors to render the cells and edit them. All you see are the editors: TextInput controls for some columns, a ComboBox for another, and a NumericStepper for the last. Lots going on, very busy to look at.

itemEditors only itemRenderers as itemEditors

Here is an example of using the CheckBox as both an itemRenderer and an itemEditor. I think the CheckBox works really well for this. It is clean, simple control and you can readily see whether a value is true or false. Plus you can just click it to change it. Straightforward implementation, good user experience.

Here is another example of using an itemEditor as a renderer. This List control represents a shopping cart. In it are all of the things you have added to your cart while shopping online at your favorite grocery store.

As you can see, the quantity of each item in the cart is represented by a NumericStepper. All the user has to do is change the quantity and the cart is updated. A delete button would also be a good idea here, too.

Shopping Cart

This complex editor/renderer class works as follows:

<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:mx="" verticalAlign="middle" paddingRight="4" paddingLeft="4" >

public function get quantity() : Number
return itemQuantity.value;

<mx:CurrencyFormatter id="cfmt" precision="2" />

<mx:Label text="{}" fontWeight="bold" fontSize="12"/>
<mx:Spacer width="100%"/>
<mx:NumericStepper id="itemQuantity" value="{data.quantity}"
<mx:Label text="{cfmt.format(data.price*itemQuantity.value)}" width="66"/>


As with every itemEditor, this one has a property used as the editorDataField. In this case it is the quantity property getter function. The function retrieves the value setting of the NumericStepper (with id itemQuantity).

As an itemRenderer, this component must also display the current quantity (as well as the product name, price, and sub-total). These values are displayed through data binding. The sub-total is actually an ActionScript expression, multiplying the price by the value of the NumericStepper. As the NumericStepper is changed so does the sub-total.

Now you are probably wondering how to get the grand total below the shopping cart to update as the NumericSteppers are changed. Simply changing the sub-total and the quantity field of the itemRenderer/Editor will not update the grand total. Remember that the editor does not commit the new value into the data provider until after the edit completes. In other words, if you increase the value of the NumericStepper for the Snow Peas row, the grand total will not update until focus leaves the Snow Peas row. This is so you can validate the information as shown in previous articles.

For a shopping cart like this, you want the grand total to update as the user changes the NumericSteppers. So you have to force the situation a little.

The first thing you do is have the itemRenderer class implment the IDropInListItemRenderer interface. This gives you access to the listData which contains a reference to the list itself and, through that, to the dataProvider.

The code demonstrating this is available in the download. Look for the ShoppingCartRendererExtra.mxml file.

Once you have the listData you can have the change event on the NumericStepper force an update on the dataProvider:

private function forceUpdate() : void
// Access the collection - listData.owner is the List and from there you have its dataProvider.
var ac:ArrayCollection = (listData.owner as List).dataProvider as ArrayCollection;

// update the quantity field from the numeric stepper. This is what the List will automatically
// do when editing completes, but since you want to see the grand total change as the NumericStepper
// changes, you have to force things a bit.
data.quantity = itemQuantity.value;

// finally, tell the collection the data changed. this will cause the collection to
// dispatch its own change event which is then picked up by the main application.

When the NumericStepper’s change event triggers this event handler, the ArrayCollection has the item updated immediately, rather than waiting for the List to complete editing the cell. If the main application is listening for a COLLECTION_CHANGE event on the collection, the grand total can be calculated:

    <mx:ArrayCollection id="shoppingCartDB"
collectionChange="updateCartTotal()" />
private function updateCartTotal() : void
if( cartTotal ) {
var total:Number = 0;
for(var i:int=0; i < shoppingCartDB.length; i++)
var record:Object = shoppingCartDB.getItemAt(i);
total += record.price * record.quantity;

cartTotal.text = cfmt.format(total);



Take care when turning an itemRenderer into an itemEditor. The user should have a straightforward interface with a single purpose when editing a cell or record. I personally prefer to separate the functions, but there are times when using an itemRenderer as an itemEditor can make sense, even if you have to go the extra mile as with this shopping cart grand total example.

9 Responses to itemEditors – Part 3

  1. Marc says:

    Nice articles! You mention CheckBoxes for itemRenderer and itemEditor. I wonder how you block them for editing when dataGrid.editable is false. Do you know a better solution than the one below?

    public class CheckboxRenderer extends CheckBox
    override protected function clickHandler( event:MouseEvent ): void
    var dataGrid: DataGrid = listData ? listData.owner as DataGrid : null
    if ( dataGrid && dataGrid.editable )
    super.clickHandler( event )

  2. Peter Ent says:

    You could try something like this:

    override public function set listData(value:BaseListData):void
    super.listData = value;

    enabled = listData.owner.editable;

  3. Marc says:

    Thanks for the better suggestion. I’m using now this:

    override public function set listData( value:BaseListData ): void
    super.listData = value
    var dataGrid: AdvancedDataGrid = AdvancedDataGrid( listData.owner )
    var column: AdvancedDataGridColumn = AdvancedDataGridColumn( dataGrid.columns[ listData.columnIndex ] )
    var dataGridEditable: Boolean = dataGrid.editable != “”
    enabled = dataGridEditable && column.editable

  4. cipri says:

    Hi Peter,

    I have some flex problems that i couldn’t resolve. Please take a look over this topic on adobe forum:

    I need desperately help.

    My email addresses:

    Best regards,
    Cipri from

  5. Haluk Tezcan says:

    Excellent articles on itemEditors and thank you. We have an application where we need to present each data in two rows and have it editable so that the full datagrid and all data elements are visible on screen without scrolling (medical application). So, the idea is that the first 6 elements of the data are in the first row and the 7th and 8th elements in the second row. Because the length of each element on given data item is variable it needs to be variableRowHeight. Any suggestions on how to present two rows with different column widths for each data item.

  6. Bob says:

    Great series of articles. I would appreciate your recommendation on configuring a grid with a row of checkboxes (as opposed to your sample with a column of checkboxes).

    Any ideas would be appreciated, Thanks

  7. Peter Ent says:

    SInce the DataGrid is column-oriented, I would use a Grid container and, within that, use a Repeater to generate all of the GridRows. If you are having a row of checkboxes as the first row, then put that before the Repeater.

  8. Stefan says:

    Hi Peter,

    thanks for the great articles! Sorry, it is not really related to this article, but I have some problems with customizing the header renderer of the DataGrid. To create a header renderer that encapsulates two or more components within it, e.g. a Label (headerText) and a TextInput field underneath (for filtering) is not easy at all and probably a good idea for another great articel.


  9. Peter Ent says:

    Header renderers are a pain. I’ll consider writing an article about them once I see how Flex 4 handles them.