JQuery UI - Append Draggable to Droppable - javascript

How do you append an item being dragged to a target element on drop, using jQueryUI's draggables/dropables? It looks like the way jQuery UI works right now is it just moves the items around on the screen via absolute positioning. Unfortunately, this functionality makes form submissions useless, as you cannot get the positions of the values on submission.
Thanks in advance for any items/pointers!

If I understood correctly, you want the dragged element to be detached from it's current parent and be appended to the new one, right? You can use a helper to do the dragging (so the original element is not affected) and, upon drop, detach it and append it to the target (thanks #Oleg and #Brian for improving over my original answer).
$(myDraggable).draggable({
helper:"clone",
containment:"document"
});
$(myDroppable).droppable({
drop:function(event, ui) {
ui.draggable.detach().appendTo($(this));
}
});
​
Working example at jsFiddle

Related

jQuery UI - programatically move a dropped draggable to another "available" droppable

I have a mini form control where I drag several draggables onto a scale. See my plunk
Ideally, whenever I drop a draggable, I would like to do in the stop( event, ui ) method:
check if the droppable already has a draggable (let's call it draggable2)
if there is draggable2, I would like to scan my droppables for one that does not have a draggable
then move draggable2 to this droppable
Are there APIs/ways to do this programmatically? I know this sounds similar to sortables, but I am strictly looking for the ability to
move a draggable to a droppable
and
to know if a droppable already has a draggable, and be able to identify the draggable
Any help will be greatly appreciated. Thank you.
I have found a way to accomplish this. Although there are no options from the jQuery UI draggables/droppables API, I have managed to track the draggables and droppables by adding unique "id" attributes to track them.
Here is how I approached the following:
move a draggable to a droppable
My approach: Find the coordinates of the target droppable, and update the css of the draggable.
To figure out which dragger was dragged and which dropper received it, I added attributes dragger-id and dropper-id so I could identify them during the drop event:
drop: function( event, ui ){
// Get the current dragger and dropper ID's
dropperId = $(this).attr('dropper-id');
draggerId = ui.draggable.attr('dragger-id');
// ... more code
}
then I calculated the top and left coordinates for the dragger based on the droppable's values. For this, I used the jQuery's offset() method.
drop_x = $('.droppable').offset().left - $('.draggable').offset().left;
drop_y = $('.droppable').offset().top - $('.draggable').offset().top;
Note: I had to do a difference calculation since draggables are positioned relative to where they start.
Finally, I set the top and left css values:
ui.draggable.css('top', drop_y+'px'); // y-axis
ui.draggable.css('left', drop_x+'px'); // x-axis
to know if a droppable already has a draggable, and be able to identify the draggable
For this, I created yet another attribute on the droppable elements to track the dragger-id values. I called it current-dragger so that it would be unique and I could query by it. I used -1 as my default value, meaning "no dragger".
I assigned current-dragger in the drop method as well:
drop: function( event, ui ){
// Get the current dragger and dropper ID's
dropperId = $(this).attr('dropper-id');
draggerId = ui.draggable.attr('dragger-id');
// Remove current-dragger value from old dropper (-1 means no dragger)
$('[current-dragger="' + draggerId + '"]').attr('current-dragger', '-1');
// Update current-dragger on this dropper
$(this).attr('current-dragger', draggerId);
// ... more code
}
I suppose there's really no need to do updates to the DOM attributes, so in prod I will be tracking the current dragger inside of a JavaScript mapping object.
For a full working example, see my updated plunk

How to properly use AppendTo with Draggable() in JQuery ui?

So I currently am attempting to make my first website (so forgive me for the very sloppy code!) and am having a bit of trouble getting the draggable function to work how I want it to.
This is the first part where I create the divs and set all of the information to how I want it to be. Basically it's using an api to get item information from a game and then is making a display for that item.
<div class='item' id='item"+itemid+"' title='Item'>\n<div class='item_image'><img src='http://ddragon.leagueoflegends.com/cdn/5.2.1/img/item/"+item.image.full+"' style='z-index: 1;position: absolute;'><img src='images/item_border.png' style='z-index: 2;position: absolute;'></div>\n<div class='item_name'>"+item.name+"</div><br>\n<div class='item_cost'><img src='images/gold.png'> "+item.gold.total+"</div></div><br>\n
I then tried to make the whole "itemid" div draggable, but when it's dragged I only want the item image to be shown under your cursor, not the whole div. If I understand this correctly, that's what the "appendTo" is used for:
$("#item"+itemid).draggable({
containment: "window",
appendTo: "#item"+itemid+" .item_image",
helper: "clone",
distance: 25,
opacity: .8,
scroll: false,
stack: "div",
revert: true
});
However whenever I try to drag something using this, it shows not just the item image+the border, but also the item name and item cost, although the gold image is at a bigger scale than it normally is when not being dragged.
How would I make it work so it only shows the image, and not the whole thing when being dragged? Also, why is it showing the whole div if the one I selected for the appendTo is only the image?
Thanks in advance!
The question: "How appendTo works in Draggable()?"
I will try to answer that.
the short answer is "Which element the draggable helper should be appended to while dragging." If you have problem understanding this sentence (like I had) let me explain it:
To explain appendTo I have to explain helper first, because they are kind of related to each other. when you start dragging an element using helper, you have three options:
1- helper: 'original' //default
2- helper: 'clone'
3- helper: function(){ return "an element" }
1 - The first option is "default" and it means the dragging element is the element itself and it has it's own position in the DOM TREE and appendTo option doesn't work in this situation. The element doesn't append to anything, it is in the same situation as before in the DOM TREE.
2 - The second option is "clone" and it means the dragging element is not the same element you start to drag, it's another element copied from the first one. Now, since we can't have an orphan element, who is the parent of the new copied element? well you should answer this in the appendTo option.
3 - The third option is "an element" returning from a function. It is something like:
helper: function(){ return $("<p>YES</p>"); }
And again this new "p" can't be an orphan element so again we attach it to an element which is selected in appendTo option.
At the end you should know that the appendTo is just doing his job while you are dragging the element and after dropping the helper will gone (unless you attach it to an element) and the appendTo will finish his job.

In jQuery, what's the proper way to "move" an element from its parent to another element?

Using jQuery 1.4 and jQueryUI 1.8
Specifically, I'm using draggables/droppables, and when dropped, I would like to move the draggable (it's children, events, etc) from belonging to its parent element to be appended/added as a child of the drop target.
I know that in the droppable drop option, I can supply the following callback:
function(event, ui) {
// stuff
}
where $(this).target will be the drop target, and ui.draggable will be the child element I would like to move - but I'm not sure the proper way to actually perform the move, preserving events, etc.
append() will remove the element and place it where you want.
$(this).target.append(ui.draggable);
// or, if $(this).target is not a jQuery object
var target = $(this).target;
$(target).append(ui.draggable);
Just use .append(), .appendTo(), .prepend() or .prependTo(). The detaching part is implicit. (I tested this by re-parenting entries in the jQuery Manipulation docs to each other.)
ui.draggable.appendTo($(this).target);

jQuery UI Selectables - Start Drag-Selecting from Outside of Objects

I am using the jQuery UI Slectable http://jqueryui.com/demos/selectable/
Once initialized (just like in the demo on that link). drag-selecting only works if I start holding the mouse button on top of a object. If I start drag-selecting from outside of the objects, the selecting does not work.
Is there any way to enable it so the user can initiate the drag-selecting outside of the Selectable objects?
The mouse event listener in the 'selectable' is bound to the wrapper element that you have attached it to. By attaching the it to the body and providing a filter you can get what you're looking for.
Based on the jQuery example:
$('body').selectable({ filter: '#selectable li' });
*Edit:
Unfortunately because of this._trigger("stop", event); it will stop other events on the page.
Your best solution might be to just make the wrapper around the selectables larger.*
This behaviour is already happening, you just can't see it!
Simply adjust the css for your ul.selectable so that it properly contains the floated li's.
#selectable{
overflow: hidden;
}

jQuery UI Draggable - need to modify element while dragging

I'm playing with Drag and drop funcitonality for the first time so I'm not entirely sure what I'm doing!
I need to add a class to a "portlet" while it is being dragged. I don't want to use the clone functionality because I want the user to drag the actual element, I just want to nodify the element while it is being dragged and reset it when it's dropped.
Can anybody help?
Perhaps there's some sort of a 'beforedrag' event you can bind to? It would be easier to add the class to an element before the user actually starts dragging it, rather than during.
If you're using jQuery UI, there's a 'start' event on draggable you can use:
http://docs.jquery.com/UI/Draggable#events
Also, you can use the "helper" option like this:
helper : function(ev, el) {
return ($(el).clone().addClass("beingDragged"));
}
Should your portlets become in the future too heavyweight to drag, you could use that to build a simplified version while dragging to smooth things out :)

Categories