Jquery ui-sortable - 无法将tr放在空的tbody中

24

我有两个相互连接的tbody元素,可以让我在两个表格之间拖动行。一切正常,直到其中一个表格中的所有行都被删除。

当所有行都被拖到另一个表格中时,tbody的高度会减小,使得很难再将行放回去。

是否有已知的解决此问题的方法?(min-height在tbody元素上不起作用)

非常感谢您的帮助。


好问题,我正在尝试对行进行排序和移动列表,并且在空表格上遇到了相同的问题...你有进一步的解决方法吗? - Mark Redman
解决方案在这里:https://dev59.com/Amw15IYBdhLWcg3wGn5c摘要:向容器添加填充。 - Populus
12个回答

15
你可以创建一行,让其在“sortable”机制下不可见。可能最简单的方法就是使用“items”选项。
假设你的HTML代码如下:
<tbody class="sortable">
    <tr><td>stuff</td></tr>
    <tr><td>stuff</td></tr>
    <tr><td>stuff</td></tr>
    <tr class="sort-disabled"><td></td></tr>
</tbody>

然后在jQuery中你可以有:

$('.sortable').sortable({
    items: ">*:not(.sort-disabled)"
});

这有点像是一个hack,但是我认为如果你尝试使用这种变体(在CSS中给类名为.sort-disabled的行添加一些高度等)你可能会找到适合自己的东西。你也可以尝试将一个类名为.sort-disabled的行放在最前面和最后面,以使中间位置成为拖放目标。

希望这可以帮助你!


最终我做了这个。效果非常好。我只是使用了“tr:not(.padder)”因为我认为“>”是隐含的。 - Henrik N
实际上,我发现一个很烦人的缺点:你无法保证在填充行之前或之后丢弃项目。这意味着样式可能会变得不一致,特别是如果您有多个表格,其中一些表格在填充器以上,而另一些表格在填充器以下。 - Henrik N
1
原来,如果您将填充器(.sort-disabled)放在第一个元素位置,上述问题就不会出现。对于空列表,您只能删除填充器下方的行,而不能删除其上方的行。因此,如果填充器位于第一位,它将保持在第一位。如果它是最后一个,则会改变位置,使您的空格不一致。 - Henrik N
不一致的空格问题可以通过使用.sort-disabled:only-child td {height:.5rem}来解决。只有在表格为空时才会显示空格。 - Ajax

8

当表格,特别是tbody为空时,很难强制设置其高度。所以我采用了以下方式。

<div class="ui-widget sortablecolumn">
   <table>
   </table>
</div>  

$( '.sortablecolumn').sortable(
{
   connectWith: '.sortablecolumn',
   items: 'table > tbody > *',
   receive: function(ev, ui) {
        ui.item.parent().find('table > tbody').append(ui.item);
   }
});
$( '.sortablecolumn' ).disableSelection();

重点是 items 选择器和 receive 事件处理程序,其中添加的项目被移动到表格主体中。

现在它运行良好。


这是最好的答案。没有任何黑客技巧,只需添加另一个容器 div 就解决了。谢谢! - MazarD
1
我通过使用 var $parent = ui.item.parent(); if($parent.is('table')){$parent.find('tbody').append(ui.item);} 解决了我的问题,这与您的解决方案非常接近。 - Ismael Miguel

4

我有同样的问题,通过以下方法已经部分解决:

$('table').sortable(
{
    connectWith: 'table',
    items: 'tbody tr'
});

这使我可以将行移动到一个空表中,看起来很好,但是该元素被插入在 tbody 之后而不是其中。我认为 Danny Robert 的回答适用于我,但我也很想看到一种非 hack 的解决方案。

3
你可以通过添加以下代码来解决这个问题:receive: function(e, ui){ $(this).find("tbody").append(ui.item); } - Ryan Vettese

4

请查看我的文章 - 您可以通过在单击时附加方法来向空容器添加高度来解决此问题:

function sortAndDrag() {
 
    //show BEFORE sortable starts
     $(".sortableClass").bind('click mousedown', function(){
          $(".sortableClass").each(function (c) {
                if ($("tbody", this).size() == 0) {
                    $(this).addClass("aClassWhichGivesHeight")
                }
            })
     });
 
    //enable sortable
    $(".sortableClass").sortable({
        connectWith: ".sortableClass",
        stop: function (a, d) {
            $("tbody").removeClass("aClassWhichGivesHeight");
        }
    });
 
}

类似这样的吗?


在tbody中添加高度是没有用的,因为如果没有内容,tbodys将不会显示 - 即使设置了display: table-row-group或类似的属性也是如此。 - Deebster

2

以下是我解决无法在空tbody中删除tr的问题的方法:

$(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>');
    }
}

2

我知道这个问题已经被标记为“已回答”,但是我还想添加另一种方法来解决这个问题。

我的做法是先检查列表是否为空,如果是,则创建一个新的行元素并将其注入到tbody中。我在td中放置了一个类似“没有更多项目”的消息。

一旦将项目拖放到“空”列表中,空消息将被销毁。

我使用Mootools,因此缺少示例代码。


1

1
简单解决方案(纯CSS):
tbody:after {
    content:" ";
    height:30px;
}

空格不一定是标准空格。它可能是像下面这样的看不见的空字符: 不可见字符 - ASCII

在Firefox和Chrome中对我有效。


工作只完成了一半,因为现在可以删除,但是在tbody之外:<tbody></tbody>[这里] - Meloman

0
在我的情况下,当没有项目时,表格和tbody会折叠为大小0x0。有效的方法是为表格和tbody提供一些最小尺寸,例如:
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;
}

这就是所需的全部。


0

我使用:

$(document).ready(function(){
      $( "#sortable1 tbody, #sortable2 tbody" ).sortable({
      connectWith: ".connectedSortable",
      remove: function(event, ui){ if($(this).html().replace(/^\s+/, "") == '') { $(this).html('<tr class="tmp_tr nobr"><td colspan="7">&nbsp;</td></tr>'); }},
      update: function( event, ui ) {$(this).find('.tmp_tr').remove();},
    }).disableSelection();

});


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接