Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Draggable button in Firefox

Is it possible to make a <button> (<input type="button">) work with HTML5 drag and drop in Mozilla Firefox (while still being clickable)?

The following snippet works in Google Chrome but the button and div with button cannot be dragged Mozilla Firefox (unless the Alt key is pressed down, no idea about mobile):

document.getElementById("myDiv").addEventListener(
  "dragstart",
  function (e) {
    e.dataTransfer.setData("Text", "myDiv")
  }
);

document.getElementById("myButton").addEventListener(
  "dragstart",
  function (e) {
    e.dataTransfer.setData("Text", "myButton")
  }
);

document.getElementById("myDivWithButton").addEventListener(
  "dragstart",
  function (e) {
    e.dataTransfer.setData("Text", "myDivWithButton")
  }
);
<div id="myDiv" draggable="true">Div</div>
<button id="myButton" draggable="true">Button</button>
<div id="myDivWithButton" draggable="true"><button>Div with Button</button></div>

I used draggable="true" and dataTransfer.setData, is there something I missed? Is there some sensible workaround?

(If you want to know what I need this for: I have something which can be either dragged at a certain position or set at the default position [center of current view], my idea was to do both through the button [d&d → choose position, click → default position]. I know that I guess I could try to format a <div> to make it look like a <button> or simply split the control into two elements but I'd rather not.)

like image 279
phk Avatar asked Dec 04 '17 14:12

phk


People also ask

How do you make an item draggable?

To make an object draggable set draggable=true on that element. Just about anything can be drag-enabled: images, files, links, files, or any markup on your page. Our example creates an interface to rearrange columns that have been laid out with CSS Grid.

What is a draggable?

Draggable is a modular drag & drop library, allowing you to start small and build up with the features you need. At its most basic, Draggable gives you drag & drop functionality, fast DOM reordering, accessible markup, and a bundle of events to grab on to.

Can any HTML element be draggable?

In HTML, any element can be dragged and dropped.


3 Answers

There is already a bug on Firefox where you can't drag a button. https://bugzilla.mozilla.org/show_bug.cgi?id=568313

However you can drag your div containing button (which is not draggable right now) using 'after' pseudo class. Example:

document.getElementById("myDivWithButton").addEventListener(
  "dragstart",
  function (e) {
    e.dataTransfer.setData("Text", "myDivWithButton")
  }
);
.frontdrop {
   position: relative;
}

.frontdrop:after {
    content: '';
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    position: absolute;
}
<div id="myDivWithButton" class="frontdrop" draggable="true"><button>Div with Button</button></div>
like image 61
Navjot Ahuja Avatar answered Oct 13 '22 06:10

Navjot Ahuja


I found a tricky solution:

<label draggable="true" ondragstart="event.dataTransfer.setData('text/plain', '')">
    <input type="button" value="Click me!" style="pointer-events: none" onclick="console.log(event)">
</label>

Wrap input with a draggable label and set pointer-events CSS property to none. Using this method, your button will be interactive and draggable.

like image 28
Dmitry Prikhodko Avatar answered Oct 13 '22 04:10

Dmitry Prikhodko


From others, I came to know that your issue is because of a bug exists in Firefox. I suggest you to implement custom listeners to imitate drag event. My solution is as follows:

var btn = document.getElementById('btn');

var btnPressed = false;

btn.addEventListener('mousedown', function(e) {
  btnPressed = true;
  px = e.clientX;
  py = e.clientY;
});

btn.addEventListener('mouseup', function(e) {
  btnPressed = false;
})

window.addEventListener('mouseup', function(e) {
  btn.style.MozTransform = "";
  btn.style.WebkitTransform = "";
  btn.style.opacity = 1;
})

window.addEventListener('mousemove', function(e) {
  if(btnPressed) {
    dx = e.clientX - px;
    dy = e.clientY - py;
    btn.style.opacity = 0.85;
    btn.style.MozTransform = "translate(" + dx + "px, " + dy + "px)";
    btn.style.WebkitTransform = "translate(" + dx + "px, " + dy + "px)";
  }
})
<button id="btn">Drag Me</button>

I know its not perfect. Hard-coding is the only way to resolve this issue until Firefox fix this bug.

like image 44
Aswath K Avatar answered Oct 13 '22 05:10

Aswath K