Search code examples
jqueryhtml-tabledraggabledroppable

jQuery draggable/droppable div in multiple divs


I want to create a table where each cell can contain an element (div) that can be dragged and dropped in other cells. It seems that the element can be dropped only the origin div. I don't understand why it doesn't work.

<style>   
.over {
  border: solid 4px #ACFA58;
}
.draggable {
    border: solid 4px red;
    width:150px;
    height:75px;
}
#timetable{
    margin-top:50px;
    width:100%;
    border-collapse:collapse;
    border: 1px solid black;
}
#timetable th{
    text-align:center;
}
#timetable td{
    width:150px;
    height:75px;
    border: 1px solid black;
}
</style>


<script>
$(document).ready(function() {
    $(".draggable").draggable({ 
        cursor: "crosshair", 
        revert: "invalid"
    });

    $(".drop").droppable({ 
        accept: ".draggable", 
        drop: function(event, ui) {
            console.log("drop");
            $(this).removeClass("border").removeClass("over");
            var dropped = ui.draggable;
            var droppedOn = $(this);
            $(dropped).detach().css({top: 0,left: 0}).appendTo(droppedOn);    
        }, 
        over: function(event, elem) {
            $(this).addClass("over");
            console.log("over");
        },
        out: function(event, elem) {
            $(this).removeClass("over");
        }
    });

    $(".drop").sortable();
});
</script>

<div id="page-wrapper">
    <table id="timetable" >
            <thead>
                <tr>
                    <th>1</th>
                    <th>2</th>
                    <th>3</th>
                    <th>4</th>
                    <th>5</th>
                    <th>6</th>
                    <th>7</th>
                </tr>
            </thead>
            <tbody id="containment">
                <tr>
                    <td><div class="drop"><div class="draggable"></div></div></td>
                    <td><div class="drop"></div></td>
                    <td><div class="drop"></div></td>
                    <td><div class="drop"></div></td>
                    <td><div class="drop"></div></td>
                    <td><div class="drop"></div></td>
                    <td><div class="drop"></div></td>
                </tr>
                <tr>
                    <td><div class="drop"></div></td>
                    <td><div class="drop"></div></td>
                    <td><div class="drop"></div></td>
                    <td><div class="drop"></div></td>
                    <td><div class="drop"></div></td>
                    <td><div class="drop"></div></td>
                    <td><div class="drop"></div></td>
                </tr>
            </tbody>
        </table>
</div><!-- /#page-wrapper -->

Solution

  • Your problem is that your target divs have no height. I edited your snippet slightly to use an activeClass so you can see the color. By setting the height & width on td div rather than only .draggable, it works as expected.

    $(document).ready(function() {
        $(".draggable").draggable({ 
            cursor: "crosshair", 
            revert: "invalid"
        });
    
        $(".drop").droppable({ 
            accept: ".draggable", 
            activeClass: "over",
            drop: function(event, ui) {
                console.log("drop");
                $(this).removeClass("border").removeClass("over");
                var dropped = ui.draggable;
                var droppedOn = $(this);
                $(dropped).detach().css({top: 0,left: 0}).appendTo(droppedOn);    
            }
        });
    
        $(".drop").sortable();
    });
    .over {
      border: solid 4px #ACFA58;
    }
    td div {
      width:150px;
      height:75px;
    }
    .draggable {
      border: solid 4px red;
    }
    #timetable{
      margin-top:50px;
      width:100%;
      border-collapse:collapse;
      border: 1px solid black;
    }
    #timetable th{
      text-align:center;
    }
    #timetable td{
      width:150px;
      height:75px;
      border: 1px solid black;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="http://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>
    
    <div id="page-wrapper">
        <table id="timetable" >
                <thead>
                    <tr>
                        <th>1</th>
                        <th>2</th>
                        <th>3</th>
                        <th>4</th>
                        <th>5</th>
                        <th>6</th>
                        <th>7</th>
                    </tr>
                </thead>
                <tbody id="containment">
                    <tr>
                        <td><div class="drop"><div class="draggable"></div></div></td>
                        <td><div class="drop"></div></td>
                        <td><div class="drop"></div></td>
                        <td><div class="drop"></div></td>
                        <td><div class="drop"></div></td>
                        <td><div class="drop"></div></td>
                        <td><div class="drop"></div></td>
                    </tr>
                    <tr>
                        <td><div class="drop"></div></td>
                        <td><div class="drop"></div></td>
                        <td><div class="drop"></div></td>
                        <td><div class="drop"></div></td>
                        <td><div class="drop"></div></td>
                        <td><div class="drop"></div></td>
                        <td><div class="drop"></div></td>
                    </tr>
                </tbody>
            </table>
    </div><!-- /#page-wrapper -->