[Edit] : Solution is given in TCHdvlp's comment to his reply below. Thanks a lot !
I need to drag elements from one container (container1) to another (container2) and back, like in this fiddle :
http://jsfiddle.net/U2nKh/20/
(this was not created by me : see original question)
As you can see in the exemple above, when the element is attached to its new container, its 'style' attribute is erased, and it snaps to the top left corner of the new container.
$(ui.draggable).appendTo($(this)).removeAttr('style');
I'd like the draggable to stay in place in its new container, where it's dropped.
But if I delete .removeAttr('style'),
$(ui.draggable).appendTo($(this));
the position information is kept, but is inexact since the parent of the draggable has changed. As a result, my draggable is positionned much lower when dropped from container1 into container2, and much higher in the other case.
I am able to compute the new position where my element should "land", based on the relative positions of the containers. But I don't know how to define this position.
Should I let the .removeAttr('style') and recrete it fom scratch with new values ? But how?
Should I delete that part, but modify the position values? But how ?
I hop I am clear enough for you to give me some advice.
Thanks !
Carefully read all the fiddle!
The draggable div has top:10px; and left:10px; properties. When it's dragged, those properties change. When it's dropped in the other droppable area, the removeAttr('style'); will remove inline style and set back the 10*10px offset. BUT, it's not snapped.
Also, the draggable element is position:absolute but the droppable area is position:relative. It means that the child element is positioned relatively to its parent.
That's why, with the original fiddle, the 10*10px position looks to be always the same, whatever the droppable area.
Remove in the css position:relative for both container and position:absolute for the div.
Remove the removeAttr and the append in the dropped function.
Because we don't want the element to be attached to the area, we don't use append. We will use 2 variables to compare last and current droppable area.
http://jsfiddle.net/TCHdevlp/U2nKh/576/
Related
I would like to drag and drop divs within a container-div. Only up and down the list, using the mouse. How can I create this?
Searching the internet and stackoverflow didn't give me a good answer, since I would like to have it in vanilla Javascript and everything is nowadays in jQuery. :S
This is wat I have:
<div class="chapcontainer" data-chaporder="1000">
<div class="chapter">Big fire</div>
<div class="subchapter" data-chapid="1">Forest burning</div>
<div class="subchapter" data-chapid="2">Balu hoses</div>
<div class="subchapter" data-chapid="3">Forest animals die</div>
<div class="subchapter" data-chapid="4">Lovely fire</div>
</div>
</div>
The chapter-div is the container. Within this div I want to be able to move the subchapter-div with a click of the mousebutton up and down the list of subchapter-divs.
For example I move the subchapter-div with data-chapid 4 to the top, then it should be moved to the top and the data-chapid changed to 1. Is something like this possible in vanilla javascript?
I've read about AppendChild, but I don't know how I can trigger this with the mouse.
You could do it with jQuery:
$(".subchapter[data-chapid='1']").on("click", function() {
$(this).css('margin-left', '20px') // add margin/padding/etc here
})
Fiddle
Doing drag and drop yourself is complicated, but here are some of the basic steps. One advantage of rolling your own is you can do more advanced things than your standard jquery ui drag and drop can, like smooth scrolling the container, auto-opening nested tree items if the user hovers over them, or doing animations while moving items.
Steps:
Listen for mousedown events on your items in your container. When the user presses down on an item, store the mouse's offset relative to the top of container (this includes the scroll of the container). Also store the mouse's offset relative to the item being dragged.
Clone the element that's being dragged and absolute position it under the mouse, using the relative offset you stored in step 1.
Make the original element invisible.
Listen for mousemove events on your container. Reposition the dragged item appropriately.
As the mouse moves, you'll need to update the mouse's new offset from the top (including scroll) and figure out which item you're over. You can do this by getting the height of each item in your list. So if your mouse is 710 pixels from the top, and each item is 100 pixels high, you're over index 8. You can use this info to change the style of the item you're over to show that it's a drop target. One thing to watch out for is if you do any styling changes that change the heights of items, you'll need to recalculate your heights.
On mouseup, you already know which item you're over, so now you need to update your data array to move the dragged item, probably using array.splice. Delete the absolutely positioned dragged element, and rerender your list to reflect your changes. I'm assuming you're using some sort of templating library to render your stuff, or at least a render function that clears what's there and replaces it with the current state.
I'm trying to use Drag and Drop to move <li> elements from one <ul> to another <ul>. I've got it working up to a point. My problem is I can't "drop" a <li> element when it's over another <li> element in my <ul> container. So when I fill up the visible portion of my container I can no longer drag and drop.
This CodePen demonstrates my problem.
not sure exactly what you are trying to achieve, if you want the drop target
to enlarge to accomodate, then be sure you set the CSS style on the target
with a text size using px definitions instead of pt specs.
then each time a drop occurs add to your drop routine to increase the size
of the drop target by the pixel height of 1 line of text. so it grows by 1 on
every drop, or the height is equal to lineHeight x (numElements + 1)
always leaving you room for 1 more drop
if you are trying to maintain a fixed size of the drop target, ie, you dont want
to move other elements down the page, take the above mentioned drop target
and put it inside a fixed size div with scrollable properties.
that way you have a drop element that can grow as described above,
but the fixed div constrains the screen real estate so the drop target doesnt
take up more space than you want
I solved my issue. I had to comment out an if statement in my handleDragOver function that was checking if the event.target was the dropzone element. I also changed my handleDrop function to use event.currentTarget instead of event.target
I'm trying to drag an <img> inside a container that has fixed width and height.
I already searched on SO and found this but it does not work for me.
Here it is a fiddle of what I'm trying to achieve; there is a container which is the only part of the image I want the user to show, and a draggable image under it. It has to be constrained in the .container element depending on the orientation of the image and the container must include always a part of the image, never a blank part, in other words the image's borders must always stay inside the container.
I tried to work with the containment property, but I don't understand how does the Array option works ( http://api.jqueryui.com/draggable/#option-containment ).
$("img").draggable({
containment: "parent"
});
and remove .active
I am working on a dashboard where user can drag and drop elements to create html pages.Now,he can have multiple images using an image component.We have managed to calculate the z-index of the images and they can be adjusted using up-down keys.
Issue:
The issue we are facing is when we select a image component we attach a dotted layer above it for helping the user to easily drag and resize it.If the user places the images as shown in the image below
we are not able to select the inner image again because the z-index of the selection div(the one with the blue dots) is(has to be) the highest(highest bcoz we have to use it for all components).So if I try to select the inner image now it cannot be selected.How can I handle the situation? For reference it works on this site as expected.
I believe we have get the element under the parent when it is clicked.But not sure how!We are using javascript,jquery to handle the events.
You can use JavaScript or jQuery to get the position of the inner image, and when the user clicks on the outer image, check to see whether the mouse position lies within the range of the smaller image. The range can be calculated with the position, width, and height of the inner element.
To get the element's position: use jQuery .offset() or .position() (The former is relative to the document, the latter to the parent).
To get the mouse position: http://docs.jquery.com/Tutorials:Mouse_Position
You could consider hiding the masking element quickly in order to gather the coordinate for your underlying element, when done, you could re enable visibility for the masking element. Use document.elementFromPoint() in order to get the DOM item from mouse coordinate.
An example:
http://jsfiddle.net/s94cnckm/14/
Alternatively you can use The CSS property pointer-events: none; on the masking element.
Related:
https://developer.mozilla.org/de/docs/Web/CSS/pointer-events
How to detecting a click under an overlapping element?
Please see the following jsfiddle: http://jsfiddle.net/bhellman1/Na3hd/11/
Right now when you move over the box, the hoverbox appears in the same place for all items.
What I would like to do is position the hover box based on which #box.corner you are moused over. If the #box.corner is to the left of the box, I'd like the hover box in the left, outside the box, centered to the corner.... If you mouse over a #box.corner that's in the bottom right, I'd like the hover box to show at the bottom right, centered to the corner.
Any ideas on how to accomplish this?
Thanks
If I read your question correctly, this should be what youre looking for: http://jsfiddle.net/Na3hd/17/
As you can see i moved around some of the css to match what different elements have in common more, so that the code can easily be reused and assigned to other elements. I moved the defining of the hoverbox into the mouseenter function, so that a new div gets created on each mouseenter, which will then not result in complication when setting the positions.
Hope this helps!
EDIT
Here a more dynamic approach: http://jsfiddle.net/Na3hd/22/
Also, i just realized you wanted to have these items show up outside of the boxes.