The DataGrid control and the DataGridEvent class define several event types that let you respond to user interaction. For example, Flex broadcasts mx.events.ListEvent class event with a type property value of mx.events.ListEvent.ITEM_CLICK ("itemClick") when a user clicks an item in a DataGrid control. You can handle this event as the following example shows:
<?xml version="1.0"?>
<!-- dpcontrols/DataGridEvents.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
<mx:Script>
<![CDATA[
import mx.events.ListEvent;
private function itemClickEvent(event:ListEvent):void {
clickColumn.text=String(event.columnIndex);
clickRow.text=String(event.rowIndex);
eventType.text=event.type;
}
]]>
</mx:Script>
<mx:DataGrid id="myGrid" width="350" height="150"
itemClick="itemClickEvent(event);">
<mx:ArrayCollection>
<mx:Object Artist="Pavement" Price="11.99"
Album="Slanted and Enchanted" />
<mx:Object Artist="Pavement" Album="Brighten the Corners"
Price="11.99" />
</mx:ArrayCollection>
</mx:DataGrid>
<mx:Form>
<mx:FormItem label="Column Index:">
<mx:Label id="clickColumn"/>
</mx:FormItem>
<mx:FormItem label="Row Index:">
<mx:Label id="clickRow"/>
</mx:FormItem>
<mx:FormItem label="Type:">
<mx:Label id="eventType"/>
</mx:FormItem>
</mx:Form>
</mx:Application>
The executing SWF file for the previous example is shown below:
In this example, you use the event handler to display the column index, row index, and event type in three TextArea controls.
The index of columns in the DataGrid control is zero-based, meaning values are 0, 1, 2, ... , n - 1, where n is the total number of columns. Row items are also indexed starting at 0. Therefore, if you select the first item in the second row, this example displays 0 in the TextArea for the column index, and 1 in the TextArea for the row index.
To access the selected item in the event handler, you can use the currentTarget property of the event object, and the selectedItem property of the DataGrid control, as the following code shows:
var selectedArtist:String=event.currentTarget.selectedItem.Artist;
The currentTarget property of the object passed to the event handler contains a reference to the DataGrid control. You can reference any control property by using currentTarget followed by a period and the property name. The currentTarget.selectedItem field contains the selected item.
The DataGrid control supports displaying sorted data in two ways:
For detailed information on using the Sort and SortField classes, see Sorting and filtering data for viewing.
Determining the initial DataGrid sort order
To specify the initial DataGrid sort order, you sort the data provider. While a number of approaches can work, the following technique takes best advantage of the built in features of Flex collections:
Controlling user sorting of DataGrid displays
The following DataGrid and DataGridColumn properties control how users can sort data:
By default, the DataGrid class uses its own sort code to control how the data gets sorted when the user clicks a column. To override this behavior, you create a headerRelease event handler to handle the DataGridEvent event that is generated when the user clicks the column header. This event handler must do the following:
The following example shows how to use the headerRelease event handler to do multi-column sorting when a user clicks a DataGrid column header.
Example: Sorting a DataGrid on multiple columns
The following example shows how you can use a collection with a Sort object to determine an initial multi-column sort and to control how the columns sort when you click the headers. The data grid is initially sorted by in-stock status first, artist second, and album name, third. If you click any heading, that column becomes the primary sort criterion, the previous primary criterion becomes the second criterion, and the previous secondary criterion becomes the third criterion.
<?xml version="1.0"?>
<!-- dpcontrols/DataGridSort.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
initialize="initDP();" width="550" height="400">
<mx:Script>
<![CDATA[
import mx.events.DataGridEvent;
import mx.collections.*;
// Declare storage variables and initialize the simple variables.
// The data provider collection.
private var myDPColl:ArrayCollection;
// The Sort object used to sort the collection.
[Bindable]
private var sortA:Sort;
// The sort fields used to determine the sort.
private var sortByInStock:SortField;
private var sortByArtist:SortField;
private var sortByAlbum:SortField;
private var sortByPrice:SortField;
// The data source that populates the collection.
private var myDP:Array = [
{Artist:'Pavement', Album:'Slanted and Enchanted',
Price:11.99, InStock: true},
{Artist:'Pavement', Album:'Crooked Rain, Crooked Rain',
Price:10.99, InStock: false},
{Artist:'Pavement', Album:'Wowee Zowee',
Price:12.99, InStock: true},
{Artist:'Asphalt', Album:'Brighten the Corners',
Price:11.99, InStock: false},
{Artist:'Asphalt', Album:'Terror Twilight',
Price:11.99, InStock: true},
{Artist:'Asphalt', Album:'Buildings Meet the Sky',
Price:14.99, InStock: true},
{Artist:'Other', Album:'Other', Price:5.99, InStock: true}
];
//Initialize the DataGrid control with sorted data.
private function initDP():void {
//Create an ArrayCollection backed by the myDP array of data.
myDPColl = new ArrayCollection(myDP);
//Create a Sort object to sort the ArrrayCollection.
sortA = new Sort();
//Initialize SortField objects for all valid sort fields:
// A true second parameter specifies a case-insensitive sort.
// A true third parameter specifies descending sort order.
// A true fourth parameter specifies a numeric sort.
sortByInStock = new SortField("InStock", true, true);
sortByArtist = new SortField("Artist", true);
sortByAlbum = new SortField("Album", true);
sortByPrice = new SortField("Price", true, false, true);
// Sort the grid using the InStock, Artist, and Album fields.
sortA.fields=[sortByInStock, sortByArtist, sortByAlbum];
myDPColl.sort=sortA;
// Refresh the collection view to show the sort.
myDPColl.refresh();
// Initial display of sort fields
tSort0.text = "First Sort Field: InStock";
tSort1.text = "Second Sort Field: Artist";
tSort2.text = "Third Sort Field: Album";
// Set the ArrayCollection as the DataGrid data provider.
myGrid.dataProvider=myDPColl;
// Set the DataGrid row count to the array length,
// plus one for the header.
myGrid.rowCount=myDPColl.length +1;
}
// Re-sort the DataGrid control when the user clicks a header.
private function headRelEvt(event:DataGridEvent):void {
// The new third priority was the old second priority.
sortA.fields[2] = sortA.fields[1];
tSort2.text = "Third Sort Field: " + sortA.fields[2].name;
// The new second priority was the old first priority.
sortA.fields[1] = sortA.fields[0];
tSort1.text = "Second Sort Field: " + sortA.fields[1].name;
// The clicked column determines the new first priority.
if (event.columnIndex==0) {
sortA.fields[0] = sortByArtist;
} else if (event.columnIndex==1) {
sortA.fields[0] = sortByAlbum;
} else if (event.columnIndex==2) {
sortA.fields[0] = sortByPrice;
} else {
sortA.fields[0] = sortByInStock;}
tSort0.text = "First Sort Field: " + sortA.fields[0].name;
// Apply the updated sort fields and re-sort.
myDPColl.sort=sortA;
// Refresh the collection to show the sort in the grid.
myDPColl.refresh();
// Prevent the DataGrid from doing a default column sort.
event.preventDefault();
}
]]>
</mx:Script>
<!-- The Data Grid control.
By default the grid and its columns can be sorted by clicking.
The headerRelease event handler overrides the default sort
behavior. -->
<mx:DataGrid id="myGrid" width="100%" headerRelease="headRelEvt(event);">
<mx:columns>
<mx:DataGridColumn minWidth="120" dataField="Artist" />
<mx:DataGridColumn minWidth="200" dataField="Album" />
<mx:DataGridColumn width="75" dataField="Price" />
<mx:DataGridColumn width="75" dataField="InStock"
headerText="In Stock"/>
</mx:columns>
</mx:DataGrid>
<mx:VBox>
<mx:Label id="tSort0" text="First Sort Field: "/>
<mx:Label id="tSort1" text="Second Sort Field: "/>
<mx:Label id="tSort2" text="Third Sort Field: "/>
</mx:VBox>
</mx:Application>
The executing SWF file for the previous example is shown below:
The DataGrid control responds to mouse and keyboard activity. The response to a mouse click or key press depends on whether a cell is editable. A cell is editable when the editable properties of the DataGrid control and the DataGridColumn containing the cell are both true. Clicking within an editable cell directs focus to that cell. Clicking a noneditable cell has no effect on the focus.
Users can modify the DataGrid control appearance in the following ways:
The DataGrid control has the following keyboard navigation features:
|
Key |
Action |
|---|---|
|
Enter Return Shift+Enter |
When a cell is in editing state, commits change, and moves editing to the cell on the same column, next row down or up, depending on whether Shift is pressed. |
|
Tab |
Moves focus to the next editable cell, traversing the cells in row order. If at the end of the last row, advances to the next element in the parent container that can receive focus. |
|
Shift+Tab |
Moves focus to the previous editable cell. If at the beginning of a row, advances to the end of the previous row. If at the beginning of the first row, advances to the previous element in the parent container that can receive focus. |
|
Up Arrow Home Page Up |
If editing a cell, shifts the cursor to the beginning of the cell's text. If the cell is not editable, moves selection up one item. |
|
Down Arrow End Page Down |
If editing a cell, shifts the cursor to the end of the cell's text. If the cell is not editable, moves selection down one item. |
|
Control |
Toggle key. If you set the DataGrid control allowMultipleSelection property to true, allows for multiple (noncontiguous) selection and deselection. Works with key presses, click selection, and drag selection. |
|
Shift |
Contiguous select key. If you set the DataGrid control allowMultipleSelection property to true, allows for contiguous selections. Works with key presses, click selection, and drag selection. |