Built-in Drag and Drop support in h-smile core
February 16, 2008
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"> <option>First<</option> <option>Second<</option> <option>Third<</option> </select> <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*/
}
select#destination
{
accept-drag: selector( select#source > option );
/* we accept only options from select#source*/
drop: append;
/* 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 */
{
background:blue; color:white;
opacity:0.5;
}
select:drop-target /* active drop target element(s) */
{
background: yellow;
/* 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
{
dragging: only-move;
}
select#source
{
accept-drag: selector( select#destination > option );
drop: append;
}
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.

It would be great if we could specify different “dragging” options for different destinations. I.e. if I drag to trash I would like to specify “only-move” value, but if I drag to different destination I want to have “only-copy” value. Is it possible?
Comment by Akatik — August 23, 2009 @ 6:24 am