views:

312

answers:

4

The sorting capabilities that are available in Flex assume that you have access to all the data, but I'm using a paginated datagrid (with custom code), the datagrid is binded to an ArrayCollection instance, on the next page call I change the data of the dataprovider and everything works ok, but for sorting I need to override the click or event better override the sort method of the arraycollection

All this is to be able to do a server-side sorting.

Has anyone faced this kind of issue?

A: 

I am not certain that I really understand the question, but it sounds like you need to do your sorting on the server-side. If you do not have all of the data loaded into the flex application, there is no way you could sort it.

Ryan Guill
exactly, I want to do server-side sorting, but I don't know which method must be overwritten, right now I'm trying to implement the sort() method, but I'm not sure if that's the best way to do this, I already tried overriding the click event over the datagrid header without good result.
Felipe
I'm not sure you understand what I mean by server-side. What language are you connecting to to get your data? No matter what it is, are you using sql to retrieve the data to provide to flex? If so, put your sort there. Overriding methods in flex have nothing to do with the server side at all.
Ryan Guill
A: 

I understood the problem like this:

He has a part of the total data in the flex client. Because the client does not know all of the data, sorting can't be done client side. He already has the serverside sorting working.

What he needs to do now is: When the user clicks on the header of the datagrid he wants to make a server call and get the sorted data back. The default behaviour when the header of a grid is clicked is that the data is sorted client side. So thats why he needs to to something client side.

The only thing I found was this:

<mx:DataGrid xmlns:mx="http://www.adobe.com/2006/mxml"
headerRelease="onHeaderRelease(event)">

The specified function onHeaderRelease is called as soon as the mousebutton on a header was clicked (the mousebutton was released again).

Example function. Maybe you can pick up from here

        public function onHeaderRelease(evt:DataGridEvent):void
        {
            var grd:DataGrid = DataGrid(evt.currentTarget);
            Alert.show(evt.columnIndex + " : " + (DataGridColumn)(grd.columns[evt.columnIndex]).sortDescending, "ColumnIndex : Sorted Descending?");
            // do the server called and get the sorted array back
        }

I hope this will help you!

countcb
Thanks for the answer countcb, I was trying to avoid visual tricks (connect mouse click event and things like that) mostly because that doesn't let me use an almost standard grid.
Felipe
A: 

I implemented the following solution, which at the moment is working pretty well, but probably there are improvements that can be made.

I extended ArrayCollection class and override the sort set/get and refresh method

package custom
{
import mx.collections.ArrayCollection;
import mx.collections.Sort;

/**
 *  Dispatched when a sort is required
 *
 *  @eventType custom.PaginatedCollectionEvent.SORT
 */
[Event(name="sort" , type="custom.PaginatedCollectionEvent")]

public class PaginatedCollection extends ArrayCollection
{
    private var _sort:Sort;

    public function PaginatedCollection(source:Array=null)
    {
        super(source);
    }

    public function setDefaultSort (s:Sort):void
    {
        _sort = s;
    }


    override public function set sort(s:Sort):void
    {
        _sort = s;
        if (!s)
            return;

        var event:PaginatedCollectionEvent = new PaginatedCollectionEvent(PaginatedCollectionEvent.SORT);
        event.fields = s.fields;
        event.s = s;
        this.dispatchEvent(event);
    }

    override public function get sort():Sort
    {
        return _sort;
    }

    /**
     * Avoid the internal sorting implementation, with this it's possible
     * to do a server side sort.
     *
     * @return true
     */
    override public function refresh():Boolean
    {
        return true;
    }

    /**
     * Wrapper for ArrayCollection refesh implementation
     */
    public function superRefresh():Boolean
    {
        return super.refresh();
    }
}

}

Felipe
A: 

Here are the steps I used to solve this issue... the nice thing about this solution is that I can allow Flex to "sort" along with me, which keeps the sort direction icons visible on the DataGrid.

Steps: 1. use the headerRelease event of the DataGrid to intercept the "sort" request. 2. keep a local map of columns and their current sort directions... this is a mimic of what flex is doing on its sort... so all columns start out with "ascending", and then the direction is toggled only when a given column is clicked twice in a row. this could probably be done by watching the flex internal structures, but i didn't care to try that. 3. the headerRelease event uses the requested column from its event, along with the previous requested column and the map of current column sort directions to decide whether to update the sort direction in the local map. 4. make the call to the server to get the appropriately sorted page of data.

at this point, Flex wants to sort the data as well... ( unless you preventDefault() the headerRelease event )... to allow Flex to "sort" the data without messing anything up, and so that the direction icons continue to function properly, you can:

  1. add a "row id" field to your SQL result set on the server, which is simply a counter for each sequential row in the result set, after it's been sorted and paged... this id will always be ascending, no matter what sort direction is applied.
  2. set the sortCompareFunction on the DataGridColumns to a "dummy" sort that uses this row id... as such:

    public function doNothingSort( a:Object, b:Object ):int { if( weAreCurrentlyInAscendingDirection ) return ObjectUtil.numericCompare( a.new, b.num ); else return ObjectUtil.numericCompare( b.num, a.num );

This will allow flex to run through the "page" and leave everything as is... so it's happy and you're happy because you have the icons...

jbell