Well, i’m not a big fan of this, but Flex’s Datagrid control doesn’t have a nice little property allowing case-insensitive string sorts.
Huh.
The best solution I could find was on the flexexamples blog. But seriously, who wants to hard code a function every time they want case-insensitive sorting ?
Not I.
How about this soln?
public function doCaselessSortForField(field:String):Function
{
return function(obj1:Object, obj2:Object):int
{
return mx.utils.ObjectUtil.stringCompare(obj1[field],obj2[field],true);
}
}
Called by a datagrid thusly:
<mx:DataGrid>
<mx:columns>
<mx:DataGridColumn sortCompareFunction=”doCaselessSortForField(‘Title’)” headerText=”Title” dataField=”Title” />
</mx:columns>
</mx:DataGrid>
Thank you! I’m new to Flex/AS3 and didn’t even realize the “field” had to be referenced in the compare function until seeing your solution.
Here’s a generic numeric sort:
public function sortNumericField(field:String):Function
{
return function(obj1:Object, obj2:Object):int
{
return mx.Utils.ObjectUtil.numericCompare(obj1[field],obj2[field]);
}
}
Very nice code! Thanks for sharing :).
Brilliant. Thanks for the solution; it saved me from creating redundant functions for each field.
Yeah!!
This is a great tip!
Thanks a lot……found this initially…didnt work….tried many different things for 3 days and finally tried this again and it worked 🙂
You’re briliant, thank you very much
Well done sir
Solid gold. Thx.
A little more generic example, doesn’t require the field name or nested function:
public function numericCompare( a:Object, b:Object ):int {
var field:String = dataProvider.sort.fields[0].name;
return ObjectUtil.numericCompare( a[field], b[field] );
}
Ritter,
Thanks for the generic example. It was exactly what I needed.
Just want to add one more message of praise. Insprired!
Just wanted to say this was exactly what I was looking for. However, for anyone that is setting the dataField with an attribute like dataField=”@moduleId”, the main example will throw an error. Ritter’s example below solved this issue, Thanks again
public function numericCompare( a:Object, b:Object ):int {
var field:String = dataProvider.sort.fields[0].name;
return ObjectUtil.numericCompare( a[field], b[field] );
}
Brilliant… Thanks, just what I needed….
@Ritter:
in my opinion your solution:
var field:String = dataProvider.sort.fields[0].name;
is not really more generic, because you create more dependencies since you use the dataProvider to get the field name. And if you want to reuse the caseInsensitive compare function in another datagrid you’ll have to copy the same function from the original datagrid into the new component. So creating a static function with the original code provided by justin seems to be the best solution. Here is my packaged version (including checks for hte field name, in order to avoid NullPointerExceptions):
public static function sortStringCaseInsensitveForField(field:String):Function
{
return function(obj1:Object, obj2:Object):int
{
// Make sure obj1 has a field property.
if (!obj1.hasOwnProperty(field)) {
obj1[field] = null;
}
// Make sure obj2 has a field property.
if (!obj2.hasOwnProperty(field)) {
obj2[field] = null;
}
return ObjectUtil.stringCompare(obj1[field],obj2[field],true);
}
}
Absolutely brilliant, this one helped me a lot. Thanks.
In Flex 4, is necessary put { } when call function like this:
It works fine on AdvancedDataGrid too.
Thanks for that, used it to do this:
package datagrid
{
import mx.controls.dataGridClasses.DataGridColumn;
import mx.utils.ObjectUtil;
public class ExtendedDataGridColumn extends DataGridColumn
{
private var _caselessSorting:Boolean;
public function ExtendedDataGridColumn(columnName:String=null)
{
super(columnName);
caselessSorting = true;
}
public function get caselessSorting():Boolean
{
return _caselessSorting;
}
public function set caselessSorting(value:Boolean):void
{
_caselessSorting = value;
if(value)
{
sortCompareFunction = caselessSort;
}
else if(sortCompareFunction == caselessSort)
{
sortCompareFunction = null;
}
}
protected function caselessSort(obj1:Object, obj2:Object):int
{
return ObjectUtil.stringCompare(itemToLabel(obj1), itemToLabel(obj2), true);
}
}
}