views:

293

answers:

2

Hi,

I'm using Dojo.dnd to transfer items between to areas. The problem is: the items will snap into place once I drop them, but I'd like to have them stay where I drop them, but only for one area.

Here's a little code to explain this better:

  <div id="dropZone" class="dropZone">
    <div id="itemNodes"></div>
    <div id="targetZone" dojoType="dojo.dnd.Source"></div>
  </div>

"dropZone" is a DIV that contains two dojo.dnd.Source-areas, "itemNodes" (created programmatically) and "targetZone". Items (DIVs with images) should be dragged from a simple list out of "itemNodes" into "targetZone" and stay where they are dropped. As soon as they are dragged out of "targetZone" they should snap back to the list inside "itemNodes".

Here's the code I use to create the items:

  var nodelist = new dojo.dnd.Source("itemNodes");
  {Smarty-Loop}
    nodelist.insertNodes(false, ['<img class="dragItem" src="{$items->info.itemtext}" alt="{$items->info.itemtext}" border="0" />']);
  {/Smarty-Loop}

But this way I just have two lists of items, the items dropped into "targetZone" won't stay where I dropped them. I've tried a loop dojo.query(".dojoDndItem").forEach(function(node) to grab all items and change them to a "moveable"-type:

  • using dojo.dnd.move.constrainedMoveable will change the items so they can always be moved around (even in "itemNodes")
  • using dojo.dnd.move.boxConstrainedMoveable and defining the "box" to the borders of "targetZone" makes it possible to just move the items around inside "targetZone", but as soon as I drop them, I can't grab and move them back out. (Strange: dojo.connect(node, "onMoved" doesn't work here, the even won't fire, no matter what.)

So here's the question: is it possible to create two dnd.Sources where I can move items back and forth and let the items be "moveable" only in one of the sources?
Or is there a workaround like making the items moveable and if they're not dropped into "targetZone" they'll be moved back to the list in "itemNodes" automatically?

Once the page is submitted, I have to save the position of every item that has been placed into "targetZone". (The next step will be positioning the items inside "targetZone" on page load if the grid has already been filled before, but I'd be happy to just get the thing working in the first place.)

Any hint is appreciated.

Greetings, Select0r

A: 

There is no direct support for such features. It can be done with a custom code, e.g., by subclassing a Source and overriding its insertNodes().

Eugene Lazutkin
Too bad, but thanks anyways. I guess, I'll open another question as soon as I get stuck with a custom solution :)
Select0r
A: 

Here's a quick workaround to get this working:

I ended up using only one DIV which is a dojo.dnd.Source and contains the items that should be dropped into a "dropZone" and moved around in it while snapping back to the item-list when placed outside the dropZone.

All items are a dojo.dnd.move.parentConstrainedMoveable to make them movable in the originating DIV. Connecting to onMoveStop will give me the opportunity to decide whether the "drop" has occured in the dropZone or somewhere else.

  if (coordX >= (dropCoords.l + dropAreaX)  &&
      coordX <= (dropCoords.l + dropAreaX + dropAreaW) &&
      coordY >= (dropCoords.t + dropAreaY) &&
      coordY <= (dropCoords.t + dropAreaY + dropAreaH))
  {
     // OK!
  }
  else
  {
    // outside, snap back to list
  }

dropAreaX and dropAreaY contain the coordinates where the dropZone starts, dropAreaW and dropAreaH contain its width and height.

If "OK!", the items will be saved into an array, so I know which items have been dropped. Otherwise the item will be removed from that array (if it's in there) and the item will be placed back into the list (via CSS "left: 0"). The number of elements in the array will tell me how many elements are left in the list, so I can "stack" them in a loop using "top: numberOfElement * heightOfElement px").

There's more to it as I need the items coordinates written to hidden fields, but I guess this should get anybody who's working on a similar problem on the right track.

Select0r