Sorting Date fields in a DataGrid in the Flex Framework

I was working on some new mini chart apps over the weekend for the MXNA reports section, and had a DataGrid that contained dates. I wanted to allow the user to sort the datagrid by the DateField, but by default the DataGrid sorts dates with a string compare (calling toString on the Date instance).

I tried to set up a custom sort function for the DataGridColumn instance that contained the dates, but because I was using a custom label format function for the column, Flex passed the labels to me, and not the data items (which would allow me to get access to the Date instance). Because of this, I couldn’t sort on the date.

There is an example on Macromedia.com that shows how to sort by dates, but it requires that you override and implement all sorting for the DataGrid (something which seemed unecessary and overkill to me). Peter Ent also posted an example, but it required massaging the data on the server first, something which was not an option for me since I was using a public web service API.

So, after much trial and error, and help from Matt Chotin, I finally got it working, and figured I would post it here.

Basically, I listen for the headerRelease event for the DataGrid. If it is in response to the date column being clicked, then I sort the dataprovider that the DataGrid is hooked up to (otherwise, I do nothing, and let the DataGrid do the sorting).

Here is an example:

Here is the Code:

———-DateSortExample.mxml———-

[code][/code]

—————————————-

———-DateSortExample.as———-

[code]private var dp:Array;private var sortOrder:Number = 1;private function initTag():Void{//listend for the headerRelease event on the datagrid, which is broadcast//when any of the column headers are clicked.dg.addEventListener(“headerRelease”,mx.utils.Delegate.create(this, onDateHeaderRelease));dp = new Array();//pupulate the date grid with some data.var item:Object;var randomDay:Number;var randomMonth:Number;for(var i:Number = 0; i d2ms){return -1;}else if(d1ms < d2ms){return 1;}else{return 0;}}//compares the datesprivate function dateFieldCompare(item1:Object, item2:Object, bit:Number):Number{//determine which way the column should be sorted (ASC or DESCvar toggle:Number = (bit == Array.DESCENDING)? 1 : -1;//call compare date function, and then toggle the sort directionreturn toggle * compareDates(item1.date,item2.date);}//called when any of the datagrids column headings are clickedprivate function onDateHeaderRelease(eventObj:Object):Void{//Only sort if the Date column head was clickedif(eventObj.columnIndex == 2){//sort the dataProvider directly, passing the function to do the sort//and a bit indicating whether to sort ascending or descendingdp.sortItems(dateFieldCompare, ((sortOrder == 1)? 0: Array.DESCENDING));//reverse the sort order so the next time the column is clicked, it is//sorted in the reverse ordersortOrder *= -1;}}[/code]

—————————————-

You can download the source from here (or right click on the example).

Creative Commons License
This work is licensed under a Creative Commons License.

<!—->

13 Responses to Sorting Date fields in a DataGrid in the Flex Framework

  1. CR says:

    excellent !is there a way do do the same in flash ???2e question, the flex datagrid component looks better that the flash one? can we use it in the flash ide ?RegardsCR

  2. Hey Mike,Very useful! I had an almost indentical situation a few weeks ago. A project I had using a datagrid recquired that every time the datagrid was displayed it showed the most recent dated recordsets starting at the top, descending on down to the oldest. The problem was the # of records the client wanted to display without paging data, I couldnt sort them ahead of time, and the format the date was coming in didnt lend itself to converting quickly enough in flash for a good compare routine. My sort routine ended up bogging everything way down and exceeding the built in scriptLimits. I overrode that temporarily until I could get a fix in place. Since this was a kiosk project, I already had a Visual Basic wrapper surrounding the Flash content, so I took advantage of that, and used VB to reformat the data and put it into a Dictionary object, sorted it on an extra re-formatted date field, then popped it back into flash as a serialized dataset. I let flash deserialize it – basically a series of splits, which go pretty fast in Flash, then I repointed the dataprovider to the newly deserialized data and everything was cool. Went from 45 seconds down to less than 6 with 1000’s of records. Not the most elegant solution if your trying to stay all in Flash – but it worked pretty well. I’ll give this sort routine a try next time around.Good post!Rob

  3. If you want to do the same thing in flash you can have an additional field in the dataprovider array. This field contains the date value represented as number.eg: jan 04 2005 is represented as “20050104” . You can then do a numeric sort on this field.regardsKiran

  4. CR says:

    ok thx =)the code works inside flash =)CR

  5. Vee says:

    Thank you 🙂

  6. Terry Middleton says:

    Gentlemen,I’m not a flash programmer nor flex and I am wondering if you know of an ‘out-of-the-box’ solution for a datagrid that we could use on a website build in DM with Php?Basically, I’m looking for a dynamic datagrid that populates from a table and allows the user to update a field on the grid.It is very similar to an expense report where you have line items and the amount.Of course, there are other little needs, but I’m not able to find anything anywhere unless I dive “real” deep into flash.Have you seen anything that you could point me to?Much appreciated,Terryterry@iwearwatches.com

  7. Steven Ross says:

    How would you do this using CF 7 and flash based cfforms? Is it possible?

  8. Micah says:

    I am trying to use this code to sort the date field in my datagrid correctly and I am running into some problems. First of all, I cannot get the event handling function to execute unless I specify it in the mxml. Trying to create the event listener programmatically doesn’t seem to be working for me. Secondly, I can’t get the dataprovider to sort based on the custom funcitons. I am making a web service call to return the data and binding the result to the datagrid. Any suggestions for something I need to do differently. I am using the above code almost verbatim aside from the dataprovider being different.Thanks,Micah

  9. pitcher says:

    you are sorting the array that is assigned to the datagrid.dataprovider and not the datagrid itsself.I have a dataset holding a recordset. For display purposes I use a datagrid (datagrid.dataprovider=dataset.dataprovidider)When I try to sort the grid on a datefield by using datagrid.sortItems(compareFunc) the compareFunc is never called, as if the method does not exists.

  10. Carlos Lozano Diez says:

    Why not simply manipulate the date/timestamp as milliseconds/Number and use a CustomCellRenderer on the table column to render the text? The table will do auto sorting based on the millisecond/Number value and not the rendered text (which is what we see). It’s much faster than a custom Comparator, especially with large datasets.The Date.class in AS provides all the methods needed to convert millis/timestamp to Date and vice versa and methods to create the formatted date text as needed.

  11. Logu says:

    Dear All,I am experienced in flex 1.5 for the past 1 month. Now I am able to get results from remote objects and populate it to a Datagrid. Now I have an issue of adding these values to a Tree. For example:First set of values in array:1.Thomas2.James3.PhilipsSecond set of values in array:1.java, unix, j2ee2. Flex, Flash, CF3. Oracle, JavaI need to design a tree at runtime. when i click the node “Thomas”, I need to add the children for that node “java”,”unix”,”j2ee” and open the node and display it to the user.Any help? mail me to ship2moon@gmail.comThanks in advance.regards,Logu.

  12. Yavstr says:

    I’ve got a major problem with the dataGrid in Flash 8.When used on the stage all works fine but once the dataGrid is nested in a movie clip the data displays and the listener is getting assigned but it returns null for selectedItem.Is there an issue when putting a datagrid nested into movie clips.

  13. Dre says:

    This function is a built-in sort function to flash and works on dates.my_dg.sortItemsBy(“Date”, Array.NUMERIC | Array.DESCENDING);