How to Reorder Datagrid Columns by Drag and Drop

I recently figured out how to reorder datagrid columns by drag and drop and I figured this may be an invaluable time saver to others. So, here it is:

  1. First create a new actionscript file (*.as) and name it ColumnHeaderRenderer.as

  2. Next put this code inside that file:

package
{
    import flash.events.Event; 
    import flash.events.MouseEvent;
    import fl.controls.DataGrid;
    import fl.controls.dataGridClasses.HeaderRenderer;
    import fl.controls.dataGridClasses.DataGridColumn;
    import fl.data.DataProvider;
    import flash.geom.Rectangle;
    import flash.utils.getTimer;
    
    public class ColumnHeaderRenderer extends HeaderRenderer 
    {
        public function ColumnHeaderRenderer()
        {
            super();
            
            // detect mouse down / up
            this.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
            this.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
        }         
        
        
        
        private function onMouseUp(event:Event):void
        {
            var i:Number; // counter
            var DG:DataGrid = this.parent.parent; // reference to host datagrid
            var Pos:Number = DG.mouseX; // release position
            var ColumnIndex:Number = -1; // selected Column Index
            
            
            // Get the name of selected column by finding header text child
            for (i = 0; i < this.numChildren; i++)
            {
                // check if child is a textfield
                if (String(this.getChildAt(i).type) == "dynamic" && this.getChildAt(i).text)
                {
                    // get selected column by name (found in header text object)
                    ColumnIndex = DG.getColumnIndex(this.getChildAt(i).text);
                    break;
                }
            }
            
            
            // Proceed only if selected column was found
            if (ColumnIndex != -1)
            {
                var TotalWidth:Number = 0; // total width of columns
                
                // cycle through columns to find which was released over
                for (i = 0; i<DG.columns.length; i++)
                {
                    var DGC:DataGridColumn = DG.getColumnAt(i); // reference to datagrid column at i
                    
                    if (DGC.visible)
                    {
                        // Check if Mouse release occured over this column
                        if (Pos >= TotalWidth && Pos <= TotalWidth + DGC.width && i != ColumnIndex)
                        {
                            SwapGridColumns (DG, ColumnIndex, i); // swap the column
                            break;
                        }
                        
                        TotalWidth += DGC.width; // accumulate column width
                    }
                }
            }
        }
        
        private function onMouseDown(event:Event):void
        {
            var DG:DataGrid = this.parent.parent; // reference to host datagrid
            var DragBounds:Rectangle = new Rectangle (0 - Number(this.width / 2), 0, Number(DG.width)-10, 0); // boundary for dragging
            
            BringToFront (); // Bring this to front
            
            this.startDrag(false, DragBounds); // start dragging
        }
        
        function SwapGridColumns (DG:DataGrid, Col1:Number, Col2:Number)
        {
            var i:Number; // Counter
            var DP:DataProvider = DG.dataProvider;     //DataProvider
            var Widths:Array = new Array ();     // the widths of the columns
            var Columns:Array = new Array ();    // the column names
            var Visibility:Array = new Array (); // visibility of columns
            var CRenderer:Array = new Array ();   // Cell Renderer of columns
            var HRenderer:Array = new Array ();   // Header Renderer of columns
            
            for (i = 0; i<DG.columns.length; i++)
            {
                if (i == Col1)
                {
                    Columns.push(DG.getColumnAt(Col2).headerText);
                    Widths.push(DG.getColumnAt(Col2).width);
                    Visibility.push(DG.getColumnAt(Col2).visible);
                    CRenderer.push(DG.getColumnAt(Col2).cellRenderer);
                    HRenderer.push(DG.getColumnAt(Col2).headerRenderer);
                }
                else if (i == Col2)
                {
                    Columns.push(DG.getColumnAt(Col1).headerText);
                    Widths.push(DG.getColumnAt(Col1).width);
                    Visibility.push(DG.getColumnAt(Col1).visible);
                    CRenderer.push(DG.getColumnAt(Col1).cellRenderer);
                    HRenderer.push(DG.getColumnAt(Col1).headerRenderer);
                }
                else
                {
                    Columns.push(DG.getColumnAt(i).headerText);
                    Widths.push(DG.getColumnAt(i).width);
                    Visibility.push(DG.getColumnAt(i).visible);
                    CRenderer.push(DG.getColumnAt(i).cellRenderer);
                    HRenderer.push(DG.getColumnAt(i).headerRenderer);
                }
            }
            
            // Remove everything from DataGrid
            DG.removeAllColumns();
            
            // Reset the widths
            for (i = 0; i < Columns.length; i++)
            {
                var DGC:DataGridColumn = new DataGridColumn(Columns*);
                DGC.width = Widths*;
                DGC.visible = Visibility*;
                DGC.cellRenderer = CRenderer*;
                DGC.headerRenderer = HRenderer*;
                DG.addColumn(DGC);
            }
            
            // Load DP
            DG.dataProvider = DP;
        }
        
        function BringToFront ()
        {
            var Parent = this.parent; // Parent of this 
            var Index = Parent.getChildIndex(Parent.getChildByName(this.name)); // Child Index of this
            
            // swap places of 'this' with child currently in front
            if (Index != Parent.numChildren-1)
                Parent.swapChildrenAt(Index, Parent.numChildren-1);
        }
    }
}
  1. Now in your fla, as you create your datagrid columns, set the headerRenderer:
    Column.headerRenderer = ColumnHeaderRenderer;

That’s it! Enjoy