Sorting date columns in a DataGrid

by Peter deHaan on August 12, 2007

Here’s an example of sorting a column of dates in a Flex DataGrid. The dates start out as Strings (such as “04/14/1980″) so you create a custom sortCompareFunction on that DataGrid column which converts the strings to dates so Flex will sort the dates in sequential order (as oppsed to string order). Hope that helps somebody out there.

I also created a little tooltip on the date column which shows the dates in a somewhat more readable form (“April 14 1980″) using the DataGridColumn object’s showDataTips and dataTipFunction properties.

Full code after the jump.

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2007/08/12/sorting-date-columns-in-a-datagrid/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white">
 
    <mx:Script>
        <![CDATA[
            import mx.utils.ObjectUtil;
 
            private function date_sortCompareFunc(itemA:Object, itemB:Object):int {
                /* Date.parse() returns an int, but
                   ObjectUtil.dateCompare() expects two
                   Date objects, so convert String to
                   int to Date. */
                var dateA:Date = new Date(Date.parse(itemA.dob));
                var dateB:Date = new Date(Date.parse(itemB.dob));
                return ObjectUtil.dateCompare(dateA, dateB);
            }
 
            private function date_dataTipFunc(item:Object):String {
                return dateFormatter.format(item.dob);
            }
        ]]>
    </mx:Script>
 
    <mx:ArrayCollection id="arrColl">
        <mx:source>
            <mx:Array>
                <mx:Object name="User A" dob="04/14/1980" />
                <mx:Object name="User B" dob="01/02/1975" />
                <mx:Object name="User C" dob="12/30/1977" />
                <mx:Object name="User D" dob="10/27/1968" />
            </mx:Array>
        </mx:source>
    </mx:ArrayCollection>
 
    <mx:DateFormatter id="dateFormatter" formatString="MMMM D, YYYY" />
 
    <mx:DataGrid id="dataGrid" dataProvider="{arrColl}">
        <mx:columns>
            <mx:DataGridColumn dataField="name"
                    headerText="Name:" />
 
            <mx:DataGridColumn dataField="dob"
                    headerText="Date of birth:"
                    sortCompareFunction="date_sortCompareFunc"
                    showDataTips="true"
                    dataTipFunction="date_dataTipFunc" />
        </mx:columns>
    </mx:DataGrid>
 
</mx:Application>

View source is enabled in the following example.

{ 10 comments… read them below or add one }

Tim Oxley September 21, 2009 at 8:54 pm

According to the current docs (22 September 09), Date.parse() is Air SDK only… though it appears to work fine for me.

http://livedocs.adobe.com/flex/gumbo/langref/Date.html#parse%28%29

Reply

Peter deHaan September 22, 2009 at 8:33 am

@Tim Oxley,

Great question. Feel free to file a bug at http://bugs.adobe.com/flex/ against the Flex Documentation project. Also, I can ask somebody to take a quick look as to why that is marked AIR only. It seems to be that way in the Flex 3 documentation also.

Peter

Reply

Kuriakose Jacob Thomas October 14, 2009 at 3:17 am
DAvid January 2, 2010 at 3:18 am

Hi,

if ever the date i want to display is of format: “DD/MM/YYYY”.

How does that one goes?

Thanks in advance …

David

Reply

Peter deHaan January 2, 2010 at 8:03 am
Michael Liscio January 25, 2010 at 8:25 am

This is a great solutio. One small problem that I have found. In a practical situation you could have rows in your datagrid that do not have a date filled in. Idealy you would want these dates to appear first or last when you sort by your date collumn. However I have found that this solution as is does not take that into consideration. When you trace this out and look at both dates you will notice that if there is no value in the specific row you are looking at the date will show up as NaN. This of course is expected obviously you can not convert a null value to a date. If you keep tracing it out you will notice that depending on which way you are trying to sort accending or decending one of the two dates dateA, and dateB will always have a value. if dateA = NaN you want to return -1 if dateB = NaN you want to return 1 otherwise let this function do its job. So if you add the following lines to this function this is a perfect solution

if(dateA.time.toString() == “NaN”){
return -1
}// end if

else if(dateB.time.toString() == “NaN”){
return 1
}// end if

obviosuly you will have to put the original return statement in the else case as follows

else{
return ObjectUtil.dateCompare(dateA, dateB);
}// end else

Hope this helps

Thanks again for this solution

Reply

Flexicious March 3, 2010 at 6:07 pm

We actually have a grid that solves the issue of sorting/filtering by dates/numbers/booleans where the actual data is string and a intermediate conversion is required before the sort/filter operation. Please take a look at http://www.flexicious.com.

Reply

Rafael Magana June 29, 2010 at 7:57 am

http://raflabs.com/blogs/silence-is-foo/2010/06/28/creating-a-common-sorting-function-for-a-datagrid-control-in-flex/

Sometimes I’m in the situation where I need to use the same complex sorting function for several datagrids, here’s my solution.

Reply

Anonymous November 28, 2009 at 5:34 am

what happened if a==b?

Reply

Anonymous November 28, 2009 at 6:44 am

thanks for a great solution!
when you replace the line:
col = dataGrid.columns[evt.columnIndex].dataField;
with:
col = evt.dataField;

you will be able to use it with multiple datagrids

Reply

Leave a Comment

Sorry, this blog is terrible at eating HTML comments.
If you're pasting any HTML/XML/MXML code, you need to convert your < characters to &lt; and your > characters to &gt; .

Anti-Spam Protection by WP-SpamFree

Previous post:

Next post: