Preventing Drag.Move click propagation on child element

3,463 views
Skip to first unread message

mkljun

unread,
Oct 18, 2012, 5:50:24 PM10/18/12
to mootool...@googlegroups.com
Hi,

I can't find the answer to this one. I have

<div id="parent"> <a href="http://www.mootools.net" id="child">Link</a></div>

I want element #parent to be draggable even if one clicks on a link and draggs it over.
But I don't want the click to be fired on #child element?

How do I do it?

I want to have something opposite to stopPropagation().

        new Drag.Move($("parent"), {
            container : $("body"), //limit the moves within the window
            onDrop: function(){           
                //do something
            },
            onComplete: function(event) {
               //prevent the child element to open
            }           
        });

Thanks for any suggestions,

m

Graham Warrender

unread,
Oct 18, 2012, 5:57:44 PM10/18/12
to mootool...@googlegroups.com
can you jsFiddle it, so i can take a look

Graham Warrender

unread,
Oct 18, 2012, 5:59:01 PM10/18/12
to mootool...@googlegroups.com
Apologies, i thought you had a problem with the js.. But it seems you haven't written the script yet
On 18 Oct 2012, at 22:50, mkljun <mkl...@gmail.com> wrote:

Arian Stolwijk

unread,
Oct 18, 2012, 6:35:32 PM10/18/12
to mootool...@googlegroups.com
There are two solutions:

1. In your #parent event listener, check the event.target element. event.target is the element that was actually clicked.
If that element matches your #child, then do nothing.

var child = $('child');
$('parent').addEvent('click', function(event){
    if (event.target == child) return;
    // other logic
});

2. Add an extra event listener to the #child and call event.stopPropagation(). This prevents the event to fire on parent elements.

$('child').addEvent('click', function(event){
    event.stopPropagation();
    // additional logic
});

In your case, with Drag, the first option is a bit complicated, so I guess you could try version 2.

mkljun

unread,
Oct 18, 2012, 7:13:37 PM10/18/12
to mootool...@googlegroups.com
Thank Graham and Arian,

Here's the jsFiddle http://jsfiddle.net/rand7/4/

If I click on the "Link" and drag the #parent around, the click gets fired on the #child and opens it.
Which is exactly what I don't want. If the #parent is moved around, I don't want open a new page.
I want to open the "Link" only of clicked and not when dragged.

If I understand stopPropagation, the second option Arian, does not prevent the click on the
#child. It prevents the click on all its ancestors.

While the second (I added return false) prevents the link to be clicked:

http://jsfiddle.net/2ubnr/

Any suggestions?

Thanks,

mkljun

Arian Stolwijk

unread,
Oct 18, 2012, 7:18:39 PM10/18/12
to mootool...@googlegroups.com
Not an answer, but return false; is an old event.preventDefault(). The latter is better because it tells you what it does.

mkljun

unread,
Oct 18, 2012, 7:42:16 PM10/18/12
to mootool...@googlegroups.com
I know Arian ...

How I understand it:
1. The click event is first on the #parent and the element gets moved around
    How does mootools get around first firing the click on the link? The #child is supposed to be on top of the #parent?
2. As soon as the move is over the click return to the #child and a new page opens up.
    And this is what I want to prevent. The return of the click event to the #child

new Drag.Move($('parent'), {
    container: $('container'),
    onDrop: function(){
      $('parent').setStyle('background', '#C17878');
    }
    onComplete: function(event){
        alert("s");
        // AND NOW PREVENT THE CLICK TO OPEN
    }           
})
;

Arian Stolwijk

unread,
Oct 18, 2012, 8:01:46 PM10/18/12
to mootool...@googlegroups.com
Ooh, euh, simply preventDefault on the child? http://jsfiddle.net/2ubnr/2/ Or maybe I don't understand the problem correctly...

mkljun

unread,
Oct 18, 2012, 9:05:41 PM10/18/12
to mootool...@googlegroups.com
But this way the link is not clickable anymore. If I move the #parent around is fine. But if I want just open the link I can't.

Maybe I did not explain myself well enough.

What I want is:
- if #child is clicked open the Link
- if #child is clicked and moved do not open the Link.

So basically when the #parent is moved and #child is a "handle" then do not open the Link.

Paul Saukas

unread,
Oct 18, 2012, 9:10:22 PM10/18/12
to mootool...@googlegroups.com
if you really need to do that then capture the click event on the mouse down on the child, stop it and fire it on the mouse up if it was not moved. 

A bit of a long way around but it would work.

 What I am most confused by is why the handle for your draggable needs to be a fully clickable surface. 
Can you not just have a spot on the handle that is ment to be a link and the rest just normal dead space ?  
If you could give us a jsFiddle showing what you are doing might we might be better able to understand the need. 



--Paul 
--
-Paul Saukas
"If you wish to change the world first start with yourself"

mkljun

unread,
Oct 22, 2012, 7:09:36 PM10/22/12
to mootool...@googlegroups.com
SOLVED

Thx to everyone for the answers.

Paul, I'm doing a desktop like application. The whole surface of a file (icon and name) needs to be draggable. Now there are two options:
- if an user moves the file around the page she probably did not mean to open it (even if clicked on the name and moved around)
- if an user just clicks on a name (which is an URL link) then she probably meant to open it.

I did not expect this behaviour but all users in testing (20) expected it to behave like I explained.

I though there is another easy way. I ended up using a flag (var moved = false;).

http://jsfiddle.net/2ubnr/7/

window.addEvent('domready', function(){
    var moved = false;   
    
    $("child").addEvents({
        click: function(){
            if (moved == false) {
               window.open('http://www.mootools.net');
            } else {
               moved = false;   
            }
        }
    });

    
    new Drag.Move($('parent'), {
        container: $('container'),      
        onDrop: function(element, droppable){

          $('parent').setStyle('background', '#C17878');
        },
        onComplete: function(){
          moved = true;
        }       
    });

Reply all
Reply to author
Forward
0 new messages