A list component dispatches the following events as part of the cell editing process: the itemEditBeginning, itemEditBegin, and the itemEditEnd events. The list-based controls define default event listeners for all three of these events.
You can write your own event listeners for one or more of these events to customize the editing process. When you write your own event listener, it executes before the default event listener, which is defined by the component, and then the default listener executes. For example, you can modify the data passed to or returned from an item editor. You can modify the data in the event listener for the itemEditBegin event. When it completes, the default event listener runs to continue the editing process.
However, you can replace the default event listener for the component with your own event listener. To prevent the default event listener from executing, you call the preventDefault() method from anywhere in your event listener.
Use the following events when you create an item editor:
Dispatched when the user releases the mouse button while over a cell, tabs to a cell, or in any way attempts to edit a cell.
The list-based controls have a default listener for the itemEditBeginning event that sets the editedItemPosition property of the list-based control to the cell that has focus.
You typically write your own event listener for this event to prevent editing of a specific cell or cells. To prevent editing, call the preventDefault() method from within your event listener, which stops the default event listener from executing, and prevents any editing from occurring on the cell. For more information, see Example: Preventing a cell from being edited.
Dispatched before an item editor opens.
The list components have a default listener for the itemEditBegin event that calls the createItemEditor() method to perform the following actions:
You can write an event listener for this event to modify the data passed to the item editor. For example, you might modify the data, its format, or other information used by the item editor. For more information, see Example: Modifying data passed to or received from an item editor.
You can also create an event listener to determine which item editor you use to edit the cell. For example, you might have two different item editors. Within the event listener, you can examine the data to be edited, open the appropriate item editor by setting the itemEditor property to the appropriate editor, and then call the createItemEditor() method. In this case, first you call preventDefault() to stop Flex from calling the createItemEditor() method as part of the default event listener.
You can call the createItemEditor() method only from within the event listener for the itemEditBegin event. To create an editor at other times, set the editedItemPosition property to generate the itemEditBegin event.
Dispatched when the cell editing session ends, typically when focus is removed from the cell.
The list components have a default listener for this event that copies the data from the item editor to the data provider of the list-based control. The default event listener performs the following actions:
You typically write an event listener for this event to perform the following actions:
In your event listener, you can modify the data returned by the editor to the list-based control. For example, you can reformat the data before returning it to the list-based control. By default, an item editor can return only a single value. You must write an event listener for the itemEditEnd event if you want to return multiple values.
In your event listener, you can examine the data entered into the item editor. If the data is incorrect, you can call the preventDefault() method to stop Flex from passing the new data back to the list-based control and from closing the editor.
Each editable list-based control has a corresponding class that defines the event object for the cell editing events, as the following table shows:
|
List class |
Event class |
|---|---|
Notice that the event class for the List and Tree controls is ListEvent.
When defining the event listener for a list-based control, ensure that you specify the correct type for the event object passed to the event listener, as the following example shows for a DataGrid control:
public function myCellEndEvent(event:DataGridEvent):void {
// Define event listener.
}
From within an event listener, you can access the current value of the cell being edited, the new value entered by the user, or the item editor used to edit the cell.
To access the current value of a cell, you use the editedItemRenderer property of the list-based control. The editedItemRenderer property contains the data that corresponds to the cell being edited. For List and Tree controls, this property contains the data provider element for the cell. For a DataGrid control, it contains the data provider element for the entire row of the DataGrid.
To access the new cell value and the item editor, you use the itemEditorInstance property of the list-based control. The itemEditorInstance property is not initialized until after the event listener for the cellBeginEvent listener executes. Therefore, you typically access the itemEditorInstance property only from within the event listener for the itemEditEnd event.
The following example shows an event listener for the itemEditEnd event that uses these properties:
<?xml version="1.0"?>
<!-- itemRenderers\events\EndEditEventAccessEditor.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.controls.TextInput;
import mx.events.DataGridEvent;
import mx.collections.ArrayCollection;
[Bindable]
private var initDG:ArrayCollection = new ArrayCollection([
{Artist:'Pavement', Album:'Slanted and Enchanted',
Price:11.99},
{Artist:'Pavement', Album:'Brighten the Corners',
Price:11.99 }
]);
// Define event listener for the itemEditEnd event.
private function getCellInfo(event:DataGridEvent):void {
// Get the cell editor and cast it to TextInput.
var myEditor:TextInput =
TextInput(event.currentTarget.itemEditorInstance);
// Get the new value from the editor.
var newVal:String = myEditor.text;
// Get the old value.
var oldVal:String =
event.currentTarget.editedItemRenderer.data[event.dataField];
// Write out the cell coordinates, new value,
// and old value to the TextArea control.
cellInfo.text = "cell edited.\n";
cellInfo.text += "Row, column: " + event.rowIndex + ", " +
event.columnIndex + "\n";
cellInfo.text += "New value: " + newVal + "\n";
cellInfo.text += "Old value: " + oldVal;
}
]]>
</mx:Script>
<mx:TextArea id="cellInfo" width="300" height="150" />
<mx:DataGrid id="myGrid"
dataProvider="{initDG}"
editable="true"
itemEditEnd="getCellInfo(event);" >
<mx:columns>
<mx:DataGridColumn dataField="Artist"/>
<mx:DataGridColumn dataField="Album"/>
<mx:DataGridColumn dataField="Price"/>
</mx:columns>
</mx:DataGrid>
</mx:Application>
The executing SWF file for the previous example is shown below:
In this example, you access the item editor, and cast it to the correct editor class. The default item editor is a TextInput control, so you cast it to TextInput. If you had defined a custom item editor, you would cast it to that class. After you have a reference to the item editor, you can access its properties to obtain the new cell value.
To access the old value of the cell, you use the editedItemRenderer property of the DataGrid control. You then use the dataField property of the event object to access the data property for the edited column.
A user can end a cell editing session in several ways. In the body of the event listener for the itemEditEnd event, you can determine the reason for the event, and then handle it accordingly.
Each event class for a list-based control defines the reason property, which contains a value that indicates the reason for the event. The reason property has the following values:
|
Value |
Description |
|---|---|
| CANCELLED |
Specifies that the user canceled editing and that they do not want to save the edited data. Even if you call the preventDefault() method from within your event listener for the itemEditEnd event, Flex still calls the destroyItemEditor() method to close the editor. |
| NEW_COLUMN |
(DataGrid only) Specifies that the user moved focus to a new column in the same row. In an event listener, you can let the focus change occur, or prevent it. For example, your event listener might check that the user entered a valid value for the cell currently being edited. If not, you can prevent the user from moving to a new cell by calling the preventDefault() method. In this case, the item editor remains open, and the user continues to edit the current cell. If you call the preventDefault() method and also call the destroyItemEditor() method, you block the move to the new cell, but the item editor closes. |
| NEW_ROW |
Specifies that the user moved focus to a new row. You handle this value for the reason property similar to the way you handle the NEW_COLUMN value. |
| OTHER |
Specifies that the list-based control lost focus, was scrolled, or is somehow in a state where editing is not allowed. Even if you call the preventDefault() method from within your event listener for the itemEditEnd event, Flex still calls the destroyItemEditor() method to close the editor. |
The following example uses the itemEditEnd event to ensure that the user did not enter an empty String in a cell. If there is an empty String, the itemEditEnd event calls preventDefault() method to prohibit the user from removing focus from the cell until the user enters a valid value. However, if the reason property for the itemEditEnd event has the value CANCELLED, the event listener does nothing:
<?xml version="1.0"?>
<!-- itemRenderers\events\EndEditEventFormatter.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.controls.TextInput;
import mx.events.DataGridEvent;
import mx.events.DataGridEventReason;
import mx.formatters.NumberFormatter;
import mx.collections.ArrayCollection;
[Bindable]
private var initDG:ArrayCollection = new ArrayCollection([
{Artist:'Pavement', Album:'Slanted and Enchanted',
Price:11.99},
{Artist:'Pavement', Album:'Brighten the Corners',
Price:11.99 }
]);
private var myFormatter:NumberFormatter=new NumberFormatter();
public function formatData(event:DataGridEvent):void {
// Check the reason for the event.
if (event.reason == DataGridEventReason.CANCELLED)
{
// Do not update cell.
return;
}
// Get the new data value from the editor.
var newData:String=
TextInput(event.currentTarget.itemEditorInstance).text;
if(newData == "")
{
// Prevent the user from removing focus,
// and leave the cell editor open.
event.preventDefault();
// Write a message to the errorString property.
// This message appears when the user
// mouses over the editor.
TextInput(myGrid.itemEditorInstance).errorString=
"Enter a valid string.";
}
}
]]>
</mx:Script>
<mx:DataGrid id="myGrid"
dataProvider="{initDG}"
editable="true"
itemEditEnd="formatData(event);">
<mx:columns>
<mx:DataGridColumn dataField="Artist"/>
<mx:DataGridColumn dataField="Album"/>
<mx:DataGridColumn dataField="Price"/>
</mx:columns>
</mx:DataGrid>
</mx:Application>
The executing SWF file for the previous example is shown below:
In this example, if the user's reason for the event is CANCELLED, the event listener does nothing.
If the reason is NEW_COLUMN, NEW_ROW, or OTHER, the event listener performs the following actions: