As far as I understand there are two distinct drag-n-drop mechanisms:
- Global drag-n-drop when objects are dragged from one window/application on desktop to another. In most cases this is very close to clipboard cut-n-paste but with some additional visualization.
- Window local drag-n-drop when objects are dragged inside single window/form. For example some shopping cart implementation.
I have added support of latter one to the h-smile core – local drag-n-drop of DOM elements. Details are here.
Consider following task:
For these two select elements:
<select id="source" size="5">
<select id="destination" size="5"></select>
we would like to provide ability to drag <option> elements from #source element to the #destination. In case of htmlayout or the Sciter (both are based on h-smile core) it is enough to write following:
select#source > option
dragging: only-move; /* we can only move options out here*/
accept-drag: selector( select#source > option );
/* we accept only options from select#source*/
/* order of items is not relevant,
always append dropped option */
and this is it – our users now are able to drag items from first <select> to second.
But what about one of main principles of good UI design – “discoverability”? User should have a visual clue while dragging: where and when he/she can drop dragged item. Following additional pseudo-classes will help us in this tasks:
option:moving /* moving (dragging ) option */
select:drop-target /* active drop target element(s) */
/* after D&D operation was started all active drop-targets
will be highlighted by yellow color */
select:drag-over /* drop target element under the dragged item.*/
outline: 1px solid green;
/* green outline to show that at current mouse position
dragged element can be dropped in this particular drop-target */
And that is all we need to enable drag-n-drop in our application.
Oh, forgot to add: what if we need to drag options in both directions – from #destination back to the #source? The same simple idea:
select#destination > option
accept-drag: selector( select#destination > option );
And one small piece left:
drop:recycle will declare element it is applied to (drop-target) as a “black hole” – all items dropped here will be deleted.