jQuery UI - dropped element -> from which div was it dragged - javascript

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>

Related

jQuery clone not working with draggable

I am using jQuery's draggable and droppable in order to drop content elements onto a page element:
<h2>Page</h2>
<div id='page-content'>
</div>
<div id='content-elements'>
<div id='text-element' class='content-element'>Text</div>
<div id='date-element' class='content-element'>Date</div>
</div>​
My JS for the draggable looks like this:
$elements.draggable({
revert: true
});
The reason I have that revert in there is that I want the content element to return to the list of elements and a 'duplicate' to be added to the page.
I tried doing this using this js for the droppable (created using coffeescript):
$('#page-content').droppable({
drop: function(event, ui) {
var $element, $me;
$me = $(this);
$element = $(ui.draggable);
console.log($element.clone(false));
return $element.clone().appendTo($me);
}
});
What this does is get the ui element that was dragged, attempt to clone it and then append it to the page.
This however does not work! Even though I CAN get the div, etc from the ui.draggable.
I created a jsfiddle to illustrate the problem:
http://jsfiddle.net/sw4Gc/2/
Why oh why?
The element was cloned in a state where it is in position relative and is outside the element. you have to remove the element styles:
var $newElement = $element.clone();
$newElement.attr('style', '');
$newElement.appendTo($me);

Jquery appending in front of div

So I'm using Jquery Drag/Drop to drag and drop something onto a dashboard. I want to now drag anything that I have dropped onto the dashboard out of the dashboard in order to destroy it/remove it from the dashboard.
I've tried adding a class to the thing that is dropped onto the dashboard and then tried adding a draggable to that, but the drag is not working, I think because when I append the element to the dashboard it appears behind the dashboard(the colours are a little faded).
Here is my code-
$(".draggable").draggable({helper:'clone'});
$("#favouritesDashboard").droppable({
accept:".draggable",
drop: function(event,ui) {
var toDrop = $(ui.draggable).clone();
//create smaller version
$(toDrop).addClass("inDashBoard");
$(this).append(toDrop);
}
});
$(".inDashBoard").click(function(){
console.log("clicking elem in dashboard");
});
I've replaced the second draggable with a click, the console.log never prints, suggesting that what I think is going on is actually going on.
Use on for late binding http://api.jquery.com/on/ .
$(document).on('click', '.inDashBoard', function(){
console.log("clicking elem in dashboard");
});
This is due to the nature of event binding / listeners in jQuery.
The elements you want to trigger a click event on do not exist when the page is loaded, they are added dynamically. So to ensure that your method is attached to new elements that match the selector you should use "on" or "live"
$(".inDashBoard").on( "click", function(){
console.log("clicking elem in dashboard");
});
this should work:
$(".inDashBoard").live('click', function(){
console.log("clicking elem in dashboard");
});

to Swap elemnts(with className too) when Draged & Dropped

Swapping two elements whenever one element dragged and dropped over another element. I used Vadim's JQuery plugin and it's working but i have an issue with height,Width,position & float of swapped elements.
Swapped elements doesn't fit if the className & it's attributes were different. Should i swap the className too OR just swap only certain attributes.
* for better understanding please check my demo*
in your example elements behave exactly as they should behave based on the css rules you apply to them. You can add or remove classes or recalculate height/width with javascript on stop event:
$("#foo").swappable({
...
stop: function(event, ui) {
alert("drug: "+ ui.item[0].id + ", drop: "+ event.originalEvent.target.id);
}
...
});
usally the iu items have methods that can be passed in the initilice object
in your case you can use stop
stop is invoked each time ends swap
example:
$(function() {
$('.row,.column').swappable({
items:'.class_1,.class_2',
cursorAt: {top:-20},
stop: function(event, ui) { alert("hi") }
});
$( '.class_1,.class_2' ).addClass( "ui-widget" );
});
instead of alert just add or remove the class you need, probably you can use toogle method
tell me if this is what you are looking for 8)

jQuery Drag plugin - Prevent dropping of a drag element on the top of another

I uses the jQuery pluins event.drag and event.drop
see a demo (just a reference question is not about restricting movement to a container)
Is it possible to prevent dropping of a drag element on the top of
another element? but it can be dragged over the other.
While you can accomplish what you want with the event.drag/drop script it is also easily done using jquery ui - draggable/droppable.
For the event., you need to return false if it meets yours criteria (or vice versa):
$('#drag1').drop("init",function(){
if ( $( this ).is('#badDiv') )
return false;
})
Here is the jquery ui version, it has a built in accept option in the $().droppable function - it accepts selectors also. This example is reverse of above. The above will let you move anywhere but badDiv, whereas this example below will won't let you move anywhere but the defined droppable:
script:
$("#drag1, #drag2").draggable({
revert: 'invalid'
});
$("#drop").droppable({
accept: '#drag1',
drop: function(event, ui) {
// whatever happens on drop
}
});
html:
<div id="drop" style="width:300px;height:300px;background:blue"></div>
<div id="drag1" style="width:50px;height:50px;background:green"></div>
<div id="drag2" style="width:50px;height:50px;background:yellow"></div>
This creates a big droppable area, but it will only accept the draggable ID of drag1. To see this effect you also need the option in your draggable for revert. This case I set it to invalid so the draggable will slide back to its original position if the drop is not valid.
I'm not sure of your exact application, but maybe this will point you in the right direction of what you're trying to accomplish.
I believe that the sorttables uses a similar setup, but that has more with appending divs and adjusting tables.
You can assign a valid drop target selector in this way.
$('.drag').drag(function( event, dd ){
// move the dragged element
},{ drop:'#drop1' }); // assign drop selector
You can also return some drop event handlers "false"
$('.drop').bind('dropinit drop',function( event, dd ){
if ( $( dd.drag ).is('#drag1') )
return false;
});

Change dragging object and restore it after dropping it

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/"));
}
});

Categories