views:

2765

answers:

2

I have a Flex3 project with 2 HorizontalList controls; one of which has drag & drop enabled. Both controls will always have the same number of items, and are related... index 0 from the 1st control matches index 0 from the 2nd control, and so on.

Naturally, when using drag and drop to reorder the 2nd control, I want the items in the 1st control to reflect the same reordering. I think I can handle the actual updating of the control, but I'm having trouble finding the from and to indexes of the item that has been moved via drag & drop.

Using the dragDrop method on the control that allows drag and drop, and perusing the contents of event.currentTarget (instead of event.target because the docs say so) in the debugger shows a public property named selectedIndex which does seem to hold the from index, but I don't see any properties that will tell me the to index.

Am I overlooking the property? Do I have to infer it based on something else? Is there a better way to do this?

update: An acceptable solution might also be to iterate over the contents of the HorizontalList and save the internal index value to an array that could then be used to re-sort the dataProvider for the other list; but I can't figure out how to iterate over the list contents, so I'm just as stuck. Any help there?

Here's my code:

main.mxml:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application 
    xmlns:mx="http://www.adobe.com/2006/mxml" 
    xmlns:com="components.*"
    layout="absolute" 
>
    <mx:Script>
     <![CDATA[
      import mx.events.DragEvent;
      import mx.controls.Alert;
      import mx.collections.ArrayCollection;

      //these two variables are junk data to represent 
      //what we will get back from our data services...
      [Bindable] 
      private var btnData:ArrayCollection = new ArrayCollection(
       [
        {title:'title1', index:0},
        {title:'title2', index:1},
        {title:'title3', index:2},
        {title:'title4', index:3}
       ]
      );
      [Bindable] 
      private var chainData:ArrayCollection = new ArrayCollection(
       [
        {tmp:'testing 1'},
        {tmp:'testing 2'},
        {tmp:'testing 3'},
        {tmp:'testing 4'}
       ]
      );

      //handle button re-ordering
      private function handleBtnReorder(event:DragEvent):void{
       Alert.show(event.action.toString());
      }
     ]]>
    </mx:Script>

    <mx:HorizontalList
     id="ChainView"
     dataProvider="{chainData}"
     itemRenderer="components.ItemRenderers.ChainLinkRenderer"
     left="20"
     right="20"
     top="20"
     height="300"
     rowHeight="300"
     columnWidth="500"
     rollOverColor="#ffffff"
     selectionColor="#eeeeee"
    />

    <mx:HorizontalList 
     id="btnList" 
     dataProvider="{btnData}"
     dragEnabled="true" 
     dropEnabled="true"
     dragMoveEnabled="true"
     dragDrop="handleBtnReorder(event)"
     itemRenderer="components.ItemRenderers.BtnListRenderer"
     horizontalCenter="true"
     left="20"
     right="20"
     top="320"
     height="50"
     rowHeight="35"
     rollOverColor="#ffffff"
     selectionColor="#ffffff"
    />

</mx:Application>

The Alert.show(...) isn't there to show anything useful, I've set a breakpoint on that line so that I can inspect the event argument.

I don't think the custom itemRenderer's are important (there's not much code to them, yet), so I'll leave them out for brevity's sake. If you think they are important, let me know and I'll edit them in here.

+2  A: 

It turns out the solution was to switch from using the dragDrop event to the dragComplete event; at which point, the binded dataProvider has been updated to reflect the reordering.

Adam Tuttle
A: 

Thats why the Model Locator pattern is made for!

You must move your dataProvider to a singleton class (Model for instance) than your item renderers can easily access to it. There is no point that your item has the property Index since its already given by a [ArrayCollection].getItemIndex(..)

eBuildy