FlyingCat
FlyingCat

Reputation: 14250

Jquery UI drag and drop issue

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('&nbsp;').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

Answers (2)

Dom
Dom

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 tds remain in the table.

Let me know if you have any questions!

Upvotes: 2

Jeemusu
Jeemusu

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:

http://jsfiddle.net/jjyNS/

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

Related Questions