PDA

View Full Version : How to Reorder Datagrid Columns by Drag and Drop



EssenceLord
August 28th, 2008, 09:45 AM
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[i]);
DGC.width = Widths[i];
DGC.visible = Visibility[i];
DGC.cellRenderer = CRenderer[i];
DGC.headerRenderer = HRenderer[i];
DG.addColumn(DGC);
}

// Load DP
DG.dataProvider = DP;
}

function BringToFront ()
{
var Parent = this.parent; // Parent of this
var Index = Parent.getChildIndex(Parent.getChildByName(this.na me)); // Child Index of this

// swap places of 'this' with child currently in front
if (Index != Parent.numChildren-1)
Parent.swapChildrenAt(Index, Parent.numChildren-1);
}
}
}
3) Now in your fla, as you create your datagrid columns, set the headerRenderer:
Column.headerRenderer = ColumnHeaderRenderer;

That's it! Enjoy

EssenceLord
August 28th, 2008, 11:28 AM
*** an extra feature to this script I posted, you could add the following code to dispatch an Event for when a column swap occurs:

1) in the class file (*.as), add this import statement:

import flash.events.EventDispatcher;

2) in this same class file, at the end of the SwapGridColumns functions, add this code:

// Dispatch Event to notify of column swap
DG.dispatchEvent(new Event("swap"));


3) Now you can add an event listener for the swap
MyDatagrid.addEventListener("swap", myFunction);