Adobe Flex 3 Help

Handling events in a DataGrid control

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.

Sorting data in DataGrid controls

The DataGrid control supports displaying sorted data in two ways:

  • By default, the control displays data in the sorted order of its underlying data provider collection. Therefore you can use the collection Sort and SortField classes to control the order of the rows.
  • By default, users can sort the display by clicking the column headers. Clicking the column header initially sorts the display in descending order of the entries in the selected column, and clicking the header again reverses the sort order. You can disable sorting an entire DataGrid Control or individual columns.

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:

  • Use an object that implements the ICollectionView interface, such as an ArrayCollection, in the dataProvider property of your DataGrid. Specify a Sort object in the data provider object's the sort field.
  • Use the Sort object to control the order of the rows in the dataProvider object.

Controlling user sorting of DataGrid displays

The following DataGrid and DataGridColumn properties control how users can sort data:

  • The DataGrid sortableColumns property is a global switch that enables user sorting of the DataGrid display by clicking column headings. The default this property is true.
  • The DataGridColumn sortable property specifies whether users can sort an individual column. The default this property is true.
  • The DataGridColumn sortCompareFunction property lets you specify a custom comparison function. This property sets the compare property of the default SortField class object that the DataGrid uses to sort the grid when users click the headers. It lets you specify the function that compares two objects and determines which would be higher in the sort order, without requiring you to explicitly create a Sort object on your data provider. For detailed information on the comparison function signature and behavior, see sortCompareFunction in the Adobe Flex Language Reference.

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:

  1. Use the event object's columnIndex property to determine the clicked column.
  2. Create a Sort object with a set of SortField objects based on the clicked column and any other rules that you need to control the sorting order. For more information on using Sort objects, see Sorting and filtering data for viewing.
  3. Apply the Sort object to the collection assigned as the data provider.
  4. Call the DataGridEvent class event object's preventDefault() method to prevent the DataGrid from doing a default column sort.

Note: If you specify a labelFunction property, you must also specify a sortCompareFunction function. The Computed Columns example in Flex Explorer shows this use.

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:

DataGrid control user interaction

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:

  • If the value of the sortableColumns property is true, the default value, clicking within a column header causes the DataGrid control to be sorted based on the column's cell values.
  • If the value of the draggableColumns property is true, the default value, clicking and holding the mouse button within a column header, dragging horizontally, and releasing the mouse button moves the column to new location.
  • If the value of the resizableColumns property is true, the default value, clicking in the area between columns permits column resizing.

Keyboard navigation

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.