I’ve seen this question come up a few times recently in various forums/lists and even in my blog comments (see “Changing the default sort arrow skin on a Flex DataGrid control”).
The following example shows how you can display the sort arrow in a DataGrid control in Flex without having the user click on a column header in the DataGrid control.
Full code after the jump.
<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2008/02/28/displaying-the-sort-arrow-in-a-flex-datagrid-control-without-having-to-click-a-column/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical"
verticalAlign="middle"
backgroundColor="white">
<mx:Script>
<![CDATA[
import mx.collections.Sort;
import mx.collections.SortField;
private function init():void {
arrColl.sort = new Sort();
arrColl.sort.fields = [new SortField("idx", false, true)];
arrColl.refresh();
}
]]>
</mx:Script>
<mx:ArrayCollection id="arrColl">
<mx:source>
<mx:Array>
<mx:Object idx="1" c1="One.1" c2="One.2" />
<mx:Object idx="2" c1="Two.1" c2="Two.2" />
<mx:Object idx="3" c1="Three.1" c2="Three.2" />
<mx:Object idx="4" c1="Four.1" c2="Four.2" />
<mx:Object idx="5" c1="Five.1" c2="Five.2" />
<mx:Object idx="6" c1="Six.1" c2="Six.2" />
<mx:Object idx="7" c1="Seven.1" c2="Seven.2" />
<mx:Object idx="8" c1="Eight.1" c2="Eight.2" />
<mx:Object idx="9" c1="Nine.1" c2="Nine.2" />
<mx:Object idx="10" c1="Ten.1" c2="Ten.2" />
<mx:Object idx="11" c1="Eleven.1" c2="Eleven.2" />
<mx:Object idx="12" c1="Twelve.1" c2="Twelve.2" />
<mx:Object idx="13" c1="Thirteen.1" c2="Thirteen.2" />
</mx:Array>
</mx:source>
</mx:ArrayCollection>
<mx:DataGrid id="dataGrid"
dataProvider="{arrColl}"
creationComplete="init();">
<mx:columns>
<mx:DataGridColumn dataField="idx" />
<mx:DataGridColumn dataField="c1" />
<mx:DataGridColumn dataField="c2" />
</mx:columns>
</mx:DataGrid>
</mx:Application>
View source is enabled in the following example.
A big thanks to Rob for the heads up with the solution!
For more information, see http://bugs.adobe.com/jira/browse/SDK-14663.



Thanks for this helpful post, glad to see that it’s not only me that has had this problem, much appreciated, keep up the good work!
The solution is good, but I just want to know is there any way that we can showed the up/down arrow without having to refresh (sort) the grid data provider.
Is there a way to programatically get the last column sort? In otherwords say the user has clicked on a particular column header, how would you store the sort associated with that header, along with its direction?
Bill J,
Not sure if this is the best solution, but it seems to work:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" verticalAlign="middle" backgroundColor="white"> <mx:Script> <![CDATA[ import mx.events.DataGridEvent; private function dataGrid_headerRelease(evt:DataGridEvent):void { // Hang out a while, wait a frame. callLater(delayedSet, [evt]); } private function delayedSet(evt:DataGridEvent):void { lbl1.text = evt.dataField; lbl2.text = dataGrid.columns[evt.columnIndex].sortDescending; } ]]> </mx:Script> <mx:Array id="arr"> <mx:Object idx="1" c1="One.1" c2="One.2" /> <mx:Object idx="2" c1="Two.1" c2="Two.2" /> <mx:Object idx="3" c1="Three.1" c2="Three.2" /> <mx:Object idx="4" c1="Four.1" c2="Four.2" /> <mx:Object idx="5" c1="Five.1" c2="Five.2" /> <mx:Object idx="6" c1="Six.1" c2="Six.2" /> </mx:Array> <mx:DataGrid id="dataGrid" dataProvider="{arr}" headerRelease="dataGrid_headerRelease(event);"> <mx:columns> <mx:DataGridColumn dataField="idx" /> <mx:DataGridColumn dataField="c1" /> <mx:DataGridColumn dataField="c2" /> </mx:columns> </mx:DataGrid> <mx:Form> <mx:FormItem label="dataField:"> <mx:Label id="lbl1" /> </mx:FormItem> <mx:FormItem label="sortDescending:"> <mx:Label id="lbl2" /> </mx:FormItem> </mx:Form> </mx:Application>If you use an ArrayCollection or XMLListCollection as a data provider, you may be able to access the collection’s underlying
sortproperty and determine the sort order as well.In fact, here’s what that would look like too:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" verticalAlign="middle" backgroundColor="white"> <mx:Script> <![CDATA[ import mx.collections.SortField; import mx.events.DataGridEvent; private function dataGrid_headerRelease(evt:DataGridEvent):void { // Hang out a while, wait a frame. callLater(delayedSet, [evt]); } private function delayedSet(evt:DataGridEvent):void { var sortField:SortField = arrColl.sort.fields[0] as SortField; lbl1.text = sortField.name; lbl2.text = sortField.descending.toString(); } ]]> </mx:Script> <mx:ArrayCollection id="arrColl"> <mx:source> <mx:Array> <mx:Object idx="1" c1="One.1" c2="One.2" /> <mx:Object idx="2" c1="Two.1" c2="Two.2" /> <mx:Object idx="3" c1="Three.1" c2="Three.2" /> <mx:Object idx="4" c1="Four.1" c2="Four.2" /> <mx:Object idx="5" c1="Five.1" c2="Five.2" /> <mx:Object idx="6" c1="Six.1" c2="Six.2" /> </mx:Array> </mx:source> </mx:ArrayCollection> <mx:DataGrid id="dataGrid" dataProvider="{arrColl}" headerRelease="dataGrid_headerRelease(event);"> <mx:columns> <mx:DataGridColumn dataField="idx" /> <mx:DataGridColumn dataField="c1" /> <mx:DataGridColumn dataField="c2" /> </mx:columns> </mx:DataGrid> <mx:Form> <mx:FormItem label="dataField:"> <mx:Label id="lbl1" /> </mx:FormItem> <mx:FormItem label="sortDescending:"> <mx:Label id="lbl2" /> </mx:FormItem> </mx:Form> </mx:Application>Again, I make no claims this is the “best” approach, just the first thing that came to mind at 7:40am. :)
Peter
Hieu Lam,
I don’t believe there is a way to show a sort arrow without refreshing the data provider. Or maybe there is, and I just don’t know about it (very likely).
If you haven’t found a solution yet (and are still reading comments), I suggest asking on the FlexCoders mailing list and seeing if anybody there has any ideas.
Peter
Just looking at the DataGrid source I dont think there is a way to update it without refreshing the list.
There is a private method on the grid, called UpdateSortIndexAndDirection which is private. Internally it sets the sortIndex and last sortIndex (these are mx_internal) which are used to draw the caret in the placeSortArrow method.
In my case I had results coming back from a server on each click so I had to extend DataGrid and override the headerReleaseHandler method. In there I stopped the default sort from happening and saved the column to be sorted off, when the results were returned from the search I reset the search critera in the sort attribute on the new collection called refresh and all was well.
But like peterd said, there is probably another way :).
Hi ,
Thanks for the post.
Saved me some time.
Your posts always help me with the right kind of stuff.
Anil
How do you do this with an HTTPService? I am using SQL and tried to convert it to an ArrayCollection, but no luck.
Hello Jason,
Could you tell me how you override headerReleaseHandler? I can’t do this… I have an exception “1020: Method marked override must override another method”
Please…