The following example shows how you can use the dragEnabled, dropEnabled, and dragMoveEnabled properties with the Flex DataGrid control to copy and move rows between different data grids.

Full code after the jump.

View MXML

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2007/09/19/dragging-rows-between-two-different-flex-datagrid-controls/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="horizontal"
        verticalAlign="middle"
        backgroundColor="white">

    <mx:Array id="arr">
        <mx:Object colA="Item A.0" colB="Item B.0" colC="Item C.0" />
        <mx:Object colA="Item A.1" colB="Item B.1" colC="Item C.1" />
        <mx:Object colA="Item A.2" colB="Item B.2" colC="Item C.2" />
        <mx:Object colA="Item A.3" colB="Item B.3" colC="Item C.3" />
        <mx:Object colA="Item A.4" colB="Item B.4" colC="Item C.4" />
        <mx:Object colA="Item A.5" colB="Item B.5" colC="Item C.5" />
        <mx:Object colA="Item A.6" colB="Item B.6" colC="Item C.6" />
        <mx:Object colA="Item A.7" colB="Item B.7" colC="Item C.7" />
        <mx:Object colA="Item A.8" colB="Item B.8" colC="Item C.8" />
        <mx:Object colA="Item A.9" colB="Item B.9" colC="Item C.9" />
    </mx:Array>

    <mx:ApplicationControlBar dock="true">
        <mx:Form>
            <mx:FormItem label="DataGrid #1:"
                    direction="horizontal">
                <mx:CheckBox id="dg1_dragEnabled"
                        label="dragEnabled" />
                <mx:CheckBox id="dg1_dropEnabled"
                        label="dropEnabled" />
                <mx:CheckBox id="dg1_dragMoveEnabled"
                        label="dragMoveEnabled" />
            </mx:FormItem>
            <mx:FormItem label="DataGrid #2:"
                    direction="horizontal">
                <mx:CheckBox id="dg2_dragEnabled"
                        label="dragEnabled" />
                <mx:CheckBox id="dg2_dropEnabled"
                        label="dropEnabled" />
                <mx:CheckBox id="dg2_dragMoveEnabled"
                        label="dragMoveEnabled" />
            </mx:FormItem>
        </mx:Form>
    </mx:ApplicationControlBar>

    <mx:VBox width="50%">
        <mx:Label text="DataGrid #1" />
        <mx:DataGrid id="dataGrid1"
                width="100%"
                rowHeight="22"
                dataProvider="{arr}"
                dragEnabled="{dg1_dragEnabled.selected}"
                dragMoveEnabled="{dg1_dragMoveEnabled.selected}"
                dropEnabled="{dg1_dropEnabled.selected}"
                verticalScrollPolicy="on">
            <mx:columns>
                <mx:DataGridColumn dataField="colA"
                        headerText="Column A" />
                <mx:DataGridColumn dataField="colB"
                        headerText="Column B" />
                <mx:DataGridColumn dataField="colC"
                        headerText="Column C" />
            </mx:columns>
        </mx:DataGrid>
        <mx:Label text="{dataGrid1.dataProvider.length} items" />
    </mx:VBox>

    <mx:VBox width="50%">
        <mx:Label text="DataGrid #2" />
        <mx:DataGrid id="dataGrid2"
                width="100%"
                rowHeight="22"
                dataProvider="[]"
                dragEnabled="{dg2_dragEnabled.selected}"
                dragMoveEnabled="{dg2_dragMoveEnabled.selected}"
                dropEnabled="{dg2_dropEnabled.selected}"
                verticalScrollPolicy="on">
            <mx:columns>
                <mx:DataGridColumn dataField="colA"
                        headerText="Column A" />
                <mx:DataGridColumn dataField="colB"
                        headerText="Column B" />
                <mx:DataGridColumn dataField="colC"
                        headerText="Column C" />
            </mx:columns>
        </mx:DataGrid>
        <mx:Label text="{dataGrid2.dataProvider.length} items" />
    </mx:VBox>

</mx:Application>

View source is enabled in the following example.

 
Tagged with:
 
About The Author

Peter deHaan

Peter deHaan currently works for Adobe on the Flex SDK QA team. While not working on Flex, Flash, and ColdFusion applications, Peter enjoys making up bios and writing in 3rd person. Peter's rarely updated blog can be found at blogs.adobe.com/pdehaan/, actionscriptexamples.com, airexamples.com, and coldfusionexamples.com.

42 Responses to Dragging rows between two different Flex DataGrid controls

  1. sm says:

    Hi Peter,
    I have a new problem I am hoping you can find solution to. I wanted to create a datagrid with some scrollable columns and some columns without scroll. So, I created two datagrids with a horizontal gap of -1 so that they look like single grid. The problem I had was that when i clicked on a row in first datagrid it did not highlight the row in 2nd datagrid. So I did :
    BindingUtils.bindProperty(dg,”selectedIndex”,dg1,”selectedIndex”);
    BindingUtils.bindProperty(dg1,”selectedIndex”,dg,”selectedIndex”);
    i.e binded the selected index of each datagrid with the other. It seemed to run fine when I had a normal flash player installed but when a friend of mine had a debug version of flash player installed it gave stackoverflow error which I figured was due to the recursion created by above two statements. Is there any other way to do it?

  2. sm says:

    Was able to find a way to do it!linked it with a mouse event!

  3. pria says:

    I am trying to do the same thing “Dragging rows between two different Flex DataGrid controls” but in my case it is not dragging though. I have 2 buttons add and remove with which i want to achieve the same result.

    i have being working on it for almost 2 days not and havent been successful.
    any suggestions?

  4. Petko says:

    !linked it with a mouse event! is nice one mat

  5. Thomas says:

    hello, is it possible to drag onto a datagrid item, for example i have a datagrid with a list of all my playlists, and i would like to drag and drop a file from another datagrid into a playlist,

    drag and drop this music item onto the right playlist but not add it to the datagrid with saved playlists, just check onto wich item it has been dropped and add it to the right playlist file (xml)

    like you can do in iTunes actually.

    grtz thomas

  6. Arun says:

    hey!
    awesome examples! please keep up the good work.
    i am basically a .net guy and a flex newbie. i was breaking my head over a scenario. i was playing around with the drag drop features in flex. i have two datagrids one is a list of all available items and another is a list of my favorite items. i’ve got the regular drag drop to work well. the only problem i’ve is in the case if there are saved favorites which needs to be displayed in the second grid.

    if we use two separate xmls – ‘all’ and ‘saved’ to bind to the two grids then you are basically working with two separate sets of data and hence when you drag drop between the lists duplicates are created.

    how can i get this to work? any help/hint will be much appreciated :)

  7. Dante says:

    So I’m trying to allow a user to drag items from one list to the other. That’s not the problem. The problem that I’m having is preventing them from being able to hold down the Ctrl key to copy the items. Maybe there is something obvious that I’m missing but I have looked all over. The ListBase class is the class that handles the built in drag and drop features of Lists. It doesn’t appear that there is a mechanism to prevent the copy. I guesss I could override that function in my instance of the list… It seems like there should be an easier way!! Please help!
    Thanks.

  8. Dante says:

    Nevermind. I got it… I just took my own advise and overrode.. ? overridded?… overrid? anyway… I did this…

    I created a new Component based off of the List class and added the code in the script tags below.

    Hope this helps someone.

  9. Dante says:

    Let me try this one more time…

    Code between the script tags:

    import mx.events.DragEvent;
    import mx.managers.DragManager;
    override protected function dragDropHandler(event:DragEvent):void
    {
    	event.action = DragManager.MOVE;
    	DragManager.showFeedback(DragManager.MOVE);
    	super.dragDropHandler(event);
    }
    
  10. Guillermo says:

    @Thomas

    The solution for that is calculateDropIndex()
    example to highlight the drag-over-item:

    private function dragOverHandler(event:DragEvent):void {
    	var grid:DataGrid = DataGrid(event.currentTarget);
    	var index:int = grid.calculateDropIndex(event);
    	if (index == grid.dataProvider.length) {
    		grid.selectedIndex = -1;
    		return;
    	}
    	grid.selectedIndex = index;
    }
    
  11. rhnkyr says:

    Hi guys. How can I add those datagrids’ data into a arraycollection? It has to do it the both way. Thanx.

  12. Marlene says:

    Hello!

    I an developing an application with a datagrid, which is populated dynamically as a result of a HTTPService request, creating the columns and inserting the rows. This request is triggered by a drop event from a list.
    My idea was to remove columns from the datagrid, causing the data (column + rows) to refresh, by dragging a column “out” of the datagrid, but i don’t know if such thing is possible… Can anyone help me? Thank you!

  13. Kyle says:

    Thanks! This was really helpful.

  14. Shalini says:

    Hi Peter,am new to flex world and i find ur examples extremely helpful… i tried drag and drop but i have to get things done using and button… two grids with the buttons. Havent found a solution yet

  15. peterd says:

    Shalini,

    This is a little rough, but should work:

    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
            layout="vertical"
            verticalAlign="middle"
            backgroundColor="white">
    
        <mx:Script>
            <![CDATA[
                private function moveRight():void {
                    var item:Object = dataGrid1.selectedItem;
                    if (item) {
                        var idx:int = arrColl1.getItemIndex(item);
                        arrColl2.addItem(item);
                        arrColl1.removeItemAt(idx);
                    }
                }
    
                private function moveLeft():void {
                    var item:Object = dataGrid2.selectedItem;
                    if (item) {
                        var idx:int = arrColl2.getItemIndex(item);
                        arrColl1.addItem(item);
                        arrColl2.removeItemAt(idx);
                    }
                }
            ]]>
        </mx:Script>
    
        <mx:Array id="arr">
            <mx:Object label="One" />
            <mx:Object label="Two" />
            <mx:Object label="Three" />
            <mx:Object label="Four" />
            <mx:Object label="Five" />
        </mx:Array>
    
        <mx:ArrayCollection id="arrColl1" source="{arr}" />
        <mx:ArrayCollection id="arrColl2" />
    
        <mx:HBox>
            <mx:DataGrid id="dataGrid1"
                    dataProvider="{arrColl1}"
                    rowCount="5">
                <mx:columns>
                    <mx:DataGridColumn dataField="label" />
                </mx:columns>
            </mx:DataGrid>
            <mx:VBox height="100%" verticalAlign="middle">
                <mx:Button label="&gt;&gt;" click="moveRight();" />
                <mx:Button label="&lt;&lt;" click="moveLeft();" />
            </mx:VBox>
            <mx:DataGrid id="dataGrid2"
                    dataProvider="{arrColl2}"
                    rowCount="5">
                <mx:columns>
                    <mx:DataGridColumn dataField="label" />
                </mx:columns>
            </mx:DataGrid>
        </mx:HBox>
    
    </mx:Application>
    

    Peter

  16. Robert Marley says:

    Great examples, thanks for that.
    I have a query perhaps someone can help with:

    I have 2 list controls and am dragging from one to the other. This is all fine. The target list is configured to use an XMLList variable as it’s data provider.

    When the list only contains 1 dropped item, the dataprovider is EMPTY.

    When it contains > 1 item, the dataprovider contains the XML that I expect it would, namely the representation of the data that has been dropped.

    DataGrid shows the same issue.

    Any ideas?

    Thanks for any help,
    SG

  17. pex says:

    Hi,
    I’m looking for similar solution (dragging rows beetween two datagrids/lists) but based on native actionscript components (f.g. fl.controls.DataGrid)

    Is possible to use some components which supporting draggin events in native AS3?
    Have you got some?

    Thanks for any help

  18. Anonymous says:

    thank you very mach!!

  19. Shikhar says:

    Hi can I move scroll bar while I am dragging row in data grid.
    Please help me!
    Thanks
    Shikhar

  20. Dave DuPlantis says:

    To expand on Peter’s example (using buttons to move data from one list to another), you can do this with dynamic data. Note that in my code below, I actually have three lists, one on the left and two on the right (lists B and C), so I pass the list as a parameter, and I have a Left and Right button for list B (A to B, B to A) and another pair for list C (A to C, C to A).

    Also note that MoveOnlyList is the name of the component I created as in Dante’s example, so that items are never copied, always moved (my experience was that the destination list was the controller, so any list that received items had to be a MoveOnlyList).

    private function moveRight( destList:MoveOnlyList ):void {
        var item:Object = listOnTheLeft.selectedItem;
        if ( item ) {
            var acSource:ArrayCollection = ArrayCollection( listOnTheLeft.dataProvider );
            var idx:int = acSource.getItemIndex( item );
            var acDest:ArrayCollection;
            if ( destList.dataProvider == null ) {
                acDest = new ArrayCollection();
                destList.dataProvider = acDest;
            } else {
                acDest = ArrayCollection( destList.dataProvider );
            }
            acDest.addItem( item );
            acSource.removeItemAt( idx );
        }
    }
    
  21. AK says:

    I have a problem!
    I have a page in which I need to place two pairs of datagrids(total four) with one column in each datagrid.
    I need to drag an item from datagrid1 to datagrid2 ONLY and NOT to any other grid.
    Similarly from datagrid3 to datagrid4 ONLY.
    But when I tried, I can drag an item from datagrid1 to datagrid3, but interesting thing is that
    the data is not dropped into datagrid3 (instead a blank row is inserted), its getting lost from datagrid1.
    How to solve this issue?

  22. CAM says:

    AK, your column data needs to be named the same in both datagrids that are utilizing the drag and drop data. The data will then show up instead of a blank row.

  23. Mike says:

    @Dante
    - I wanted to express my gratitude as I also came across the problem of preventing users from making copies of the data while trying to reorder rows via the drag and drop feature. I tried what you had posted and it worked beautifully.

  24. ilya says:

    I’ve been looking for this everywhere but can’t find it.. I’m really hopping you can help.

    I’m dragging new items to existing datagrid and creating new columns.

    On item drop I’d like to know which column of existing datagrid I’m droping on.

    I can easily determine row I’m droping in dragDrop event: var dropLoc:int = dropTarget.calculateDropIndex(event); but how do I determine column?

    Any help or reference will be greatly appreciated!

    • Mike says:

      I am looking for the same solution – knowing which column was dropped on. Any luck in finding a solution?

  25. Rahul Joshi says:

    That is something what i was looking for. But can it be done that one is a normal DG and the other one is an advanced DG, both having different columns?

  26. link View source a problem, you send viewsource for mail?

  27. Peter deHaan says:

    Jackson Barcellos,

    All the code is in the post above (there aren’t any other files needed).
    But I did recreate the project in Flex Builder and repost the source and it should all work now.

    Sorry about that,
    Peter

  28. jack says:

    It seems that dragStart event does not work in the AdvancedDataGrid.

  29. Peter deHaan says:

    jack,

    Sorry, I’m not familiar with the AdvancedDataGrid control. You could try asking on the Adobe Flex forums (http://forums.adobe.com/community/flex/flex_general_discussion) or on the FlexCoders mailing list.

    Peter

  30. Hoaxan says:

    Hi Peter,

    I have two advanceddatagrid(grid1, grid2), where each grid has two different hierarchial data model having grouped columns. Since this reason i placed preventDefault() method to handle drop events manually.

    Need to allow dragging grid1 data to grid2 with necessary data change. On dragging from grid1, am using mouseDown event to track which element being selected for dragging, on the other hand while the dropping, how to find where the element being dropped in second grid.

  31. Naresh says:

    Hi,
    I need help from you .
    I have a list which have the drop and drop functionality.
    How can i calculate the drop index of list
    I tried with list.calculateDropIndex(ev);
    but iam getting length of arrayColl not drop index.
    ex:
    I have 5 row in a list I am going to drag the 4th row into the I st row
    Now i need the droped item row index.
    how can i find throw bu coding

    if anybody know abt this let me know.
    Thanks and regards,
    Naresh

    • Bogdan says:

      Naresh,
      try using (event.relatedObject as List).lastDropIndex;
      i had the same problem as you, and the line above seems to do the trick.

  32. Hector Sanchez says:

    Hi, Excellent blog

    Do you know how to DISABLE the drag and drop in a one simple column of the AdvancedDataGrid? just one not entire

  33. Roelof says:

    Great example Peter! I would like to inform you that we wrote an article about drag and drop from AdvancedDataGrid to Tree on our blog.

    Cheers

  34. Anthony says:

    This is awesome. I combined it with resizable drag panels and it works great so far !!!!

    http://blogs.adobe.com/flexdoc/2007/03/creating_resizable_and_draggab.html

  35. Reshma says:

    Hi,

    In this example, is there a way you can avoid highlighting the list border when we drag both in source list and destination list(when we drag over it)?

    Thanks!

  36. siddhartha says:

    Hi , here is a code that puts a datagrid value into a list , this is done pretty first time , so guys enjoy.

  37. Sorry did not notice the chevrons says:

    <?xml version=”1.0″ encoding=”utf-8″?>
    <mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml”
    creationComplete=”initApp();”>

    <mx:Script>
    <![CDATA[

    import mx.events.DragEvent;
    import mx.managers.DragManager;
    import mx.core.DragSource;
    import mx.collections.IList;
    import mx.collections.ArrayCollection;
    import mx.controls.Alert;

    private function initApp():void {

    destDG.dataProvider = new ArrayCollection([
    {label:"First", data:"1"},
    {label:"Second", data:"2"},
    {label:"Third", data:"3"},
    {label:"Fourth", data:"4"},
    ]);

    srcList.dataProvider = new ArrayCollection([]);

    }

    private function dragDropHandler(event:DragEvent):void {
    if (event.dragSource.hasFormat(“items”))
    {
    // Explicitly handle the dragDrop event.
    event.preventDefault();

    // Since you are explicitly handling the dragDrop event,
    // call hideDropFeedback(event) to have the drop target
    // hide the drop indicator.
    // The drop indicator is created
    // automatically for the list controls by the built-in
    // event handler for the dragOver event.
    event.currentTarget.hideDropFeedback(event);

    // Get drop target.
    var dropTarget:List =
    List(event.currentTarget);

    var itemsArray:Array =
    event.dragSource.dataForFormat(‘items’) as Array;
    var tempItem:Object =
    { label: itemsArray[0].Fund,
    data: itemsArray[0].AMC,
    data: itemsArray[0].Risk_Rating
    };

    // Get the drop location in the destination.
    var dropLoc:int = dropTarget.calculateDropIndex(event);

    IList(dropTarget.dataProvider).addItemAt(tempItem, dropLoc);
    }
    }
    ]]>
    </mx:Script>

    <mx:HBox>
    <mx:List id=”srcList”
    dragEnabled=”true”
    dropEnabled=”true”
    dragDrop=”dragDropHandler(event);”/>

    <mx:DataGrid id=”destDG”
    dragEnabled=”true”
    dragMoveEnabled=”true”>
    <mx:columns>
    <mx:DataGridColumn dataField=”label”/>
    <mx:DataGridColumn dataField=”data”/>
    <mx:DataGridColumn dataField=”date”/>
    </mx:columns>
    </mx:DataGrid>

    </mx:HBox>

    <mx:Button id=”b1″
    label=”Reset”
    click=”initApp()”
    />

    </mx:Application>

  38. Jay says:

    Hi Guys,

    How to pass details from one datagrid to another which is in another mxml component.

    Thanks in advance.

  39. Anonymous says:

    Hi

    Just wondering if there is a way to achieve the same functionality, but in Flash CS4 or 5 using AS3 (and possibly AIR)?

    Thanks

    Shaun Thomson

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

Anti-Spam Protection by WP-SpamFree