.. _pages/desktop/ui_dragdrop#drag_&_drop: Drag & Drop *********** Drag & Drop is one of the essential technologies in today's applications. An operation must have a starting point (e.g. where the pointer was tapped), may have any number of intermediate steps (widgets that the pointer moves over during a drag), and must either have an end point (the widget above which the pointer was released), or be canceled. qooxdoo comes with a powerful event-based layer which supports drag&drop with full data exchange capabilities. Every widget can be configured to cooperate with drag&drop be it as sender (draggable), receiver (droppable) or both. A sender (drag target) can send data to any receiver (drop target). You may like to see an example first: * `Drag&Drop for Lists `_ .. _pages/desktop/ui_dragdrop#basics: Basics ====== To enable Drag & Drop the properties `draggable `_ and `droppable `_ must be enabled on the specific widgets. For list type sources or targets it's often enough to make the top-level widget drag- or droppable e.g. the list instead of the list items. :: var dragTarget = new qx.ui.form.List(); dragTarget.setDraggable(true); var dropTarget = new qx.ui.form.List(); dropTarget.setDroppable(true); The basic drag&drop should start working with these properties enabled, but it will show the no-drop cursor over all potential targets. To fix this one needs to register actions (and optionally data types) supported by the drag target. This can be done during the ``dragstart`` event which is fired on the drag target: :: dragTarget.addListener("dragstart", function(e) { e.addAction("move"); }); The drop target can then add a listener to react for the ``drop`` event. :: dropTarget.addListener("drop", function(e) { alert(e.getRelatedTarget()); }); The listener now shows an alert box which should present the identification ID (classname + hash code) of the drag target. Theoretically this could already be used to transfer data from A to B. .. _pages/desktop/ui_dragdrop#data_handling: Data Handling ============= qooxdoo also supports advanced data handling in drag&drop sessions. The basic idea is to register the supported drag data types and then let the drop target choose which one to handle (if any at all). To register some types write a listener for ``dragstart``: :: source.addListener("dragstart", function(e) { e.addAction("move"); e.addType("qx/list-items"); e.addType("html/list"); }); This is basically only the registration for the types which could theoretically be delivered to the target. The IDs used are just strings. They have no special meaning. They could be identical to typical mime-types like ``text/plain`` but there is no need for this. The preparation of the data (if not directly available) is done lazily by the ``droprequest`` event which will explained later. The next step is to let the target work with the incoming data. The following code block appends all the dropped children to the end of the list. :: target.addListener("drop", function(e) { var items = e.getData("qx/list-items"); for (var i=0, l=items.length; i