From: DL on

Rumor has it that some implementation of HTML5's drag and drop is very
clumsy. Let's ignore that for now.

Say, we have we have 5 or 6 DIV (s) in a page or 5 or 6 or more TD in
a TR, what might be an elegant way to drag the DIV (s) or TD (s) to re-
arrange the DIV (s) or TD (s)?

Then, maybe, we could consider to drag a DIV to a trash bin for
removal as well ...

Primarily browsers to be supported at this point is IE7 and FF3.5.

Thanks.
From: Garrett Smith on
DL wrote:
> Rumor has it that some implementation of HTML5's drag and drop is very
> clumsy. Let's ignore that for now.
>

OK. It would be worthwhile to hear some discussion the shortcomings. We
can proceed without, that, though.

> Say, we have we have 5 or 6 DIV (s) in a page or 5 or 6 or more TD in
> a TR, what might be an elegant way to drag the DIV (s) or TD (s) to re-
> arrange the DIV (s) or TD (s)?
>

DIV can have left/top style value applied. TD cannot.

A general approach is:
Add a callback for mousedown on document.
Add a callback for mousemove on document
Add a callback for mouseup on document.

mousedown: if the element the user clicked or one of its ancestors is
something that can be dragged, set the activeDragObject to that.

mousemove:
1) if there is no activeDragObject, return.
2) move the activeDragObject by the difference from where mousedown
occurred and the cursor position. The cursor position
is e.pageX[1] or (e.clientX[2] + scroll offsets[3][4]).

mouseup: set activeDragObject = null.

That is basically the idea to use. IFRAMEs can make things harder.

A general outline might look like:-

function mousedownHandler(ev) {
var target = getEventTarget(ev),
draggable = findDraggableAncestor(target);
if(draggable) {
activeDragObject = draggable;
}
}

function mousemoveHandler(ev) {
if(!activeDragObject) return;
var coords = getEventCoords(ev),
ePageX = eventCoords.x, ePageY = eventCoords.y,
distX = ePageX - mousedownX,
distY = ePageY - mousedownY;
}

function mouseupHandler(ev) {
activeDragObject = null;
}

function findDraggableAncestor(target) {
var closestAncestor = document.body;
for(var x = target; x !== closestAncestor; x = x.parentNode) {
if(matchesDragCriteria(x)) {
return x;
}
return null;
}

function getEventCoords(ev) {
var coords = { x : 0, y : 0 };
// find e.pageX/e.pageY or
// (e.clientX/e.clientY + scroll offsets);

return coords;
}

> Then, maybe, we could consider to drag a DIV to a trash bin for
> removal as well ...
>

Is the trash bin on the same page?

> Primarily browsers to be supported at this point is IE7 and FF3.5.
>

Why so limited? There is no reason this could not work in older versions
of Firefox, Opera, versions of Webkit. iPhone, too, with very little
extra work.

Blackberry - I need to investigate further, for latest touch screens.
Palm Pre - I think it is not possible.

[1]https://developer.mozilla.org/En/DOM/Event.pageX
[2]http://msdn.microsoft.com/en-us/library/ms533567%28VS.85%29.aspx
[3]http://msdn.microsoft.com/en-us/library/ms534617%28VS.85%29.aspx
[4]https://developer.mozilla.org/en/DOM/window.pageXOffset
--
Garrett
comp.lang.javascript FAQ: http://jibbering.com/faq/
From: Don84 on
On Oct 10, 1:20 am, Garrett Smith <dhtmlkitc...(a)gmail.com> wrote:
> DL wrote:
> > Rumor has it that some implementation of HTML5's drag and drop is very
> > clumsy.  Let's ignore that for now.
>
> OK. It would be worthwhile to hear some discussion the shortcomings. We
> can proceed without, that, though.
>
> > Say, we have we have 5 or 6 DIV (s) in a page or 5 or 6 or more TD in
> > a TR, what might be an elegant way to drag the DIV (s) or TD (s) to re-
> > arrange the DIV (s) or TD (s)?
>
> DIV can have left/top style value applied. TD cannot.
>
> A general approach is:
>    Add a callback for mousedown on document.
>    Add a callback for mousemove on document
>    Add a callback for mouseup on document.
>
> mousedown: if the element the user clicked or one of its ancestors is
> something that can be dragged, set the activeDragObject to that.
>
> mousemove:
> 1) if there is no activeDragObject, return.
> 2) move the activeDragObject by the difference from where mousedown
> occurred and the cursor position. The cursor position
> is e.pageX[1] or (e.clientX[2] + scroll offsets[3][4]).
>
> mouseup: set activeDragObject = null.
>
> That is basically the idea to use. IFRAMEs can make things harder.
>
> A general outline might look like:-
>
> function mousedownHandler(ev) {
>    var target = getEventTarget(ev),
>        draggable = findDraggableAncestor(target);
>    if(draggable) {
>      activeDragObject = draggable;
>    }
>
> }
>
> function mousemoveHandler(ev) {
>    if(!activeDragObject) return;
>    var coords = getEventCoords(ev),
>        ePageX = eventCoords.x, ePageY = eventCoords.y,
>        distX = ePageX - mousedownX,
>        distY = ePageY - mousedownY;
>
> }
>
> function mouseupHandler(ev) {
>   activeDragObject = null;
>
> }
>
> function findDraggableAncestor(target) {
>    var closestAncestor = document.body;
>    for(var x = target; x !== closestAncestor; x = x.parentNode) {
>      if(matchesDragCriteria(x)) {
>        return x;
>      }
>    return null;
>
> }
>
> function getEventCoords(ev) {
>    var coords = { x : 0, y : 0 };
>    // find e.pageX/e.pageY or
>    // (e.clientX/e.clientY + scroll offsets);
>
>    return coords;
>
> }
> > Then, maybe, we could consider to drag a DIV to a trash bin for
> > removal as well ...
>
> Is the trash bin on the same page?
>
> > Primarily browsers to be supported at this point is IE7 and FF3.5.
>
> Why so limited? There is no reason this could not work in older versions
> of Firefox, Opera, versions of Webkit. iPhone, too, with very little
> extra work.
>
> Blackberry - I need to investigate further, for latest touch screens.
> Palm Pre - I think it is not possible.
>
> [1]https://developer.mozilla.org/En/DOM/Event.pageX
> [2]http://msdn.microsoft.com/en-us/library/ms533567%28VS.85%29.aspx
> [3]http://msdn.microsoft.com/en-us/library/ms534617%28VS.85%29.aspx
> [4]https://developer.mozilla.org/en/DOM/window.pageXOffset
> --
> Garrett
> comp.lang.javascript FAQ:http://jibbering.com/faq/

Excellent. Before I start to "play" with it, let me say, sorry I
haven't clearly stated that all the actions would take place on the
same page, but I guess the vars of your sample code of ePageX and
ePageY can be anything really, or ePageX and ePageY won't hurt
neither, yes?

Also, on
"
Add a callback for mousedown on document.
Add a callback for mousemove on document
"
would it be like <div id="div1" onmousedown="jsdoDownFN();"
onmousemove="jsdoMoveFN();" .../> ?
Is that what you meant by "callback"?

Many thanks.
From: Garrett Smith on
Don84 wrote:
> On Oct 10, 1:20 am, Garrett Smith <dhtmlkitc...(a)gmail.com> wrote:
>> DL wrote:
>>> Rumor has it that some implementation of HTML5's drag and drop is very
>>> clumsy. Let's ignore that for now.
>> OK. It would be worthwhile to hear some discussion the shortcomings. We
>> can proceed without, that, though.
>>
>>> Say, we have we have 5 or 6 DIV (s) in a page or 5 or 6 or more TD in
>>> a TR, what might be an elegant way to drag the DIV (s) or TD (s) to re-
>>> arrange the DIV (s) or TD (s)?
>> DIV can have left/top style value applied. TD cannot.
>>
>> A general approach is:
>> Add a callback for mousedown on document.
>> Add a callback for mousemove on document
>> Add a callback for mouseup on document.
>>
>> mousedown: if the element the user clicked or one of its ancestors is
>> something that can be dragged, set the activeDragObject to that.
>>
>> mousemove:
>> 1) if there is no activeDragObject, return.
>> 2) move the activeDragObject by the difference from where mousedown
>> occurred and the cursor position. The cursor position
>> is e.pageX[1] or (e.clientX[2] + scroll offsets[3][4]).
>>
>> mouseup: set activeDragObject = null.
>>
>> That is basically the idea to use. IFRAMEs can make things harder.
>>
>> A general outline might look like:-
>>
>> function mousedownHandler(ev) {
>> var target = getEventTarget(ev),
>> draggable = findDraggableAncestor(target);
>> if(draggable) {
>> activeDragObject = draggable;
>> }
>>
>> }
>>
>> function mousemoveHandler(ev) {
>> if(!activeDragObject) return;
>> var coords = getEventCoords(ev),
>> ePageX = eventCoords.x, ePageY = eventCoords.y,
>> distX = ePageX - mousedownX,
>> distY = ePageY - mousedownY;
>>
>> }
>>
>> function mouseupHandler(ev) {
>> activeDragObject = null;
>>
>> }
>>
>> function findDraggableAncestor(target) {
>> var closestAncestor = document.body;
>> for(var x = target; x !== closestAncestor; x = x.parentNode) {
>> if(matchesDragCriteria(x)) {
>> return x;
>> }
>> return null;
>>
>> }
>>
>> function getEventCoords(ev) {
>> var coords = { x : 0, y : 0 };
>> // find e.pageX/e.pageY or
>> // (e.clientX/e.clientY + scroll offsets);
>>
>> return coords;
>>
>> }
>>> Then, maybe, we could consider to drag a DIV to a trash bin for
>>> removal as well ...
>> Is the trash bin on the same page?
>>
>>> Primarily browsers to be supported at this point is IE7 and FF3.5.
>> Why so limited? There is no reason this could not work in older versions
>> of Firefox, Opera, versions of Webkit. iPhone, too, with very little
>> extra work.
>>
>> Blackberry - I need to investigate further, for latest touch screens.
>> Palm Pre - I think it is not possible.
>>
>> [1]https://developer.mozilla.org/En/DOM/Event.pageX
>> [2]http://msdn.microsoft.com/en-us/library/ms533567%28VS.85%29.aspx
>> [3]http://msdn.microsoft.com/en-us/library/ms534617%28VS.85%29.aspx
>> [4]https://developer.mozilla.org/en/DOM/window.pageXOffset
>> --
>> Garrett
>> comp.lang.javascript FAQ:http://jibbering.com/faq/
>

(It would be good if you could reply inline-style, trimming/removing
signatures or other things that don't matter anymore)

> Excellent. Before I start to "play" with it, let me say, sorry I
> haven't clearly stated that all the actions would take place on the
> same page, but I guess the vars of your sample code of ePageX and
> ePageY can be anything really, or ePageX and ePageY won't hurt
> neither, yes?
>

First let me say that the example is non-functional. It was given to
outline the process of drag 'n drop.

In mousemomveHandlerm variables ePageX and ePageY represent the current
cursor position. In mousemove, the activeDragObject will move left by
the amount the cursor has moved. That is: (ePageX - mousedownX).

So, if the mousedown event happened at {x:10, y:10}, we can say that
mousedownX = 10.

When mousemove fires, say for example, the cursor happens to be at
(x:20, y:30}, the difference in |x| is (20 - 10). This means the div
new position will add 10 (10px) to the current position.

TO avoid re-parsing the style properties of the draggable object, an
object can be used to represent the div. THe object can have x and y
properties that get updated a moveToX and moveToY methods. This can be
added after you get a basic, working example.

> Also, on
> "
> Add a callback for mousedown on document.
> Add a callback for mousemove on document
> "
> would it be like <div id="div1" onmousedown="jsdoDownFN();"
> onmousemove="jsdoMoveFN();" .../> ?
> Is that what you meant by "callback"?

No, the events are added on document.

document.onmousedown = mousedownHandler;

function mousedownHandler(ev) {
var target = getEventTarget(ev);
// ...
}

Function getEventTarget will find the ev.target or event.srcElement,
depending on the browser event model.

If that target is something that the program is interested in dragging,
set the activeDragObject to that.
--
Garrett
comp.lang.javascript FAQ: http://jibbering.com/faq/
From: Don84 on
> ...
>
....
>
> Function getEventTarget will find the ev.target or event.srcElement,
> depending on the browser event model.
>
> If that target is something that the program is interested in dragging,
> set the activeDragObject to that.

It looks like I didn't know how to implement the getEventTarget
function properly. The code below is not working. The getEventTarget
function is at the bottom.

Many thanks.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://
www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>"flowing" objects </title>
<script type="text/javascript">
function addDot() {
var div = document.createElement("div");
if (div)
{

div.style.position = "absolute";
div.style.left = "100";
div.style.top = "150";
div.style.width = "20px";
div.style.height = "20px";
div.style.backgroundColor = "red";

document.body.appendChild(div);

}
}

// drap and drop to move DIV, credit of Garrett Smith

function mousedownHandler(ev) {
var target = getEventTarget(ev),draggable = findDraggableAncestor
(target);
if(draggable) {
activeDragObject = draggable;
}
}
document.onmousedown = mousedownHandler;

function mousemoveHandler(ev) {
if(!activeDragObject) return;
var coords = getEventCoords(ev), ePageX = eventCoords.x, ePageY =
eventCoords.y,
distX = ePageX - mousedownX,
distY = ePageY - mousedownY;
}
document.onmousemove = mousemoveHandler;

function mouseupHandler(ev) {
activeDragObject = null;
}
document.onmouseup = mouseupHandler;

function findDraggableAncestor(target) {
var closestAncestor = document.body;
for(var x = target; x !== closestAncestor; x = x.parentNode) {
if(matchesDragCriteria(x)) {
return x;
}
return null;
}

function getEventCoords(ev) {
// var coords = { x : 0, y : 0 };
var coords = { x : 100, y : 150 };
// find e.pageX/e.pageY or
// (e.clientX/e.clientY + scroll offsets);
return coords;
}

function getEventTarget(ev) {
var ev.target = div;
// var target = div;
activeDragObject = div;
}

</script>

</head>
<body onload="addDot()">
<!--h1>Multi-dimensional view of data sets</h1-->
</body>
</html>