Create a custom sort for the Spark DataGrid control

By default, users can sort the row of a DataGrid 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. For an example, see Sorting the columns of the Spark DataGrid control.

The GridColumnsortCompareFunction property lets you specify a custom comparison function used to sort the rows by that column. This property sets the compareFunction property of the default Spark SortField class object used by the DataGrid.

The sortCompareFunction property 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.

The comparison function passed to the sortCompareFunction property must have the following signature:

function sortCompareFunction(obj1:Object, obj2:Object, gc:GridColumn):int { 
    // Sort logic 
}

The obj1 and obj2 arguments specify the objects to compare, and gc specifies the column of the DataGrid control to sort.

Flex ships with two collator classes to help you write your comparison function. The spark.globalization.MatchingCollator and spark.globalization.SortingCollator provide locale-sensitive string comparison functions.

By default, the sorting used by the DataGrid control is case sensitive. In the following example, you use the SortingCollator class to perform a case-insensitive comparison of two cells to sort the Name column of the DataGrid:

<?xml version="1.0" encoding="utf-8"?>
<!-- dpcontrols\sparkdpcontrols\SparkDGXMLSort.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:mx="library://ns.adobe.com/flex/mx"
    width="500" height="600">
    <s:layout>
        <s:VerticalLayout paddingTop="10"/>
    </s:layout>

    <fx:Declarations>
        <fx:XMLList id="employees">
            <employee>
                <name>Joanne Wall</name>
                <phone>555-219-2012</phone>
                <email>jwall@fictitious.com</email>
                <active>true</active>
            </employee>
            <employee>
                <name>Mary Jones</name>
                <phone>555-219-2000</phone>
                <email>mjones@fictitious.com</email>
                <active>true</active>
            </employee>            
            <employee>
                <name>mary jones</name>
                <phone>555-219-2000</phone>
                <email>mjones@fictitious.com</email>
                <active>true</active>
            </employee>            
            <employee>
                <name>Maurice Smith</name>
                <phone>555-219-2012</phone>
                <email>maurice@fictitious.com</email>
                <active>false</active>
            </employee>            
            <employee>
                <name>Dave Davis</name>
                <phone>555-219-2000</phone>
                <email>ddavis@fictitious.com</email>
                <active>true</active>
            </employee>            
            <employee>
                <name>Tom Maple</name>
                <phone>555-219-2000</phone>
                <email>tmaple@fictitious.com</email>
                <active>true</active>
            </employee>            
        </fx:XMLList>
        <s:XMLListCollection id="employees2" source="{employees}"/>
        <s:XMLListCollection id="employees3" source="{employees}"/>
    </fx:Declarations>
    
    <fx:Script>
        <![CDATA[
            import mx.events.FlexEvent;
            import spark.collections.Sort;
            import spark.collections.SortField;
            import spark.globalization.SortingCollator;
            
            // Create an instance of the SortingCollator.
            private var collator:SortingCollator = new SortingCollator();
            
            // Define the sort compare function used by the first column.
            private function sortCompareFunction(obj1:Object, obj2:Object, gc:GridColumn):int {
                // Make the sort case insensitive. The default is case sensitive.
                collator.ignoreCase = true;
                return collator.compare(obj1[gc.dataField], obj2[gc.dataField]);
            }
        ]]>
    </fx:Script>

    <s:Label text="Custom case insensitive sort of the Name colum"/>
    <s:DataGrid id="dg" width="500" dataProvider="{employees2}">
        <s:columns>
            <s:ArrayList>
                <s:GridColumn dataField="name" headerText="Name" 
                    sortCompareFunction="sortCompareFunction"/>
                <s:GridColumn dataField="phone" headerText="Phone"/>
                <s:GridColumn dataField="email" headerText="Email"/>
            </s:ArrayList>
        </s:columns>
    </s:DataGrid>

    <s:Label text="Default case sensitive sort of the Name colum"/>
    <s:DataGrid width="500" dataProvider="{employees3}">
        <s:columns>
            <s:ArrayList>
                <s:GridColumn dataField="name" headerText="Name"/>
                <s:GridColumn dataField="phone" headerText="Phone"/>
                <s:GridColumn dataField="email" headerText="Email"/>
            </s:ArrayList>
        </s:columns>
    </s:DataGrid>    
</s:Application>

The executing SWF file for the previous example is shown below: