Aleks
Aleks

Reputation: 5854

Parent div obstructs focus of its child

I'm trying to make a simple plugin to be able to make a div draggable. Of course a div can have a content inside (typically a form) and it should be dragged with it.

Here is a prototype: http://jsfiddle.net/Xcb8d/539/

The problem is that the texbox inside this div never gets focus, so I cannot type in it:

<div id="draggable-element">Drag me!
<form>
    <input type="text" style="width:50px;"/>
    <button>ok</button><br><br>
    <input type="checkbox">check it</input>
 </form>
</div>

As you can see, this does not happen to other elements on the form. Checkbox can be regularily used, as well as the button.

In addition, I would like only the grey coloured area to be draggable, and not the inner elements. On this example, you can place the mouse cursor fully inside the textbox and start the drag of the whole parent div.

Upvotes: 2

Views: 204

Answers (3)

Tiago Rold&#227;o
Tiago Rold&#227;o

Reputation: 10649

paradoxix's answer was correct in stating that the return falseon the mousedown event is preventing the propagation of all other events.

On any element listening to the mousedown event you won't have any problems, because the event happens for them first, and only after for the box itself. But the input listens to the focusevent, which never happens due to the return false in the box's event.

The solution is to prevent onmousedown from bubbling from the child elements into the box, like so:

var nodes = document.getElementById('draggable-element').childNodes;
for(var i=0; i<nodes.length; i++) {
    nodes[i].onmousedown = function(e) {
        e.stopPropagation();
    }
}

Working fiddle: http://jsfiddle.net/Xcb8d/546/

Upvotes: 1

user2369337
user2369337

Reputation:

the onmousedown handler on the draggable element return false and there by stopping event propagation, allowing it will make the input focus-able and the dragging still works. (at least on chromium)

document.getElementById('draggable-element').onmousedown = function (e) {
    // memorize the offset to keep is constant during drag!
    x_offset = e.clientX - x_elem;
    y_offset = e.clientY - y_elem;    
    _drag_init(this);
    return true;
};

Upvotes: 3

JosiahDaniels
JosiahDaniels

Reputation: 2521

In your onmousedown handler you end with a return false. This prevents the click event from happening when you click on the input, and thus it never gets focus. What I think you are looking for is this:

// Bind the functions...
document.getElementById('draggable-element').onmousedown = function (e) {
    if (e.id == 'draggable-element') {
        // memorize the offset to keep is constant during drag!
        x_offset = e.clientX - x_elem;
        y_offset = e.clientY - y_elem;    
        _drag_init(this);
        return false;
    }
};

Upvotes: 1

Related Questions