tags:

views:

3213

answers:

3

OK I am sorting an XMLListCollection in alphabetical order. I have one issue tho, If the value is "ALL" I want it to be first in the list. Most cases this happens already but values that are numbers are being sorted before "ALL" ...I want "ALL" to always be the first selection in my dataProvider and then the rest alphabetical.

So I am tryint to write my own sort function, is there a way I can check if one of the values is all, and if not tell it to do the regular compare on the values?

here is what I have:

function myCompare(a:Object, b:Object, fields:Array = null):int
{
    if(String(a).toLowerCase() == 'all')
    {
        return -1;
    }
    else if(String(b).toLowerCase() == 'all')
    {
        return 1;
    }
    // NEED to return default comparison results here?
}

//------------------------------

var sort:Sort = new Sort();
sort.compareFunction = myCompare;

Does anyone have a solution for what I am trying to do?

Thanks!!

+1  A: 

Well I tried something out, and I am really surprised it actually worked, but here is what I did.

The Sort class has a private function called internalCompare. Since it is private you cannot call it. BUT there is a getter function called compareFunction, and if no compare function is defined it returns a reference to the internalCompare function. So what I did was get this reference and then call it.

private function myCompare(a:Object, b:Object, fields:Array = null):int
{
    if(String(a).toLowerCase() == 'all')
    {
        return -1;
    }
    else if(String(b).toLowerCase() == 'all')
    {
        return 1;
    }
    // NEED to return default comparison results here?
    var s:Sort = new Sort();
    var f:Function = s.compareFunction;
    return f.call(null,a,b,fields);
}
John Isaacks
You may also be able to make f an instance or static member of the class, so you don't have to create a new sort each time a compare is made.
Kathy Van Stone
@Kathy, good point.
John Isaacks
+3  A: 

The solution from John Isaacks is awesome, but he forgot about "fields" variable and his example doesn't work for more complicated objects (other than Strings)

Example:

// collection with custom objects. We want to sort them on "value" property
// var item:CustomObject = new CustomObject();
// item.name = 'Test';
// item.value = 'Simple Value';

var collection:ArrayCollection = new ArrayCollection();
var s:Sort = new Sort();
s.fields = [new SortField("value")];
s.compareFunction = myCompare;
collection.sort = s;
collection.refresh();

private function myCompare(a:Object, b:Object, fields:Array = null):int
{
    if(String((a as CustomObject).value).toLowerCase() == 'all')
    {
        return -1;
    }
    else if(String((b as CustomObject).value).toLowerCase() == 'all')
    {
        return 1;
    }
    // NEED to return default comparison results here?
    var s:Sort = new Sort();
    s.fields = fields;
    var f:Function = s.compareFunction;
    return f.call(null,a,b,fields);
}
Imrahil
At first glance I thought you were wrong but turns out Adobe managed to screw up once more. Their internalCompare function checks for the instance fields instead of the function parameter. Yet another one of Adobe's gems...
bug-a-lot
A: 

Thanks guys, this helped a lot. In our case, we needed all empty rows (in a DataGrid) on the bottom. All non-empty rows should be sorted normally. Our row data is all dynamic Objects (converted from JSON) -- the call to ValidationHelper.hasData() simply checks if the row is empty. For some reason the fields sometimes contain the dataField String value instead of SortFields, hence the check before setting the 'fields' property:

private function compareEmptyAlwaysLast(a:Object, b:Object, fields:Array = null):int {
    var result:int;
    if (!ValidationHelper.hasData(a)) {
        result = 1;
    } else if (!ValidationHelper.hasData(b)) {
        result = -1;
    } else {
        if (fields && fields.length > 0 && fields[0] is SortField) {
            STATIC_SORT.fields = fields;
        }
        var f:Function = STATIC_SORT.compareFunction;
        result = f.call(null,a,b,fields);
    }
    return result;
}
Ola