views:

1433

answers:

4

I extended the DataGridColumn because I wanted to include a custom itemToLabel function (to be able to show nested data in the DataGrid. See this question.

Anyways, it also needs a custom sorting function. So I have written the sorting function like so:

private function mySortCompareFunction(obj1:Object, obj2:Object):int{
    var currentData1:Object = obj1;
    var currentData2:Object = obj2;

    //some logic here to get the currentData if the object is nested.

    if(currentData1 is int && currentData2 is int){
        var int1:int = int(currentData1);
        var int2:int = int(currentData2);
        var result:int = (int1>int2)?-1:1; 
        return result;
    }
    //so on for string and date
}

And in the constructor of my CustomDataGridColumn, I've put: super(columnName); sortCompareFunction = mySortCompareFunction;

Whenever I try to sort the column, I get the error "Error: Find criteria must contain at least one sort field value."

When I debug and step through each step, I see that the first few times, the function is being called correctly, but towards the end, this error occurs.

Can someone please shed some light on what is happening here?

Thanks.

+1  A: 

Hi,

I have seen this error too, and I tracked it down to one of the cells containing 'null'. And if I remember correctly, this error also shows up, when one of the columns has a wrong 'dataField' attribute.

hth,

Koen Weyn

Koen Weyn
I think you just solved my problem on which I spend nearly 6 hours so far. Thank you. I'd vote you up more if I could ;)
trex279
A: 

Just to specify how exactly I solved this problem (for the benefit of others):

Instead of using the dataField property (to which I was assigning something like data.name, data.title since I was getting data from a nested object), I created my own field nestedDataField and made it bindable. So my code basically looks like this now:

public class DataGridColumnNested extends DataGridColumn{
[Bindable] public var nestedDataField:String;

private function mySortCompareFunction(obj1:Object, obj2:Object):int{
    var currentData1:Object = obj1;
    var currentData2:Object = obj2;

    //some logic here to get the currentData if the object is nested.

    if(currentData1 is int && currentData2 is int){
        var int1:int = int(currentData1);
        var int2:int = int(currentData2);
        var result:int = (int1>int2)?-1:1; 
        return result;
    }
    //so on for string and date
}
}

Then I assign to this new variable my dataField entry

<custom:DataGridColumnNested headerText="Name" nestedDataField="data.name"/>

And lo and behold! it works without a hitch.

trex279
A: 

I often find it easier to use the standard datafield and just write a getter function in my valueobject to use as a datafield. For example:

//file SomeObject.as with a nested object as property
public class SomeObject
{
   public var someProperty:AnotherObject;

   public function get someString():String;
   {
     if(someProperty)
        return someProperty.someString;
     else
        return "";
   }
}

//your nested class, AnotherObject.as
public class AnotherObject
{
   public var someString:String;
}

//this way sorting and the label will work without custom label/compare functions
<mx:DataGridColumn headerText="" dataField="someString"/>
David Vermeir
A: 

The easiest way to solve the problem is change the dataField="obj.atributte" by a labelFunction. If you want you can add a sortCompareFunction too.

    <mx:DataGridColumn headerText="email" 
dataField="user.email" textAlign="center" />

change by

    <mx:DataGridColumn headerText="email" 
labelFunction="emailLabelFunction" 
sortCompareFunction="emailsCompareFunction2" 
textAlign="center" />



public static function emailLabelFunction(item:Object, column:DataGridColumn):String{

   if (item!=null){
    var user:User = (item as TpAnnouncementUser).user as User;

    return user.email;
   }else{

    return "";
   }
}

public static function emailCompareFunction(obj1:Object, obj2:Object):int{

    var dato1:String = User(obj1).email.toLowerCase();
    var dato2:String = User(obj2).email.toLowerCase();

    return ObjectUtil.compare(dato1, dato2);

}


    public static function emailsCompareFunction2(obj1:Object, obj2:Object):int{

    var dato3:User = (TpAnnouncementUser(obj1).user as User);
    var dato4:User = (TpAnnouncementUser(obj2).user as User);

    return emailCompareFunction(dato3, dato4);
AntuanF1