I have an issue regarding jquery Ui droppable.
I need to drop an element before or after the element it's dragged over. Is there anyway to detect which element it's over, and then append/prepend it in the parent container.
Right now, I just drops in the end of the div, because of append, I'm a little clueless.
I made a fiddle to hopefully better illustrate my issue:
http://jsfiddle.net/tsxzf80u/
$('section').droppable({
accept:'.dragme',
drop:function(event, ui){
var div = $("<div />").addClass('full').html('test');
$(this).append(div);
}
});
Thanks in advance
If you make each of the divs inside of the section individually droppable, then use after(), seems to do what you want.
$('#fullId1, #fullId2').droppable({
accept: '.dragme',
drop: function (event, ui) {
var div = $("<div />").addClass('full').html('test');
$(this).after(div);
}
});
http://jsfiddle.net/tsxzf80u/2/
Related
I'm trying to use jquery draggable and droppable.
I have multiple draggables and multiple droppables on my page.
The drga and drop works fine but the issue is that when I drag and drop a div onto 1 droppable, it will get cloned in other droppables on my page as well... also, when I move the draggables inside the droppables, they get multiplied again.
To explain this issue, I've created this FIDDLE
and this is my entire code:
(function ($) {
$.fn.liveDraggable = function (opts) {
this.live("mouseover", function() {
if (!$(this).data("init")) {
$(this).data("init", true).draggable(opts);
}
});
return this;
};
}(jQuery));
$('.drag').liveDraggable({
helper: 'clone',
cursor: 'move'
});
var x = null;
$(".droppable").droppable({
drop: function(e, ui) {
var parent = $(".droppable");
var x = ui.helper.clone();
var img = $(x)
var leftAdj = (ui.position.left - parent.offset().left);
var topAdj = (ui.position.top - parent.offset().top);
if (x.hasClass("outside")) {
x.css({
left: leftAdj,
top: topAdj
});
x.removeClass("outside");
}
x.draggable({
helper: 'original'
});
x.find('.ui-resizable-handle').remove();
x.resizable();
x.appendTo('.droppable');
ui.helper.remove();
}
});
Drag the red divs onto the black divs and you should see the issue.
Could someone please advise on this issue?
Any help would be appreciated.
EDIT:
Getting close but still not quite there: https://jsfiddle.net/qkhunz8k/2/
Edit: Apparently I'm not communicating very well. Let me try this again. All of your droppables have the class droppable. As you say, of course they do. That is the purpose of the class.
However, in your code, when you say x.appendTo('.droppable'), this is the source of your duplicates. It is appending to every element which has the droppable class.
I'm not suggesting that you change or remove the droppable class. I'm not suggesting that you change all of your jquery selectors. I'm only suggesting that when you do your .appendTo, perhaps you should only be appending it to the droppable which is the target. Not all of them. Does that make sense? You can do this by doing x.appendTo(this). Just change that one line, and see if the duplicate problem goes away.
$(".droppable").droppable({
...
x.appendTo(this);
The only thing this change will do is change the number of elements your draggable gets appended to. It wouldn't cause any other changes. But I think it will solve your original problem.
As an aside, might I suggest that you would get better results by changing one other line? If you were to use the ui.draggable instead of the ui.helper, you might find that the css positioning would be a little easier to manage, and that you wouldn't need to manipulate the top and left properties so much. Just a thought.
var x = ui.draggable.clone();
updated modification of your fiddle here
I want it to be possible to drag (draggables) several HTML elements into several other HTML elements. (droppables)
I found the jQuery UI draggable/droppable.
Currently, I define all li elements inside an ul as draggable. I also have three divs which accept all the draggable li elements.
<ul>
<li>foo</li>
<li>bar</li>
<li>baz</li>
</ul>
Defining them as draggable:
$('li').draggable({ revert: 'invalid' });
My droppable divs:
<div class="droppable" id="div1"></div>
<div class="droppable" id="div2"></div>
<div class="droppable" id="div3"></div>
Make the divs droppable:
$('div.droppable').droppable({ accept: 'li', drop: funcDrop, out: funcOut });
I now want that only one li element can be dropped into a div at the same time. I am trying to do that by disabling the droppability inside the div element I dropped the draggable, like so:
funcDrop = function(event, ui) {
$(this).droppable('disable');
}
This works. Now I am not able drop any further li elements into this div. The problem is, how/when to enable the div again? Clearly if the contianing draggable was removed. So I tried to enable the div inside funcOut:
funcOut= function(event, ui) {
strIdValue = event.target.id;
$('#' + strIdValue).droppable('enable');
}
But this does not work.
It seems also that I can't work with $(this) selector inside the funcOut.
Does anyone have a hint?
Best regards
I use jQuery 2.1 and UI 1.10.4
I figured out an alternative solution:
It seems if an element once was disabled, the out event does not fire and I am therefore not able to enable it again using the element itself. So what I did, is this:
If you drop a draggable element on a droppable element, the drop event is triggered and does this:
$(this).droppable({ accept: ('#' + $(ui.draggable).attr('id')) });
So the droppable is not disabled, but accepts only the received draggable by its unique HTML id. Because it is not disabled the out event will now be triggered. This is what I do in it:
$(this).droppable({ accept: 'li' });
Now the droppable accepts all HTML li elements as ever. Now each droppable accepts only one draggable. The droppable is now "locked" if it receives a draggable.
I wonder if this is a valid solution or just a dirty hack.
(Possible duplicate/related: jQuery UI - Droppable only accept one draggable)
Based on the JSFiddle you've shared (which currently is not doing what you asked), here is a modified version of the droppable function that you can use to achieve the desired result:
$(".droppable").droppable({
accept: "li",
drop: function(event, ui) {
$(this).droppable('option', 'accept', ui.draggable);
},
out: function(event, ui){
$(this).droppable('option', 'accept', 'li');
}
});
As the other answer stated, the trick is to make our droppable div accept 'ui.draggable', being ui the item that is currently being dragged to our droppable div.
Hope that helps!
(EDITED: Grammar)
I have a problem with jQuery UI and get some information of a dropped item.
I have three areas on the screen:
<div id="area1"></div>
<div id="area2"></div>
<div id="area3"></div>
In these areas, I put elements which are draggable with jQuery UI.
Now if an element is dropped from one to another area, I will not only get the area number in which the element is dropped to, I also want the area number where the element was dropped before the new drop.
I created a full working example: http://jsbin.com/iyaya3/
There is a blue draggable element and if I drag it from area1 to area2, I want to have the alert message with "dragged from area1 - dropped to area2".
How can this be done?
Best Regards, Tim-.
Hey, I updated your jsbin - http://jsbin.com/iyaya3/3
It works like this:
Take initial parent element's id and save it on draggable using jQuery.data
When dropping it on droppable, update data
I've got two ideas:
1) You can put a class or ID on the elements in each div:
<div id="area1"><node class="from1"></node></div>
<div id="area2"><node class="from2"></node></div>
<div id="area2"><node class="from2"></node></div>
And then test for that when you have the item
2) Write a function to do the clone instead of relying on the drag and drop to do it for you (http://ui-dev.jquery.com/demos/draggable/#option-helper) and then test for the parent and store that (in a singleton outside the scope of the dragger) where you can get it later.
I think I would prefer the first (even if you don't have html access to add these classes, just add it with javascript)
In your draggable setup, add this:
start: function(event,ui){
ui.helper.data('from-id', $(this).parent().attr('id') );
}
This will attach, as data, the ID of the container from which the element is being dragged.
Then, in the droppable, you can have:
alert( 'I was dragged from ' + ui.draggable.data('from-id') );
Here's the updated jsBin.
Edit: The start function creates a closure, so $(this).parent().attr('id') continues to point to the original parent. One solution to this problem (if you wish to keep a start function) is to clear start when the drag stops:
stop: function(event,ui){
ui.helper.draggable({ start: null });
}
This will allow the data methods in the droppable handlers to update the from-id without being immediately reverted to the original value by the start function.
Here's a revised jsBin example.
$(element.draggable).parent().attr('id')) works for me
I removed the duplicated code and solved the problem by saving the previous element id by the data() function.
JS Bin
<script type="text/javascript">
$(document).ready(function() {
$('#area1').append('<div class="shoulddraggable" style="width:100px;height:100px;top:0px;left:0px;background-color:blue;" data-elementid="100"></div>');
$(".shoulddraggable").draggable({
scroll: false,
revert: "invalid",
scope: "items",
});
$(".shoulddraggable").data('previousId', 'area1');
$('.droppable').droppable({
scope: "items",
drop: function(event, ui) {
alert('Previous container id: ' + ui.draggable.data('previousId'));
alert("Element: "+ui.draggable.data("elementid")+" dragged into" + $(this).attr('id'));
ui.draggable.data('previousId', $(this).attr('id'));
}
});
});
</script>
</body>
</html>
please help me, I know in general how to use the draggable and droppable classes, but I can not find a way to achieve this:
I have a large-sized image that I need to drag and drop into a div.
1) while dragging, instead of moving around the large-sized image, I want to use a small-sized image (I already have it, just need to change the src).
2) Once it reaches the target div, I would like to hide that dragged image and show again the large-sized image in its original place.
The only restriction is: "revert: invalid" must apply.
This is my code:
$("#big_img").draggable({
revert: 'invalid',
drag : function(e, ui){
//Change big image with a small version of it
$(this).attr("src").replace("/Large/","/Small/"); //<--this do nothing
}
});
$("#target").droppable({
drop: function(e, ui) {
alert("was added"); //<-- no problem here.
//Restore the big_img
}
});
Thank you.
I think I solved it:
Using "helper", I can achieve to use other image instead, like this:
$("#big_img").draggable({
helper: return $("<img src='"+$(this).attr("src").replace("/Large/","/Small/")+"' />");
});
I just need to center it to the mouse cursor, but that I think won't be a problem. Then,
removing the dropped element won't be a problem either. So, I won't need to restore the image as it is not really moving. :)
If you have another alternative, I will be pleased to read it.
String.prototype.replace() does not modify the source string, but returns a new, modified string. Try the following:
$("#big_img").draggable({
revert: 'invalid',
drag : function(e, ui) {
$this = $(this);
$this.attr("src", $this.attr("src").replace("/Large/","/Small/"));
}
});
I am actually trying to make a .php page where I am going to have 3 draggable elements which have to be dragged to 3 droppable elements -each draggable to a droppable, and they are unique, so one each droppable will only accept a certain draggable.
The thing is that I need to control that all of the elements have been dragged to the right spot, in which case I should redirect the user for example to success.php, otherwise, if some of the elements were dragged to the wrong droppable, the user have to go to for example failure.php.
Is there anyway for example to save a certain value in a $_SESSION in PHP in order to know that all the draggables have been dropped in the right place?
This is the code for the drag&drop:
$(function() {
$("#draggableLeiden").draggable();
$("#draggableTheHague").draggable();
$("#draggableRotterdam").draggable();
$("#droppableLeiden").droppable({
accept: '.imgLeiden',
drop: function(event, ui)
{
$(this).addClass('ui-state-highlight');
}
});
$("#droppableTheHague").droppable({
accept: '.imgTheHague',
drop: function(event, ui)
{
$(this).addClass('ui-state-highlight');
}
});
$("#droppableRotterdam").droppable({
accept: '.imgRotterdam',
drop: function()
{
$(this).addClass('ui-state-highlight');
//var activeClass = $(this).droppable('option', 'activeClass','ui-state-highlight');
}
});
});
I am trying to do this for example getting the active class of the droppable elements to see if it matches 'ui-state-highlight', but actually, that tag is gonna be executed everytime the page reloads, so if I try to insert any code into the
drop: function()
it will always execute.
Thanks a lot in advance!
Use the revert option instead. When a draggable element is dropped on anything but the accepted droppable element then it will slide back to its original spot. Does this work for you?
Are you by chance looking for ui.draggable it holds the element that was dropped?
http://jqueryui.com/demos/droppable/
$('#target').droppable({
drop : function(event,ui){
if($(ui.draggable).attr('id') == "correcttarget")
{
window.location = "yay.php";
}
else
{
window.location = "awwww.php";
}
}
})