Eva Nebko
Eva Nebko

Reputation: 214

jQuery UI drag and drop puzzle

I'm trying to make a simple puzzle. When you move the selected div 1, it must swap place of the div 2 on which it was dropped and the div 2 must replace the position of div 1. You can see this if you drop blue on red. How to use this rule for all elements?

I saw a lot of plugins that solve it - but do not like to use a borrowed code into my projects, so I would be grateful if someone give advice or tell how to do it.

http://jsfiddle.net/fresa150/6Ghr5/3/

<table>
<tr>
<td class="drop"><div class="red"></div></td>
<td class="drop"><div class="blue"></div></td>
<td class="drop"><div class="grey"></div></td>
<td class="drop"><div class="yellow"></div></td>
</tr>
</table> 

======================================================

.drop{
      border:1px solid black;
      width:5em;
      height:5em;
      padding: 1em;
    }
.red{
      border:1px solid black;
      width:5em;
      height:5em;
      background:red;
      color:white;
    }
.blue{
      border:1px solid black;
      width:5em;
      height:5em;
      background:blue;
      color:white;
    }
.grey{
      border:1px solid black;
      width:5em;
      height:5em;
      background:grey;
      color:white;
    }
.yellow{
      border:1px solid black;
      width:5em;
      height:5em;
      background:yellow;
      color:white;
    }

==================================================

    $('.red,.blue,.grey,.yellow').draggable({
            helper : 'original',
            opacity : 0.5,
            axis:'x'
    });
    var blueOffset = $('.blue').offset();
    var redOffset = $('.red').offset();

    $('.drop').droppable({    
        drop : function(event, ui) {
                    $('.red').offset(blueOffset);
                    $('.blue').offset(redOffset);
            }
    });

Upvotes: 1

Views: 2275

Answers (1)

nmarsh
nmarsh

Reputation: 164

Part of the issue you're running into is that you'red defining your blueOffset and redOffset vars outside of your function, so whenever .drop() gets fired, you're using the original offsets to determine where the div should move to, which is why this works only the first time.

What you need to do is determine where something is being dropped dynamically each time you drop an element. I believe that you're better off using draggable's stop attribute rather than a separate droppable funciton for this. Here's a fiddle that should get you started: http://jsfiddle.net/2MYkV/

And the code I used:

        $('.drag').draggable({
            helper : 'original',
            opacity : 0.5,
            axis:'x',
            revert: true,
            stop: function(event) {
                    var dropelt = document.elementFromPoint(event.clientX, event.clientY);
                    var dropcell = dropelt.tagName == "td" ? $(dropelt) : $(dropelt).closest('td');
                    var dropdiv = dropcell.find('div');
                    var origcell = $(this).parent('td');
                    var origdiv = origcell.find('div');
                    origdiv.detach();
                    dropdiv.detach();


                    origcell.append(dropdiv);
                    dropcell.append(origdiv);
            }
    });

Upvotes: 1

Related Questions