Or, another way to perhaps word it: can a non-Draggable element be 'disguised' as a Draggable in the eyes of a droppable?
The situation is that I'm trying to implement a workaround for the fact that jQuery Draggables and Droppables are not touch enabled. There are workarounds to this (such as Touch-Punch) but they still are emulating the touch by translating to the mouse events that a jQuery Draggable is listening for.
This is a problem for me as the particular goal I'm after is to allow a user to drag two elements with two separate drag interactions simultaneously--which one obviously can't do with a mouse--so just isn't supported by jQuery UI.
I found this as an alternative to the Draggable: https://github.com/heyman/jquery-draggable-touch
It's not nearly as robust as a default jQuery draggable, as there aren't handy parameters such as 'revert'. But not a huge deal. I can rewrite those features as needed.
However, I'd rather not rewrite all the logic that I've already built around the built-in functionality of a droppable. For example: getting the dropped item from within the droppable configuration via ui.droppable--or just trying to figure out if it there was even an element dropped upon it.
Is there a way for an element to be 'seen' as a jQuery draggable by a jQuery droppable without actually being a jQuery draggable?
UPDATE:
I've discovered I can use this draggable-touch AND jQuery's draggable at the same time...draggable for mouse, draggable-touch for touch. Nice.
However, I still have to integrate the touch event into the fold and to do that, ideally, I could manually calculate the position of the dragged item and if it is above a droppable element, I could .trigger the drop event. Alas, I can't find the correct syntax for triggering a drop event on a droppable.
Related
This is mostly an 'is this possible' type of question, because after a day of testing options, I am not sure that it is.
We have a list of item within a scrollable DIV, each of which needs to be touch draggable. Just turning on drag and drop for each time will break the ability to scroll the list, as a swipe to scroll gets interpreted as a drag event as well. The easiest option if to add a drag handle to each item, but we have very little UI space available on these items, and the powers that be were hoping to not squeeze things even tighter to add a touch hit area for said handle.
The option I am looking into is a 'touch and hold to release'. The user touched and holds the touch for one second, and the item 'unlocks' to be draggable. This sounded easiest enough when I set out, using HammerJS for the Press event, then calling a start for the drag and drop event process. This is not working out however, as none of the browser drag events can be manually started. I can call 'touchstart' with a trigger or dispatchEvent, which will do the setup we need, but no drag events every occur. 'dragstart' normally gets fired as soon as the touchstart occurs, and since I am needing to wait, there is never and dragstart to kick off the process.
I assume the browser's drag and drop events work only under specific circumstances. Triggering dragstart manually wont be a real drag event (its missing all the dataTransfer stuff), and most importantly, nothing actually gets dragged, despite the element being a valid, draggable element. Using an alternate event like 'dragover' works, but since its there was never a real dragstart, there is no actual drag and drop occurring.
Is this just something that browsers do not support short of dropping the HTML drag and drop for javascript? Or is there something I am missing?
I am working on a drag and drop project.
How: I am using the HTML5 drag events.
Code: See fiddle here
Problem: It only works sometimes, and I checked the code a million times
Idea:
- Get element and drag it over a div with id: LayerN (N=number)
- Create a new layer before LayerN when dropping
- AppendChild to new Layer.
- Remove empty layers if there are any.
Is there anything I am doing wrong or too complex? I don't want to use a JQuery framework, i want to understand what I am doing. Thanks a lot for reading, any help will be highly appreciated.
I can't get your fiddle to work so I'm giving general comments rather than a full 'answer' so hope it helps!
For D&D I find what works best is attach a mousedown event to the document on page load (or the containing element of the draggable objects if that's more appropriate).
Don't attach any events to the draggable elements themselves at this stage.
On mousedown, check the classname/id of the target and if it's draggable:
If you want to show it dragging, clone the element and append to a position:fixed or :absolute DIV - you can move this on mousemove relative to the cursor. Keeping this element offset to the cursor means you can still detect what's under the cursor.
Hide the element you're dragging. You can put some sort of image showing where it came from at this stage if you wish using insertBefore.
I hide the element rather than move it because if you cancel the drag it's very easy to restore it.
Attach mousemove and mouseup events to the window or document. The function you call on mousemove can, based upon the event.target/event.srcElement, decide whether the dragged object can be dropped or not (again, I generally look for a className here).
This way you've only got a maximum of two event listeners running everything rather than multiple events on every single element. I suspect your event listeners may be tripping over each other.
I don't know if that gets you any further, but good luck!
I want to drag and drop my widget into my div. I drag my widget over my div, but it doesnt drop the true place.
Here is my example: jsfiddle.net/Mg6V3/15
My goal is when i drop the widget on "1", widget must be drop in it.
Thank you.
It was easier than I originally thought it would be.
First of all, there is greedy option you can set when initializing droppable. It aims to stop drop events from being propagated to all droppable parent when using nested droppables.
Second of all, binding the droppable behavior to matched selectors isn't a constant process. Meaning, that when using something like $('.test').droppable() it will bind droppable only to applicable elements that already exists in the DOM. If you create new ones you're suppose to initialize droppable on them on your own.
Here's the working example based on your code. I tried to be minimize the changes - it can be done better, cleaner but it's just an illustration so I guess it's ok. http://jsfiddle.net/vM3dU/
Various JavaScript libraries, such as jQuery UI, offer drag-and-drop interactions where you can constrain the movement of the dragged element to a single axis, or within a particular area.
Is this sort of thing possible using the native HTML5 drag and drop API?
It's totally different!
The jQuery UI drag and drop make element move (with top and left CSS properties) in the page.
The native HTML5 drag and drop API only allow you to move a "ghost" of the draggable element (of course, you can hide the original element while dragging the ghost).
The API come with a lot of event but no, you can't constrain mouse position so you can't constrain to a single axis (cause the ghost follow the mouse position, even if the mouse leave the page (but event may probably stop operate)).
I'm doing a visual editor using HTML5 Drag and Drop and i need to drag an element set as draggable to a div who acts as a container.
Some browsers provides a kind of preview image that represents the element while i'm dragging it, and when i let the element in the container with the drop event, i need to get the position where the user wants to put him. The problem is that i don't know the position of the preview ghost provided by browsers, so i don't know where exactly the element should be positioned.
I used the mouse position but it's not what i wanted, because the mouse position is not ever the same as the preview's. Is there a way to get the current position of the preview of a dragging element?
Have you considered using jQuery UI to do your DnD? I'm not sure if you've considered that or not, but here are some resources that might help you in-case you do choose to do the jQuery UI route:
jQuery UI Draggable (also see Droppable)
jquery ui drag/drop getting position from multiple draggables