19
Sep
07

Dragging rows between two different Flex DataGrid controls

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.


30 Responses to “Dragging rows between two different Flex DataGrid controls”


  1. 1 sm Sep 26th, 2007 at 7:53 am

    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. 2 sm Sep 26th, 2007 at 10:36 am

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

  3. 3 pria Nov 6th, 2007 at 2:31 pm

    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. 4 Petko Dec 5th, 2007 at 9:32 am

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

  5. 5 Thomas Jan 11th, 2008 at 2:22 pm

    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. 6 Arun Jan 21st, 2008 at 1:49 pm

    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. 7 Dante Jan 24th, 2008 at 11:34 am

    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. 8 Dante Jan 24th, 2008 at 11:46 am

    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. 9 Dante Jan 24th, 2008 at 11:49 am

    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. 10 Guillermo Feb 10th, 2008 at 11:41 am

    @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. 11 rhnkyr Feb 11th, 2008 at 10:45 am

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

  12. 12 Marlene Mar 11th, 2008 at 12:38 pm

    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. 13 Kyle May 12th, 2008 at 2:41 am

    Thanks! This was really helpful.

  14. 14 Shalini May 26th, 2008 at 5:11 am

    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. 15 peterd May 27th, 2008 at 12:38 am

    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. 16 Robert Marley Jul 4th, 2008 at 5:58 am

    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. 17 pex Aug 20th, 2008 at 11:33 am

    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. 18 Anonymous Sep 9th, 2008 at 11:35 pm

    thank you very mach!!

  19. 19 Shikhar Sep 12th, 2008 at 11:53 pm

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

  20. 20 Dave DuPlantis Oct 17th, 2008 at 1:34 pm

    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. 21 AK Oct 22nd, 2008 at 1:06 am

    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. 22 CAM Mar 24th, 2009 at 10:05 pm

    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. 23 Mike Mar 26th, 2009 at 12:42 pm

    @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. 24 ilya Apr 19th, 2009 at 12:28 pm

    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!

  25. 25 Rahul Joshi Apr 28th, 2009 at 11:16 pm

    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. 26 Jackson Barcellos Jun 2nd, 2009 at 12:32 pm

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

  27. 27 Peter deHaan Jun 3rd, 2009 at 7:42 pm

    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. 28 jack Jun 4th, 2009 at 11:22 pm

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

  29. 29 Peter deHaan Jun 5th, 2009 at 7:26 am

    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. 30 Hoaxan Jun 6th, 2009 at 5:40 am

    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.

Leave a Reply

This blog is terrible at eating HTML tags. If you plan on posting code/XML, please escape your "<" characters as "&lt;" and your ">" characters as "&gt;".




September 2007
M T W T F S S
« Aug   Oct »
 12
3456789
10111213141516
17181920212223
24252627282930

Badge Farm

  • Powered by Redoable 1.2
  • Cornify
  • Feeds burnt by Feedburner
  • Feed