Jquery ui-sortable - unable to drop tr in empty tbody

Viewed 10758

I have two connected tbody elements allowing me to drag rows between two tables. Everything works fine until all rows are removed from either table.

When all rows have been dragged to the other table the tbody height decreases making it (near)impossible to drop rows back inside.

Is there a known workaround for this problem? (min-height doesn't work on a tbody element)

Many thanks in advance.

11 Answers

Here's how I solved the issue with being unable to drop a tr in an empty tbody:

$(function() {

    var sort1 = $('#sort1 tbody');
    var sort2 = $('#sort2 tbody');

   sizeCheck(sort1);
   sizeCheck(sort2);

   //Start the jQuery Sortable for Active and Fresh Promo Tables
   $("#sort1 tbody, #sort2 tbody").sortable({

     items: ">*:not(.sort-disabled)",

     deactivate: function(e, ui) {

        sizeCheck(sort1);
        sizeCheck(sort2);

     },
     //Connect tables to pass data
     connectWith: ".contentTable tbody"

   }).disableSelection();

});

//Prevent empty tbody from not allowing items dragged into it

function sizeCheck(item){
    if($(item).height() == 0){
        $(item).append('<tr class="sort-disabled"><td></td></tr>');
    }
}

In my case it was about table and tbody collapsing to size 0x0 when no items present. What worked was providing some minimal size for the table and tbody, like this:

table.items-table {
    width: 100%; /*needed for dropping on empty table to work - can be any non-zero value*/
}

table.items-table >tbody { /*needed for dropping on empty table to work */
    display: block;
    min-height: 10px;
}

That was all that was needed.

Based on Ismael Miguel comment on Cetnar answer, here is my working solution.

  • I send different ajax call for each table (urgent, normal, low priority tasks), and it works fine with empty table dropping.
  • In database I update all tasks present in the array sent by ajax with a sorting column.

3 tables sortable with tr and sorted in database

jQuery code :

$('.draggable-zone').sortable({
    items:       'tr.draggable',
    helper:      'clone',
    appendTo:    'body',
    connectWith: '.draggable-zone',
    update: function(e, ui) {
        $.ajax({
            url:  '/inve/new/sort', 
            type: 'POST',
            data: $(this).sortable('serialize', { 
                key: $(this).attr('data-partl')
            })
        });
    },
    receive: function(e, ui) {
        var $parent = ui.item.parent(); 
        if($parent.is('table')){
            $parent.find('tbody').append(ui.item);
        }
    }
});

HTML / Smarty template (1 table only) :

<table class="table table-striped table-hover table-bordered draggable-zone" data-partl="normal[]">
    <tbody>
        {foreach $data.normal as $task}
            <tr class="draggable" id="sort_{$task.id}">
                <td><b>{$task.title}</b></td>
                ...
            </tr>
        {/foreach}
    </body>
</table>
...
Related