Tips & Tricks : itemEditors – I
Alex has written two wonderful posts in his blog about working with itemRenderers. Along with itemRenderers another extremely useful feature in flex is itemEditors. itemEditors provide a highly efficient and clean way of providing custom editors for editing data in components like List and DataGrid.
Take this example: You have a Datagrid with two columns (Product, Available and Order Qty). Avaliable & Order Qty columns contain numeric data. You want to allow the user to make an order by selecting the Order Qty column by entering a value for the number of pieces he wants to order in the column.
Option 1: You can simply pop the default itemEditor of a Datagrid / List, which is a TextInput where the user can key in the number.
Option 2: You can pop a custom itemEditor.In this case, using a NumericStepper makes a lot of sense because it lets the user increment / decrement a value and also allow him to type in just like in a textinput.
I have used Option 2, to implement the solution.
So, Why itemEditors and not itemRenderers?
You can set a NumericStepper as an itemRenderer and set the rendererIsEditor property to true. But in that case the renderers are pre-created, they are *always* displayed evcen when you are not editing it and lastly, you have to write your own logic to persist the data after editing the cell. (That surely seems like more work than using itemEditors for our current problem.)
Lets Get back to itemEditors - Take a look at the example attached along with this post which uses a NumericStepper as its itemEditor. You can see that the NumericStepper is popped when you click on the cell in the Order Qty column and the editor is destroyed when you click on anywhere else / change the focus. Also note that the value that you entered / stepped is now committed and the DataGrid display is updated.
Lets do a little digging into the code
As you can see, there is *very little* code that is written to implement this solution.
Step 1 – Set up the data: (see inline code comments)
//DataGrid event, fired when the itemEditing is performed
import mx.events.DataGridEvent;
//Used for populating the datagrid
import mx.collections.ArrayCollection;
//Used to display the Alert
import mx.controls.Alert;
//ArrayCollection that will hold the data
[Bindable]private var arr:ArrayCollection
private function populateData():void
{
//Create an array with dummy product names
var prodarray:Array = ['Apple','Orange','Peach','Grapes','Guava','Mango','Raspberry','Strawberry','Watermelon','Passionfruit']
//Create an arraycollection
arr = new ArrayCollection()
//Loop to create 10 records
for(var i:int=0;i<10;i++)
{
//create a random number
var rnd:Number = Math.round(Math.random()*100);
//Create an object to insert into the array collection
var obj:Object = {value:rnd, disp:prodarray[i],order:0}
//Add the object to array collection
arr.addItem(obj)
}}
Step 2: Create the Datagrid and set up the itemEditor.
The following lines of code create an instance of Datagrid with 3 columns, and we set the itemEditor and editorDataField properties to the third column. (See inline comments)
One important point to be remembered here. The DataGrid or List always looks for the default property text on the itemEditors unless you specify the editorDataField property to the appropriate value. In this case editorDataField will be value since we will be altering the value property when we increment / decrement a NumericStepper. If we were to use a TextArea, the property should be set to text. If you forget to set this property, then prepare yourself for some erratic behavior
<!– DataGrid Instance, dataProvider is bound to ‘arr’- the arraycollection. –>
<mx:DataGrid editable=”true” id=”datagrid” x=”56″ y=”104″ height=”176″ width=”317″ dataProvider=”{arr}”>
<mx:columns>
<mx:DataGridColumn headerText=”Product” dataField=”disp”/>
<mx:DataGridColumn headerText=”Available” dataField=”value”/>
<!– itemEditor is set to our class CustomNumericStepper. Always remember to set the editorDataField to the dataField on which the operation is performed–>
<mx:DataGridColumn headerText=”Order Qty” dataField=”order” itemEditor=”CustomNumericStepper” editorDataField=”value” />
</mx:columns>
</mx:DataGrid>
Step 3: Create the custom itemEditor
I have created a CustomNumericStepper class which extends from NumericStepper. (CustomNumericStepper.as). This class contains just two properties, the maximum and the stepSize. The maximum is set to 150, assuming that we will *not* be stocking more than 150 fruits of each type (well, we will change this assumption soon, accommodating a more realistic calculation, but lets keep it this way for the sake of simplicity
)
package
{
import mx.controls.NumericStepper;public class CustomNumericStepper extends NumericStepper
{
public function CustomNumericStepper():void
{
super();
//Set the properties
stepSize=1;
maximum=150;
}
}
}
Note: I chose to write this as a .as file, you could very well use an MXML component to achieve the same results.
View the Sample | Download Source
and right click on the application to view / download the full source.
Coming up next: Doing more with itemEditors – applying formatters & validators to itemEditors









July 10, 2007 - 1:31 pm
Nice. I’m trying to do this, adding numeric steppers in a DataGrid to edit quantities. My problem is, each entry in the data grid has a different minimum and maximum, as in:
private var ingredientList2:ArrayCollection = new ArrayCollection([
{label:"Celery, chopped", quant:1, min2:1, max2:2, units:"cups"},
{label:"Onions, chopped", quant:1, min2:2, max2:3, units:"cups"} ]);
How can I pass the different Min and Max values to the steppers?
September 26, 2007 - 7:12 pm
Have you noticed that when you do not use the stepper in your dataGrid field and instead type in a value in that field the typed value is not committed when you leave the that record?
I have yet to find a solution for this problem!
November 27, 2007 - 6:57 am
I have a requirment where i need to render diffrent editors based on the value in the cell.
e.g. if value is numeric then number steper should be the editor and if the value is string it should render text input. Same column can have nummeric values or alpha numberic values. based on value the editor should apear.
can you help me in this ?