Hi all,

I have a problem related to sorting type-casted numeric data, and was
wondering if someone could help me out:

Given some numeric data stored as strings ("11.5"), how can I populate
it into a DataGrid and have it sort properly?

>From the Flex API docs
<http://livedocs.adobe.com/flex/3/langref/mx/controls/dataGridClasses/Da\
taGridColumn.html#sortCompareFunction>  it appears that when you use a
labelFunction instead of a dataField to specify what should be displayed
in a column, that the output of the label function is what is then used
for sorting:

"If you specify a value of the labelFunction property,       you must
also provide a function to the sortCompareFunction property,      
unless sorting is not allowed on this column.            "

So my first attempt was to simply cast the strings to numbers within the
label function and hope that the default sorters would still be
available:

private function testLabel2(item:Object, col:DataGridColumn):Number {
     return parseFloat(item.string);
}
... I also tried using "Number(item.string)", however, neither worked so
I went to manually specifying the sort compare function:

     public function sortAsIs(obj1:Object, obj2:Object):int {
         if (obj1 < obj2)
             return -1;
         else if (obj1 == obj2)
             return 0;
         else
             return 1;
     }

This didn't do the trick either. So finally, I decided to try doing the
conversion in the sortCompareFunction, just in case it was comparing the
original data fields and not the output of the label function. Again no
luck.

Anyone have any suggestions? Any help would be greatly appreciated.

Here is the full code for the test case I am describing:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml";>
     <mx:Script>
     <![CDATA[
         import mx.collections.ArrayCollection;

         [Bindable]
         public var test:ArrayCollection = new ArrayCollection([
             {"string": "11.0", "number": 11.0},
             {"string": "0", "number": 0},
             {"string": "7.75", "number": 7.75},
             {"string": "8", "number": 8},
             {"string": "3", "number": 3},
             {"string": "8.93", "number": 8.93}
         ]);

         private function testLabel1(item:Object,
col:DataGridColumn):Number {
             return Number(item.string);
         }

         private function testLabel2(item:Object,
col:DataGridColumn):Number {
             return parseFloat(item.string);
         }

         public function sortAsIs(obj1:Object, obj2:Object):int {
             if (obj1 < obj2)
                 return -1;
             else if (obj1 == obj2)
                 return 0;
             else
                 return 1;
         }

         public function sortAfterCasting(obj1:Object, obj2:Object):int {
             var a:Number = Number(obj1);
             var b:Number = Number(obj2);

             if (a < b)
                 return -1;
             else if (a == b)
                 return 0;
             else
                 return 1;
         }

     ]]>
     </mx:Script>

     <mx:DataGrid id="testDG" dataProvider="{test}">
         <mx:columns>
             <mx:DataGridColumn dataField="string" />
             <mx:DataGridColumn dataField="number" />
             <mx:DataGridColumn headerText="Number(string) - sortAsIs"
labelFunction="testLabel1" sortCompareFunction="sortAsIs"/>
             <mx:DataGridColumn headerText="parseFloat(string) -
sortAsIs" labelFunction="testLabel2" sortCompareFunction="sortAsIs"/>
             <mx:DataGridColumn headerText="Number(string) - casting"
labelFunction="testLabel1" sortCompareFunction="sortAfterCasting"/>
             <mx:DataGridColumn headerText="parseFloat(string) - casting"
labelFunction="testLabel2" sortCompareFunction="sortAfterCasting"/>
         </mx:columns>
     </mx:DataGrid>
</mx:Application>


Thanks!
Keith


Reply via email to