I have two DataGrids, the "menu" and the "receipt".  I want to be able to:

1) Add items to the receipt by dragging from the menu
2) Remove items from the receipt by dragging back to the menu

With the following constraints:

a) The menu should never change
b) A receipt can never contain more than one of a given item

This seems like it should be really straightforward, but I can't figure it out. 
 What would 
you suggest?  What I think should work (but doesn't) is the following:

Set "dragEnabled" and "dropEnabled" to "true" on both the menu and receipt 
DataGrids.  
This accomplishes requirement (1) above, but fails all the other.

Next, set "dragMoveEnabled" on the receipt.  This accomplishes requirements (1) 
and (2) 
above (ie, dragging from the menu to the receipt correctly adds it to the 
receipt without 
modifying the menu, dragging from the receipt correctly removes it, and 
dragging from 
the receipt to itself does nothing), but fails the two constraints (nothing 
prevents adding 
the same item to the receipt multiple times, and items dragged from the receipt 
to the 
menu modify the menu).

So, we're most of the way there with only a couple changes.  But I can't find 
any way to 
enforce these constraints.  Some options I've tried/considered for the first 
constraint:

i) Override whatever function on the menu actually does the "adding" to simply 
make it do 
nothing.  Unfortunately, it appears that the "add" code is actually some secret 
part of the 
DataGrid itself, and can't be overridden.  Overriding "dragDrop" doesn't do it, 
because it's 
added after "dragDrop" actually runs.

2) Override "dragDrop" on the menu to remove the item right after it's added.  
Unfortunately, "dragDrop" runs *before* the item has been added, so it can't 
remove what 
doesn't yet exist.

3) Override "dragComplete" on both the receipt and the menu to determine if the 
item is 
being added to the menu, and if so remove it.  However, the "dragEvent" passed 
in to 
"dragComplete" doesn't seem to have any awareness of the drop target -- 
"currentTarget" 
and "dragInitiator" both point to the *source* of the drag (ie, the receipt) 
not the 
*destination* (the menu).  Thus it has no way of knowing if we're dragging from 
a receipt 
to the menu, or between receipts.

4) Skip all this drag/drop junk entirely and add a listener to the menu's 
DataProvider that 
simply watches for any ADD CollectionEvent and immediately removes it.  But 
this 
complicates actually adding things to the menu via other means (the menu can be 
modified, just not by the drag/drop).

The best I can come up with is overriding "dragDrop" on the menu to set some 
sort of 
global variable saying "the last drop operation went to me, at location X".  
Then override 
"dragComplete" on both menu and receipt to check "if the last drop operation 
went to the 
menu, erase whatever was added from location X".

Alternatively, override the menu's "dragDrop" to set a global "please delete 
whatever was 
added" variable, and then check this in the CollectionEvent listener -- if set, 
delete any 
additions and clear the variable.

But ug, those are pretty nasty.  Surely there must be a better way?


As for the second constraint (a receipt can contain only one of a given item), 
I'm not even 
sure where to start.  I considered overriding "dragEnter" to simply refuse the 
drag/drop 
operation if the receipt already contained the item, but I couldn't get 
anything to work on 
that, so I'll focus on the first constraint first.

Any suggestions?  Thanks!

-david

Reply via email to