Hi Keith,
Have you tried casting your string to a number via the number()
function first? Number() handles floating points well. We have the same
problem sorting kit numbers in true numerical fashion as we can have
some that begin with a letter versus a true number. So in our sort
compare we do this:
public static function compareKitNumbers(obj1:Object,
obj2:Object):int
{
var value1:Number = (obj1.KitNum == '' || obj1.KitNum ==
null) ? null : new Number(obj1.KitNum);
var value2:Number = (obj2.KitNum == '' || obj2.KitNum ==
null) ? null : new Number(obj2.KitNum);
var kitnum1:String = obj1.KitNum as String;
var kitnum2:String = obj2.KitNum as String;
var kit1Length:int = kitnum1.length - 1;
var kit2Length:int = kitnum2.length - 1;
if (isNaN(value1) isNaN(value2))
{
if (kitnum1.substr(0,1) kitnum2.substr(0,1))
{
return -1;
}
else if (kitnum1.substr(0,1) kitnum2.substr(0,1))
{
return 1;
}
else
{
value1 = new Number(kitnum1.substr(1,kit1Length));
value2 = new Number(kitnum2.substr(1,kit2Length));
}
}
if (value1 value2 || (isNaN(value2) !isNaN(value1)))
{
return -1;
}
else if (value1 value2 || (isNaN(value1) !isNaN(value2)))
{
return 1;
}
else
{
return 0;
}
}
HTH,
Adrian
Keith Hughitt wrote:
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/DataGridColumn.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 /