9

I am fairly new to jQuery and am stuck trying to get a dragged image elements id to append to the drop target instead of the image element itself or the drop targets id. I am using the html5 native DnD. And so far I can get the element itself to append by sending through its id with the datatransfer method in the drag function and the getdata function in the drop. Whenever I try to call that id from the drop however it gets the drop target id instead of the dragged elements.

Any help would be greatly appreciated as I have searched thoroughly online and found nothing but more methods to get the target id of the drop area. Here is a snippet of my current code fiddle:

function allowDrop(ev) {
ev.preventDefault();
}

function dragStart(ev) {

ev.dataTransfer.setData('Text/html', ev.target.id); // sends the dragged images data.

//alert(ev.target.id); // alerts the correct id of the dragged image.

}


function drop(ev) {

ev.preventDefault();
var data = ev.dataTransfer.getData("text/html");//retrieves dropped images data.
ev.target.appendChild(document.getElementById(data));//this displays the dropped image.

//alert(ev.target.id); // alerts the id of the drop target(Want to get the dropped images id.)

//$("#mybillets").append("<span>"+ev.target.id+" </span>"); //appends the drop targets id(Want to append the dropped images id.)
}
Jason
  • 123
  • 1
  • 2
  • 10
  • 1
    If you have the DOM element in a variable named `elem`, then the id is simply `elem.id`. – jfriend00 Oct 22 '14 at 02:47
  • 1
    in that case `data` should give you that – Arun P Johny Oct 22 '14 at 03:59
  • Any advice on how I could implement that? Been trying so many different things my head is fried. – Jason Oct 22 '14 at 04:08
  • 1
    `var data` should have what you needed.Since you are a new to jQuery try jQuery UI.It has nicely built-in options for drag and drop. Then you just need to call `$(ui.draggable).closest("img").attr("id");` to get the image ID check this out http://jqueryui.com/draggable/ – vinu Oct 22 '14 at 04:10
  • I feel so stupid, got it sorted. Thanks for the help guys, wouldn't have clicked with me otherwise. I just used the 'data' variable to call the id. Arun P, you're comment made me realise how simple it was and how stupid I am. I had a look at the UI but wanted to get it with the native Drag and Drop as this is part of a larger project and I wanted to learn a few new tricks. Thanks for all the help! $("#mybillets").append(""+data+" "); – Jason Oct 22 '14 at 04:13

4 Answers4

22

In the drop method looks like ev is the event object, so ev.target will refer to the element on which the item was dropped.

So use ev.target.id to refer to the drop target id.

function allowDrop(ev) {
    ev.preventDefault();
}

function drag(ev) {
    ev.dataTransfer.setData('Text/html', ev.target.id);
}

function drop(ev, target) {
    ev.preventDefault();
    console.log(target.id, ev.target.id)

    var data = ev.dataTransfer.getData("text/html");
    alert(data)
}
#div1 {
  width: 350px;
  height: 70px;
  padding: 10px;
  border: 1px solid #aaaaaa;
}
<div id="div1" ondrop="drop(event, this)" ondragover="allowDrop(event)"></div>
<br/>
<img id="drag1" src="//placehold.it/336X69/ff0000" draggable="true" ondragstart="drag(event)" width="336" height="69" />
Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
  • 4
    I am actually trying to display the id of the image being dragged and not the drop target, I have edited my code a bit to better illustrate what I am trying to do. ev.target.id refers to the element that fired the event, which in the case of the drop event, refers to the area that the image is being dropped into. I want to get the id of the image that is being dropped instead. – Jason Oct 22 '14 at 03:57
  • I did, it's working now.. Thank you! It's appending the correct id now. – Jason Oct 22 '14 at 04:20
  • How do you get the id of the container (div1) rather than the id of the dragged item? – Seif Eddine Mouelhi Jul 22 '16 at 01:37
2

Thanks to @Arun P Johny. Excellent work on this simple example.

However, I just wanted to add that if you try and drag from an "A" tag, you won't have much luck.

This will not work (in all browsers):

<a draggable="true" ondragstart="drag(event)" id="drag1" href="#">
 <img src="https://placehold.it/336X69/ff0000" width="336" height="69" />
</a>

However this will work (in more browsers):

<img draggable="true" ondragstart="drag(event)" id="drag1" src="//placehold.it/336X69/ff0000" width="336" height="69" />

This took me a long time to discover this out, because many of the browsers don't return or let you get the source id of what you are dragging. This example should reveal the source id for you in an alert and also the console:

<script>
    function allowDrop(ev) {
        ev.preventDefault();
    }
    
    function drag(ev) {
        ev.dataTransfer.setData('text', ev.target.id);
    }
    
    function drop(ev, target) {
        ev.preventDefault();
        console.log(target.id + " : " + ev.target.id) 
        console.log(ev.dataTransfer.getData("text/html")); 
        console.log(ev.dataTransfer.getData("text")); 
        var data = ev.dataTransfer.getData("text");
        alert(data)
    }
</script>
<style "type="text/css">
       #div1 
       { 
          width: 350px; 
          height: 70px; 
          padding: 10px; 
          border: 1px solid #aaaaaa; 
       }
</style>

<div id="div1" ondrop="drop(event, this)" ondragover="allowDrop(event)"></div>
<br/>
<img id="drag1" src="https://placehold.it/336X69/ff0000" draggable="true" ondragstart="drag(event)" width="336" height="69" />
vr_driver
  • 1,867
  • 28
  • 39
1

I have created simple drag and drop example that maybe you can use as example for your problem. There are 4 boxes where images can be dropped to. Just grab a image from the list below and drop it into one of the boxes above. The code will alert the movement you have made.

HTML Code:

  <div id="box1" class="empty">Box 1</div>
  <div id="box2" class="empty">Box 2</div>
  <div id="box3" class="empty">Box 3</div>
  <div id="box4" class="empty">Box 4</div>


<div id="example1" class=" container list-group col" >
  <div id="image1" class="fill list-group-item" draggable="true">
      <img src="https://source.unsplash.com/random/150x150"> Image 1
  </div>
  <div id="image2" class="fill list-group-item" draggable="true">
      <img src="https://source.unsplash.com/random/149x149"> Image 2
  </div>
  <div id="image3" class="fill list-group-item" draggable="true">
      <img src="https://source.unsplash.com/random/151x151"> Image 3
  </div>
  <div id="image4" class="fill " draggable="true">
      <img src="https://source.unsplash.com/random/152x152"> Image 4
  </div>
  <div id="image5" class="fill" draggable="true">
      <img src="https://source.unsplash.com/random/153x153"> Image 5
  </div>
  <div id="image6" class="fill" draggable="true">
      <img src="https://source.unsplash.com/random/154x154"> Image 6
  </div>  
  <div id="image7" class="fill" draggable="true">
      <img src="https://source.unsplash.com/random/155x155"> Image 7
  </div>
  <div id="image8" class="fill" draggable="true">
      <img src="https://source.unsplash.com/random/156x156"> Image 8
  </div>
  <div id="image9" class="fill" draggable="true">
      <img src="https://source.unsplash.com/random/157x157"> Image 9
  </div>
  <div id="image10" class="fill" draggable="true">
      <img src="https://source.unsplash.com/random/158x158"> Image 10
  </div>
</div>

Javascript

const fills = document.querySelectorAll('.fill');
const empties = document.querySelectorAll('.empty');

let object="";
let destiny=""; 

// Fill listeners
for (const fill of fills) {
  fill.addEventListener('dragstart', dragStart);
  fill.addEventListener('dragend', dragEnd);
}

// Loop through empty boxes and add listeners
for (const empty of empties) {
  empty.addEventListener('dragover', dragOver);
  empty.addEventListener('dragenter', dragEnter);
  empty.addEventListener('dragleave', dragLeave);
  empty.addEventListener('drop', dragDrop);
}

// Drag Functions

function dragStart() {
  this.className += ' hold';
  setTimeout(() => (this.className = 'invisible'), 0);
  console.log('Start');
  objeto = this.id;
}

function dragEnd() {
  //alert('Objeto: '+this.id);
  this.className = 'fill';
}

function dragOver(e) {
  e.preventDefault();
}

function dragEnter(e) {
  e.preventDefault();
  this.className += ' hovered';
}

function dragLeave() {
  this.className = 'empty';
}

function dragDrop() {
  //alert('Destino: '+this.id);
  this.className = 'empty';
  destino = this.id;
  showMove();
}

function showMove()
{
  alert('Moving object: '+objeto+' -> to : '+destino);
  console.log('Moving object: '+objeto+' to : '+destino);
}

https://codepen.io/iburguera/pen/jObLaKY?editors=1010

Iker
  • 2,018
  • 2
  • 29
  • 52
1

To clarify for people like myself for how to get both the ID of draggable element and droppable target: based on the code provided in the question from Jason:

    function drop(ev) {

          var dataA = ev.dataTransfer.getData("text/html");
          var dataB = ev.target.id;

          //console.log(dataA); ==> This will give "drag1" (object/item being dragged)
          //console.log(dataB); ==>This will give "div1" (area the object is being dragged into, AKA drop target)
          
     }
Ming Chen
  • 11
  • 2
  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Ronald Haan Jan 11 '23 at 07:44
  • As its currently written, I found it quite clear and was exactly the answer I'm looking for. – Phaelax z Aug 14 '23 at 18:17