Reputation: 3804
I want to remember or get data of the current drag element. This is what I did :
$('.source_element').on('dragstart', function(e){
e.originalEvent.dataTransfer.setData("source", this);
});
$('.destination').on('drop', function(e){
var source = e.originalEvent.dataTransfer.getData('source');
console.log(source);
console.log(source.className);
console.log($(source));
$(this).html($(source).html());
e.preventDefault();
});
The first console.log show [object HTMLDivElement]
as a string, not an object, second undefined
, third throws an error.
So I suspect that dataTransfer.setData
only accept the data as a string, object is not allowed. If that's the case, how do you solve this problem, how can I remember which element is being dragged without knowing its specific ID ?
Upvotes: 5
Views: 7513
Reputation: 998
You could also do this by inserting a stringified JSON object to the dataTransfer.setData part:
Add the HTML element (use outerHTML so it's a string):
var dragData = {element:originalElement.outerHTML, type:'move-hovered'}
dragData = JSON.stringify(dragData);
event.dataTransfer.setData("text/plain", dragData);
In the above, I create the dragData
object with 2 keys - one is the element
, and the other, move-hovered
, is just a name for the drag event, so you can identify it.
Then JSON parse it when dropped:
var data = e.dataTransfer.getData("text");
var dragData = JSON.parse(data)
var element = dragData.element
Not sure if there's a limit on the length of the text that can be passed, but this is working for me. The main issue though is that there is no reference to the original HTML element, as a new string is used.
And you have to recreate the HTML node when dropped:
var dragDataElement = document.createElement('div')
dragDataElement.innerHTML = dragData.element
originalElement = dragDataElement.firstChild
Upvotes: 0
Reputation: 10928
I'm not a fan of globals, but sometimes they suit the problem. If you want to be able to move an HTMLElement with some data, try this:
window.dragDepo = {};
const dragID = "unique_dragging_name";
sourceEl.addEventListener("dragstart", (event) => {
window.dragDepo[dragID] = { el: sourceEl, origin: "where it was before" }
event.dataTransfer.setData("text/plain", dragID);
});
// clear global data asap
sourceEl.addEventListener("dragend", (event) => window.dragDepo[dragID] = undefined);
.
destinationEl.addEventListener("drop", (event) => {
const dragID = event.dataTransfer.getData("text/plain");
dragData = window.dragDepo[dragID];
});
Upvotes: 3
Reputation: 97672
Just use some string to uniquely identify the element, like giving each element an id or a data attribute
$('.source_element').on('dragstart', function(e){
var id = 'drag-'+(new Date()).getTime();
this.id = id;
//$(this).attr('data-drag', id);
e.originalEvent.dataTransfer.setData("source", id);
});
$('.destination').on('drop', function(e){
var source = e.originalEvent.dataTransfer.getData('source');
console.log(source);
console.log($('#'+source));
$(this).html($('#'+source).html());
//console.log($('[data-id="'+source+'"]'));
//$(this).html($('[data-id="'+source+'"]').html());
e.preventDefault();
});
Upvotes: 4