Reputation: 14250
I am trying to do a drag and drop using Jquery
UI
I need drag and drop feature between two tables.
table1
<table class='table'>
....
</table>
table2
<table class='table'>
....
</table>
I want the user to drag cell
from table 1 to table 2.
The codes below accomplish that
var dragging =null;
obj = $('.table td');
$(obj).draggable({
cursor:'pointer',
snap:$('td span'),
revert: 'invalid'
})
$(obj).droppable({
//only accept the drop if the cell is empty.
accept: function(e){
return $(this).text().trim()=="";
},
//replace anything items on table 2.
drop:function(event, ui){
$(this).html(' ').droppable( 'disable' );
}
})
My question is: After I drag the itemA
from table 1 to table 2. I can't seem to drag itemA
anymore on table 2. I want the user still be able to drag itemA
even if it's in table 2.
I am not sure what went wrong here. Can anyone help me about it? thanks so much
Upvotes: 1
Views: 1817
Reputation: 40463
The main issue is caused by making the td
draggable and droppable. When you drag a td
and drop it on another td
, then you physically move the td
out of the table, so the "drop" point changes.
Also I recommend against using accept
in this manner. When you call $(this)
within your accept
function, it returns all draggable objects. Since you are really only concerned with the td
's content, I suggest approaching this in a different manner, using drop
event to verify whether the td
is empty or not.
$(function() {
var dragging =null;
obj = $('.table td');
//use obj since $(obj) is already jQuery object
obj.draggable({
cursor:'pointer',
snap:$('td span'),
revert: 'invalid',
helper: 'clone',
start: function( event, ui ) {
//make helper same height as td
$(ui.helper).css('height', $(this).height());
}
})
obj.droppable({
accept: obj, //make obj accept
drop:function(event, ui){
var target = $(event.target), //can also use $(this)
drag = $(ui.draggable),
targetText = "",
dragText = "",
duration = 0;
if(target.text().trim() === ""){
//store original target, drag text
targetText = target.text().trim();
dragText = drag.text().trim();
//change html for each element
target.html(dragText);
drag.html(targetText);
}
else{
//if not empty, change duration
duration = 500;
}
//always have td revert
//however, if invalid, the revertDuration will be default
//so the element "reverts"
ui.draggable.draggable('option', 'revertDuration', duration);
ui.draggable.draggable('option','revert', true);
}
})
});
DEMO: http://jsfiddle.net/dirtyd77/7Xd6n/4/
By doing it in this manner, only the content changes and the td
s remain in the table
.
Let me know if you have any questions!
Upvotes: 2
Reputation: 10533
The problem with draggable is that the element your dragging doesn't actually move in the DOM. So when you try to drag it back to it's original position your are attempting to drop it upon itself.
Ideally, instead of dragging the <td>
elements you should wrap the contents inside them in <div>
elements and drag these instead.
The adjusted code would be something like this:
$(function() {
draggable_obj = $('.table td div');
droppable_obj = $('.table td');
$(draggable_obj).draggable({
cursor:'pointer',
snap:'td',
revert: 'invalid'
})
$(droppable_obj).droppable({
drop:function(event, ui){}
})
});
Here is a fiddle of it in action:
If you need the elements to move in the DOM too, then you may want to clone the element when it is dragged, hide the original, then when you drop it append the cloned element and remove the original.
Upvotes: 1