How to add drag and drop support to datagrids
April 19th, 2009 in Flex | 4 CommentsIn this tutorial, we are going to see how we can let the user drag and drop items between two datagrids. We will use datagrid controls that include built-in support for the drag-and-drop operation.
1. Before continuing to read, view the demo to see what we are going to do and then create a new flex project named DragDropDatagrid.
2. Open the main application so we can begin adding our code.
First we are going to build the structure of the application by adding all the components that we need. To do so follow the following structure :

For now your code should look something like this :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Style>
Panel{
paddingTop : 20px;
paddingRight : 20px;
paddingBottom : 20px;
paddingLeft : 20px;
}
</mx:Style>
<mx:Panel title="Select your activities" horizontalAlign="center">
<mx:HBox>
<mx:DataGrid width="450" height="400">
</mx:DataGrid>
<mx:Spacer width="20"/>
<mx:DataGrid width="175" height="400">
</mx:DataGrid>
</mx:HBox>
<mx:Button label="Validate"/>
</mx:Panel>
</mx:Application>
3. Next open a script tag and declare a Bindable variable typed as an ArrayCollection to store the datas related to the activities.
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
private var datas:ArrayCollection = new ArrayCollection([
{name:"Athletics",date:"All week 9.am - 11.am",icon:"athletics.jpg"},
{name:"Baseball",date:"Monday & Friday 8.pm - 11.pm",icon:"baseball.jpg"},
{name:"Basketball",date:"Wednesday & Thursday 3.am - 5.am",icon:"basketball.jpg"},
{name:"Judo",date:"Thursday 6.am - 8.am",icon:"judo.jpg"},
{name:"Soccer",date:"Tuesday & Friday 8.am - 10.am",icon:"soccer.jpg"},
{name:"Swimming",date:"All week 9.am - 11.am ",icon:"swimming.jpg"},
{name:"Tennis",date:"Wednesday & Friday 4.pm - 6.pm",icon:"tennis.jpg"}
]);
]]>
</mx:Script>
4. Set the dataprovider of the left datagrid to this variable.
For this datagrid, we want to display all the informations about each activity. So we have 3 columns, one for the icon, one for the name and the last one for the schedule.
The column for the icon uses an inline itemrenderer to diplay the image that is stored in the assets folder.
<mx:DataGrid dataProvider="{datas}" width="450" height="400">
<mx:columns>
<mx:DataGridColumn headerText="" dataField="icon" width="60">
<mx:itemRenderer>
<mx:Component>
<mx:VBox height="60" horizontalAlign="center">
<mx:Image source="assets/{data.icon}"/>
</mx:VBox>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
<mx:DataGridColumn headerText="Available Activities" dataField="name" width="150"/>
<mx:DataGridColumn headerText="Schedule" dataField="date"/>
</mx:columns>
</mx:DataGrid>
6. And now to fulfill the goal of this tutorial, we need to allow two-way drag-and-drop between the 2 datagrids.
The Datagrid control as well as HorizontalList, List, Menu, PrintDataGrid, TileList, and Tree controls have dragEnabled and dropEnabled properties.
So for each of our 2 datagrids we set these properties to true.
Also we set the dragMoveEnabled property to true so that the item move from one datagrid to the other.
<mx:DataGrid dataProvider="{datas}" width="450" height="400"
dragEnabled="true" dragMoveEnabled="true" dropEnabled="true">
<mx:columns>
<mx:DataGridColumn headerText="" dataField="icon" width="60">
<mx:itemRenderer>
<mx:Component>
<mx:VBox height="60" horizontalAlign="center">
<mx:Image source="assets/{data.icon}"/>
</mx:VBox>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
<mx:DataGridColumn headerText="Available Activities" dataField="name" width="150"/>
<mx:DataGridColumn headerText="Schedule" dataField="date"/>
</mx:columns>
</mx:DataGrid>
<mx:DataGrid width="175" height="400"
dragEnabled="true" dragMoveEnabled="true" dropEnabled="true" >
<mx:columns>
<mx:DataGridColumn headerText="Selected Activities" dataField="label"/>
</mx:columns>
</mx:DataGrid>
7. Also we allow the user to drag and drop simultaneously several activities. (To select multiple items at once, the user has to hold down the Shift key on the keyboard while clicking on an item)
<mx:DataGrid dataProvider="{datas}" width="450" height="400"
dragEnabled="true" dragMoveEnabled="true" dropEnabled="true"
allowMultipleSelection="true">
8. For the button we let you continue on your own to see what function you can create. In our case we just diplay an Alert message when the button is clicked.
9. The final code is beneath. Run the application.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Style>
Panel{
paddingTop : 20px;
paddingRight : 20px;
paddingBottom : 20px;
paddingLeft : 20px;
}
</mx:Style>
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.collections.ArrayCollection;
[Bindable]
private var datas:ArrayCollection = new ArrayCollection([
{name:"Athletics",date:"All week 9.am - 11.am",icon:"athletics.jpg"},
{name:"Baseball",date:"Monday & Friday 8.pm - 11.pm",icon:"baseball.jpg"},
{name:"Basketball",date:"Wednesday & Thursday 3.am - 5.am",icon:"basketball.jpg"},
{name:"Judo",date:"Thursday 6.am - 8.am",icon:"judo.jpg"},
{name:"Soccer",date:"Tuesday & Friday 8.am - 10.am",icon:"soccer.jpg"},
{name:"Swimming",date:"All week 9.am - 11.am ",icon:"swimming.jpg"},
{name:"Tennis",date:"Wednesday & Friday 4.pm - 6.pm",icon:"tennis.jpg"}
]);
private function validateSelection():void{
Alert.show("Function not implemented here","To do ...");
}
]]>
</mx:Script>
<mx:Panel title="Select your activities" horizontalAlign="center">
<mx:HBox>
<mx:DataGrid dataProvider="{datas}" width="450" height="400"
dragEnabled="true" dragMoveEnabled="true" dropEnabled="true"
allowMultipleSelection="true">
<mx:columns>
<mx:DataGridColumn headerText="" dataField="icon" width="60">
<mx:itemRenderer>
<mx:Component>
<mx:VBox height="60" horizontalAlign="center">
<mx:Image source="assets/{data.icon}"/>
</mx:VBox>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
<mx:DataGridColumn headerText="Available Activities" dataField="name" width="150"/>
<mx:DataGridColumn headerText="Schedule" dataField="date"/>
</mx:columns>
</mx:DataGrid>
<mx:Spacer width="20"/>
<mx:DataGrid width="175" height="400"
dragEnabled="true" dragMoveEnabled="true" dropEnabled="true">
<mx:columns>
<mx:DataGridColumn headerText="Selected Activities" dataField="name"/>
</mx:columns>
</mx:DataGrid>
</mx:HBox>
<mx:Button label="Validate" click="validateSelection()"/>
</mx:Panel>
</mx:Application>

Jul 21st, 2009
Great tutorial ,
I’ve been wondering how to access the data stored in the destination grid for further processing. Could you please give me a hint.
Regards,
Ben
Apr 30th, 2010
Greaaat
May 7th, 2010
Hi,
I have been looking to drag and drop buttons from a list onto a canvas. But when i do that, the buttons just vanish from the list. I just want to copy the buttons and move them to the canvas. How do i do it?
Jun 7th, 2010
Hi,
I wanna drag and drop buttons from a list to a canvas. Imagine u have a set of images that u can drag and drop onto a canvas. In place of these images i want buttons. I tried but when i drag and drop, the button disappears from the list. Please let me know how i can just replicate the button in the list onto the canvas when i drag and drop. Please check my code below:
public function dragButton(e:MouseEvent):void
{
if(e.buttonDown)
{
var button:Button = e.currentTarget as Button;
var buttonProxy:Button = new Button();
buttonProxy.width = button.width;
buttonProxy.height = button.height;
var dragSource:DragSource = new DragSource();
dragSource.addData(button, ‘button’);
DragManager.doDrag(button, dragSource, e);
}
}
public function dragEnter(event:DragEvent): void
{
var target:Canvas = event.currentTarget as Canvas;
if (event.dragSource.hasFormat(‘button’)/* && target.getChildren().length == 0 */)
{
DragManager.acceptDragDrop(target);
DragManager.showFeedback(DragManager.COPY);
}
}
public function dragDrop(event:DragEvent): void
{
var target:Canvas = event.currentTarget as Canvas;
var button:Button = event.dragSource.dataForFormat(‘button’) as Button;
button.x = event.localX;
button.y = event.localY;
networkStage.addChild(button);
}