Default Sorting for a Flex DataGrid

While working on the DeveloperCircuit Flex widget, I had the need to set a default sorting for a Flex DataGrid control. The standard control does not provide a mechanism to do this.

The Flex documentation suggests that you sort the underlying dataset, however I felt that this was very unsatisfactory. When you manually sort a DataGrid, the column which is being used to sort the data and the order of the sort, ascending or descending, is shown by the way of little black arrow in the column header. I felt that the default sorting should also be communicated to the user by this mechanism.

After some experimentation, this is the solution I came up with. There is a DataGrid event which is called when the user sorts a column. By announcing this event manually, once the underling data set has been returned by a call to a back end server, one can simulate the user action and set the default sorting of the DataGrid, complete with arrow. Example below:

<mx:RemoteObject
	id="someService"
	destination="ColdFusion"
	source="{this.someServiceLocation}"
	showBusyCursor="false"
	result="this.someDataGrid.dispatchEvent
	(
		new DataGridEvent
		(
			DataGridEvent.HEADER_RELEASE,
			false,
			true,
			0,	// The zero-based index of the column to sort in the DataGrid object's columns array.
			null,
			0,
			null,
			null,
			0
		)
	);"
/>

45 Responses to “Default Sorting for a Flex DataGrid”

  1. Inigo Says:

    Thanks for the tip, it worked nicely!

  2. LV Says:

    +1

  3. Steve Kwan Says:

    Works perfectly! Thanks. I’m surprised Flex doesn’t have this by default.

  4. Alistair Says:

    David you are a lifesaver. This has been driving me nuts for days. Thanks.

  5. Homer Says:

    That just ended an hour of head-banging. Thanks!

  6. Josh Says:

    Thanks for posting this, it’s EXACTLY what I needed!

  7. Gregor Rot Says:

    Hi there, nice – i was working on this code for some time now in the hope to be able to also specify in which direction (ascending, descending) the sort on the grid is shown, but no luck :( Did you manage to do it? Tnx

  8. David Says:

    @Gregor – The only thing I can think of is to issues either one, or two DataGridEvent.HEADER_RELEASE events depending on the required sort order.

  9. Max Says:

    Thanks a lot mate! That’s just what i needed. So why the heck didn’t Adobe implement something like this?!

  10. Gabriel Says:

    Thanks for the idea! I used it with the AdvancedDataGrid dispatching the event AdvancedDataGridEvent.SORT.

  11. Bob Tate Says:

    Thank you for this little snippet. It was indeed the answer to what it was I was looking for. As I am still new to Flex it took me a little bit to understand what it was that was taking place here. Once I did it was great. I made a slight modification to it so that it may be more easily reusable code by placing this in a function. The code is below. I hope that this helps others looking for this.

    private function dgSort(dgName:Object, dgColumn:int):void
    {
    /**
    * The dgSort functions requires two input items. The dgName which as the variable suggest
    * is the name of the DataGrid and the dgColumn, DataGrid Column, to be sorted by the numbers.
    * column numbering begins with zero.
    *
    * These input items are used with the DataGridEvent below and is dispatched (excuted). The
    * DataGridEvent has a total of 9 values for successful operation. They are listed below in expanded detail.
    *
    * 1. type:String — The event type; indicates the action that caused the event. This is represented by the
    * dgName input variable. The DataGridEvent.HEADER_RELEASE constant defines the value of the type property
    * of the event object for a headerRelease event, which indicates that the user pressed and released the
    * mouse on a column header
    *
    * 2. bubbles:Boolean (default = false) — Specifies whether the event can bubble up the display list
    * hierarchy.
    *
    * 3. cancelable:Boolean (default = false) — Specifies whether the behavior associated with the event can
    * be prevented.
    *
    * 4. columnIndex:int (default = -1) — The zero-based index of the column where the event occurred. This
    * is represented by the dgColumn input variable.
    *
    * 5. dataField:String (default = null) — The name of the field or property in the data associated with
    * the column.
    *
    * 6. rowIndex:int (default = -1) — The zero-based index of the item in the in the data provider.
    *
    * 7. reason:String (default = null) — The reason for an itemEditEnd event.
    *
    * 8. itemRenderer:IListItemRenderer (default = null) — The item renderer that is being edited or the
    * header renderer that was clicked.
    *
    * 9. localX:Number — Column x-position for replaying columnStretch events.
    */

    dgName.dispatchEvent(
    new DataGridEvent
    (
    DataGridEvent.HEADER_RELEASE,
    false,
    true,
    dgColumn,
    null,
    0,
    null,
    null,
    0
    )
    )
    }

  12. Bob Tate Says:

    Gabriel,

    I would love to know how it is that you managed to get the AdvancedDataGrid to do a default sort. So far I have been having no luck with that one and it would be a gret help as the current project I am on has at least one ADG that will initial be sorted on at least 3 fields.

  13. Darrell Says:

    Nicely done – thanks David and Bob (for the function). Small point for the noobs out there (which I fell foul of) … make sure you have the ‘import mx.events.DataGridEvent;’ defined otherwise the function bombs out with a [1120: Access of undefined property DataGridEvent.].

    Small question – I’m using this to auto-sort a datagrid by date column – date info is stored in YYYY-MM-DD format so gets round any Flex date understanding nightmares. The dgSort function above sorts in ascending order initially whereas I want it in descending order (i.e. newest dates top). Is there any way to specify one of the parameters above to do this? At the moment my workaround is to call the dgSort twice but it would be nice to save some cpu cycles. Any ideas appreciated.

    Thanks, Darrell.

  14. Elvis Fernandes Says:

    Great! A simple solution for an annoying problem!

    Thanks!!!

  15. venkat Says:

    Hi,

    I am doing a server side sort and getting the new dataset on header release of a datagrid. But i am not getting the default sort arrow. If i dispatch a new data grid header release event in the result handler, it is going in an infinite loop.

    please give some clues, i m new to flex.

    Thanks,
    Venkat.

  16. Daniela Says:

    Much thank you!! just saved my day =]

  17. phu Says:

    Many thanks !! i’ve been searching for this for 2 days now. thanks for putting me outta my misery.
    like Gabriel i dispatched AdvancedDataGridEvent.SORT event. using this on a Flex app.

  18. David Says:

    This is excellent – however, it alternates between ascending and descending sort each time – a bit annoying!

  19. Ashwin Says:

    Thanks :-) it works without any problems.

  20. Eirik Says:

    Excellent tip. Just what I needed. Anyone has a great idea of how do sort descending? I’ve modified the code to dispatch the event twice for descending sort order, but if anyone has a better way of doing it…?

    public function dgSort(dgName : Object, dgColumn : int, descending : Boolean) : void {
    for (var i : int = 0; i < (descending ? 2 : 1); i++) {
    dgName.dispatchEvent(
    new DataGridEvent (
    DataGridEvent.HEADER_RELEASE,
    false,
    true,
    dgColumn,
    null,
    0,
    null,
    null,
    0
    )
    )
    }
    }

  21. Jessica Says:

    This is useful! Has anyone got example code of this sort using an AdvancedDataGrid?

    Also does any clever flex person have an idea how i would sort the AdvancedDataGrid on the Branch column containing a date? Im pretty new to flex and this is really bugging me :(

    Jess
    x

  22. Chandu Says:

    Hi

    I am stuck with server side sorting. below is the problem I am encountering.

    1) I am able to populate the data into the datagrid but it doesnt show the sort icon by default .. How Can I make it show on the column I desire

    2) I want to do server side sorting and override datagrid provided sort.How do I get the information if the user has clicked in asc order or desc order.

    After I receive data from the server do I need to create the columns again or just refresg the data provider..

    Any help will be greatly appreciated

    Regards

  23. chad Says:

    I just stumbled upon this post when searching for DG sorting. Some of you have asked how to make this descending instead of ascending by default. The easy way (instead of firing this off twice), is to set the “sortDescending” property to “true” in the datagrid COLUMN.

    Thanks for the help.
    -chad

  24. nylarch Says:

    Serious life saver – thanks for this….

  25. Josh G Says:

    Thanks so much! I ran into this problem after failing to apply a sort to the underlying data provider since the column I wanted to sort was derived from more than one field.

  26. Sajain Geevar Says:

    @Gregor, David

    Use a variable sort direction and a sort compare function. Make the sort compare function to sort ascending or descending based on the sort direction value.

  27. Shashank Says:

    Hi,

    Thanks for the trick worked nicely for me

  28. božulin Says:

    David, Bob Tate, thanks a lot!

    good luck with your work.

  29. Flexicious Says:

    public static function sortDataGrid(dgGrid : Object, dgColumnName : String , descending : Boolean) : void {
    var dgColumn:int=0;
    for (var col : int = 0; col < dgGrid.columns.length; col++) {
    var column:Object = dgGrid.columns[col];
    if(column.dataField == dgColumnName){
    var sortField:String = column.dataField;
    var sortThese:Sort = new Sort();
    sortThese.fields = [new SortField(sortField, true, descending)];
    dgGrid.dataProvider.sort= sortThese;
    dgGrid.dataProvider.refresh();
    dgColumn = i;
    break;
    }
    }

    for (var i : int = 0; i < (descending ? 2 : 1); i++) {
    dgGrid.dispatchEvent(new AdvancedDataGridEvent(AdvancedDataGridEvent.HEADER_RELEASE,false,true,dgColumn,null,0,null,null,0))
    }
    }

  30. Erik Reedstrom Says:

    @Eirik

    To sort descending, set sortDescending=”true” on the DataGridColumn or AdvancedDataGridColumn. When the default sort gets called, it will be descending.

    Cheers!

  31. Mynam Says:

    Nice tip.. Thanks tons for all the time you have saved.

  32. Toggi Says:

    Thanks for the idea of dispatching the event. I used it with the trick of descending the column and it works as I wanted.

  33. Rich Sadowsky Says:

    Let me throw my thanks into the mix. I used the dgSort function in the comments above with sortDescending and it did exactly what I needed. That said, it seems like this should be an inherent property of the DataGrid to allow you to specify a column to use for the initial sort. As we can see from these functions it is not hard to accomplish and it seems like a very common use case. Adobe Flex Components team, are you listening?

  34. links for 2010-04-21 | andy.edmonds.be Says:

    [...] Default Sorting for a Flex DataGrid | BealeARTS (tags: flex datagrid sorting automatic) [...]

  35. Pratik Says:

    Thanks….it really helped n what a cool way to do that !

  36. David Lira Says:

    You can define the first sort like ASC or DESC setting the propertie sortDescending in datagrid. True for descending or false for ascending. I think that is a better solution than dispatch two events.

  37. Eric Heimburg Says:

    Just wanted to say thanks for this, too. Bizarre that this is not a built-in feature, though…

  38. adeb Says:

    Thanks a lot

  39. Chris Says:

    Thank you so much! That’s a perfect little snippet I pasted right into my code.

  40. Jon Says:

    This neat hack is totally unnecessary if you use an instance of ListCollectionView as your dataProvider because you can accomplish this by setting the sort property of your collection as shown below. Your suggestion would also reset the sort column if/when data is reloaded from the server. Thus you should create your collection and set the default sort field during initialization, then populate your collection anytime data is loaded from an external source, which will preserve the user’s chosen sort columns when data is reloaded.

    However, I’ve found that if you have to set a custom sort function, then the DataGrid and AdvancedDataGrid doesn’t show the ascending/descending marker by default even though the data is properly sorted. I tried your suggestion to see if it would resolve my issue, but unfortunately it does not work either.

    [code]

    import mx.collections.Sort;
    import mx.collections.SortField;
    import mx.collections.XMLListCollection;

    private accounts:XMLListCollection;
    private function init():void {
    accounts = new XMLListCollection();
    accounts.sort = new Sort();
    accounts.sort.fields = [new SortField("name", true, false, false)];
    accounts.refresh();
    }

    [/code]

    If you want to try an awesome data grid, go to http://flexicious.com/Home/Demo.

  41. Rakesh Says:

    Hi,
    I want to sort a coulmn of a datagrid, by using predefined values..
    i have values in datagridcolumn like ( ? , ! , *, *!, !?, *?…)

    AND I WANT TO SORT THE GRID VALUE IN THE ORDER ( ! , *! ,!? , ? , *? , * )
    cAN YOU GUYS HELP ME OUT..

  42. Tashu Says:

    It worked :)

  43. hectorzeta Says:

    Great and simple solution.
    Just one side note, if you change the dataprovider of the datagrid the sorting will be lost. In order to avoid this you can use a ListCollectionView as the dataprovider of the datagrid and assign your ArrayCollection data to the ‘list’ property of the ListCollectionView. Then if you need to change the dataprovider you only modify the list property and the dataprovider of the datagrid is not reset, and the sort is preserved.

  44. cirxesoul Says:

    Awesome! Thanks.

  45. Jan de Ruiter Says:

    Thanks, This is exactly what I have been looking for.
    >David Says:
    >October 11th, 2008 at 4:52 pm
    >This is excellent – however, it alternates between ascending and >descending sort each time – a bit annoying!
    I had the same problem, and finally found out why it happens.
    The problem I had was that a refresh of the dataset would reset any sorting that was in effect. So I recorded the sorting column AND sorting order when the user clicks a column header. Then on the refresh of the dataset, I restored the recorded sorting by way of the described DataGridEvent. Once when the sorting was ASC, twice when the sorting was DESC. But it turned out that in the case of DESC order, the alternating problem appears.
    I found out that the reason for this is, that the DataGrid ALSO remembers the sort order. So one DataGridEvent is always enough. If the column was DESC, then after the event it is still DESC. The dispatching of a second Event causes the alternating problem.
    Hope this helps anyone facing this problem.


Leave a Reply

You must be logged in to post a comment.

Copyright © 2005, David Beale

  • Valid XHTML 1.0!
  • Valid CSS
  • Level Triple-A conformance icon, W3C-WAI Web Content Accessibility Guidelines 1.0