Invalid Character
Invalid Character

Reputation: 203

Flex AdvancedDataGrid - setting the correct sort function at runtime

Using Flex 3.2, I have a object which extends a TitleWindow. In this TitleWindow I have an AdvancedDataGrid.

On creation of this object, I pass it 2 lists, one full of data to display, and the other I pass an array of column definitions. This allows me to, at runtime, create the correct columns and define the correct display attributes for each column (e.g. booleans will show up as checkboxes, and dates are formatted in a specific format (coming in from an XML feed in a variety of STRING formats where nulls are a possibility)

The problem is that the default sort, being based on string, doesn't work 100% of the time and even when the format is one that would be sorted nicely, it fails when nulls are involved.

The above problem would be easily solved using a sortCompareFunction, but the fact is when you set the sortCompareFunction of the column, it seems to require you to hardcode in the column name into the function.

Is there any way around this last issue?

for reference here's the function I'm using to create the columns:

    private function setupGrid():void
    {

        var localcols:Array = new Array();
        datagrid1.columns = new Array();


        var gcol:AdvancedDataGridColumn = new AdvancedDataGridColumn();
            gcol.headerText = "Group";
            gcol.dataField="GroupLabel";                
            localcols.push(gcol);

        for each (var s:Object in DGColumns)
        {               
            var col:AdvancedDataGridColumn = new AdvancedDataGridColumn();
            col.headerText = s.Header;
            col.dataField=s.Column;
            col.headerWordWrap = true;
            //col.sortable = false;             

            try
            {
                switch (s.type)
                {
                    case "boolean":
                        col.labelFunction = boolCellLabel;                           
                        break;
                    case "date":
                        col.labelFunction = dateCellLabel;
                        col.sortCompareFunction = dateCompare; // doesn't work, as the function requires the column name coded into it
                        // inline does not work because s.Column is still set to the last column in the grid at sort time 
                        col.sortCompareFunction = function (obj1, obj2):int
                            {
                                var l:XML = obj1 as XML;
                                var r:XML = obj2 as XML;

                                var left:Date = new Date( l.elements(s.Column).valueOf() );
                                var right:Date = new Date( r.elements(s.Column).valueOf() );


                                if (left == null && right == null) return 0;
                                else if (left == null) return -1
                                else if (right == null) return 1 
                                else if (left < right) return -1;
                                else if (left > right) return 1;
                                else return 0;
                        ;
                        break;
                    case "string": // use defaults
                    default:
                        break;
                }
            }
            catch (ex:Object) 
            {}              
            localcols.push(col);                                
        }
        datagrid1.columns = localcols;      
    }

and for the column definition:

var DGColumns:Array = [{Header:"Lorem ipsum", Column: "lorem", type:"string"},                      
{Header:"dolor", Column: "dolor" , type:"string"},
{Header:"sit amet", Column: "sitAmet", type:"string"},
{Header:"consectetur", Column: "consecteturDate", type:"date"},
{Header:"adipiscing", Column: "adipiscingDate", type:"date"},
{Header:"elit", Column: "isElit" , type:"boolean"}
]

Upvotes: 1

Views: 5428

Answers (3)

user478727
user478727

Reputation: 23

protected function headerReleaseHandler(event:AdvancedDataGridEvent):void
{
  //event.dataField will give you column name

  //call sort compare fn
}

Upvotes: 0

Invalid Character
Invalid Character

Reputation: 203

Found the answer. It's a multi-part solution.
Part 1: set the compare function as I tried first:

col.sortCompareFunction = dateCompare;


part 2: add a headerRelease event handler to the AdvancedDataGrid

<mx:AdvancedDataGrid -otherAttributes- headerRelease="HeaderClick(event)"   >


part 3: define the event handler and global variable to remember the column

private var clickedCol:AdvancedDataGridColumn      
private function HeaderClick(event:AdvancedDataGridEvent):void 
  {
   clickedCol = AdvancedDataGridColumn(event.currentTarget.columns[event.columnIndex]);

  }


part 4: tell the compare function how to use the column

public function dateCompare(obj1:Object, obj2:Object):int 
        { 
         trace ("compare");

         var l:XML = obj1 as XML;
      var r:XML = obj2 as XML;

      var lDateStr:String = l.elements(clickedCol.dataField).valueOf()
      var rDateStr:String = r.elements(clickedCol.dataField).valueOf()
      // compare logic goes here
      }


part 5: build/run/profit

Upvotes: 2

Amarghosh
Amarghosh

Reputation: 59461

declare all the sort compare functions outside (class level) and assign the name of appropriate one to the sortCompareFunction at runtime.

Upvotes: 0

Related Questions