I'm trying to figure out a way to pass a native object through javascript's event.dataTransfer for drag and drop. I'm writing the front end editor portion of a CMS, and want users to be able to drag and drop elements (of many different types, ranging from files to images to snippets of HTML to just about anything). That's why I want to pass a real object, so I can attach data to it to specify things that will be necessary in order to know how to render it.
One workaround is to use jQuery's .data() to attach an object to something else on the page, and then simply pass the selector string in setData... but I don't particularly enjoy that hack.
This could also be solved with jQuery UI's draggable/droppable (and I'm not totally opposed to using any libraries), but since the dropzone is in an iframe, this is a actually a documented bug in the latest jQuery UI (1.10.2). Also, I would strongly prefer to do it natively if possible. There are already enough libraries in this app.
Here's the problem: http://jsfiddle.net/AHnh8/
var foo = {foo: "foo", bar: "bar"}; $dragme.on("dragstart", function(e) { e.originalEvent.dataTransfer.setData("foo", foo); }); $dropzone.on("dragenter", function(e) { e.preventDefault(); }); $dropzone.on("dragover", function(e) { e.preventDefault(); }); $dropzone.on("drop", function(e) { console.log(e.originalEvent.dataTransfer.getData("foo")); // [Object object] console.log(typeof e.originalEvent.dataTransfer.getData("foo")); // string });
Now, after reading the specs, I totally understand why this fails. What I don't understand, is how to ultimately achieve what I want.
Thanks
The DataTransfer object is used to hold the data that is being dragged during a drag and drop operation. It may hold one or more data items, each of one or more data types. For more information about drag and drop, see HTML Drag and Drop API.
The DataTransfer() constructor, when invoked, must return a newly created DataTransfer object initialized as follows: Set the drag data store's item list to be an empty list. Set the drag data store's mode to read/write mode. Set the dropEffect and effectAllowed to "none".
The DataTransfer. setData() method sets the drag operation's drag data to the specified data and type. If data for the given type does not exist, it is added at the end of the drag data store, such that the last item in the types list will be the new type.
If you want to drag an element, you need to set the draggable attribute to true for that element. Set an event listener for dragstart that stores the data being dragged. The event listener dragstart will set the allowed effects (copy, move, link, or some combination).
You should pass the object to JSON.stringify
before using setData
because you can only store strings.
var j = JSON.stringify(foo); e.originalEvent.dataTransfer.setData("foo", j);
And the other way round you have to reconvert the string to an object:
var obj = JSON.parse(e.originalEvent.dataTransfer.getData("foo")); console.log("foo is:", obj);
See this working Fiddle
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With