Products
Technologies

Developer resources

Multiple column sorting with a DataGrid

Not yet rated

Problem

Whereas the AdvancedDataGrid component allows you to sort on multiple columns, the DataGrid component only allows you to sort on one column.

Solution

Prevent the DataGrid default handling of the header release event and implement your own sorting function.

Detailed explanation

Subclass the SDK DataGrid :

 

public class MyDataGrid extends DataGrid {

     ...

}

 

Create your own event listener on the header release event, in the MyDataGrid constructor for instance :

 

addEventListener( DataGridEvent.HEADER_RELEASE    , onHeaderRelease ,  false , int.MAX_VALUE );

 

The int.MAX_VALUE is here to ensure that our listener will be the first one to be called.

 

Then implement the listener :

 

private function onHeaderRelease( event:DataGridEvent ):void {
      event.preventDefault();
      sortByColumn( event.columnIndex );
}

 

Don't forget to prevent the default behaviour of the event, so that our sort will be the only one used here (that's why we need our listener to be the first one called).

 

And finally take the SDK DataGrid's header release listener and customize it :

 

        private function sortByColumn( index :int ) :void {
            var c :DataGridColumn = columns[ index ];
            var desc :Boolean = c.sortDescending;
           
            // do the sort if we're allowed to
            if ( c.sortable ) {
                var s :Sort = collection.sort;
                var f :SortField;
                if ( s ) {
                    s.compareFunction = null;
                    // analyze the current sort to see what we've been given
                    var sf :Array = s.fields;
                    if ( sf ) {
                        for ( var i :int = 0 ; i < sf.length ; i++ ) {
                            if ( sf[ i ].name == c.dataField ) {
                                // we're part of the current sort
                                f = sf[ i ]
                                /*
                                 * Reverse sort direction, but only if the sort field is the primary sort field.
                                 * Otherwise, we just want to make it the primary one, without changing its direction.
                                 */
                                if ( i == 0 )
                                    desc = !f.descending;
                                break;
                            }
                        }
                    }
                } else
                    s = new Sort;

                if ( !f )
                    f = new SortField( c.dataField );

                c.sortDescending = desc;

                // if you have a labelFunction you must supply a sortCompareFunction
                f.name = c.dataField;
                if ( c.sortCompareFunction != null ) {
                    f.compareFunction = c.sortCompareFunction;
                } else {
                    f.compareFunction = null;
                }
                f.descending = desc;
               
                // Avoid NullPointerException on first sort
                if ( s.fields == null )
                    s.fields = [];
               
                // Add the new SortField to the collection sort
                if ( ArrayUtil.getItemIndex( f , s.fields ) != -1 ) {
                    s.fields = ArrayUtils.removeItem( f , s.fields );
                }
                s.fields.unshift( f );
            }
            collection.sort = s;
            collection.refresh();
        }

 

The ArrayUtils.removeItem is a custom utility function removing element from an Array. There goes its implementation :

 

        /**
         * Creates a new Array containing the same elements as the given one,
         * excepted for the given object to remove.
         */
        public static function removeItem( element:Object , array:Array ):Array {
            var result    :Array = [];
            for ( var i:int = 0 ; i < array.length ; i++ )
                if ( array[i] != element )
                    result.push( array[i] );
           
            return result;
        }


+
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. Permissions beyond the scope of this license, pertaining to the examples of code included within this work are available at Adobe.

Report abuse

Related recipes