Jquery ui-sortable - 无法在空 tbody 中删除 tr

Posted

技术标签:

【中文标题】Jquery ui-sortable - 无法在空 tbody 中删除 tr【英文标题】:Jquery ui-sortable - unable to drop tr in empty tbody 【发布时间】:2011-04-14 15:58:51 【问题描述】:

我有两个连接的 tbody 元素,允许我在两个表之间拖动行。一切正常,直到从任一表中删除所有行。

当所有行都被拖到另一个表时,tbody 高度会降低,从而(几乎)不可能将行放回内部。

是否有针对此问题的已知解决方法? (最小高度不适用于 tbody 元素)

非常感谢。

【问题讨论】:

好问题,我正在尝试对行和移动列表进行排序并在空表中遇到相同的问题...您对此有进一步了解吗? 解决方案在这里:***.com/questions/6832687/… 摘要:为容器添加填充 【参考方案1】:

您可以做的是创建一个对“可排序”机制不可见的行。可能最简单的方法是使用“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)"
);

这有点小技巧,但我认为如果您尝试使用这种变体(在 CSS 等中给 .sort-disabled 行一些高度),您可能会找到适合您的东西。您也可以尝试在第一行和最后一行设置一个 .sort-disabled 行,这样中间的位置就是放置目标。

希望这会有所帮助!

【讨论】:

最终这样做了。工作得很好。我只做了“tr:not(.padder)”,因为我相信“>”是隐含的。 实际上,我发现了一个令人讨厌的缺点:您无法保证是在填充行之前还是之后丢弃项目。这意味着样式可能会变得不一致,特别是如果您有多个表,其中一些在填充器上方有行,而一些在其下方有行。 原来如果你把padder (.sort-disabled) 作为第一个元素,上面的不是问题。使用空列表,您只能将行放在填充器下方,而不能放在它上方。因此,如果 padder 是第一个,它将保持第一个。如果是最后一个,它将改变位置,使您的空格不一致。 空格不一致的问题可以通过.sort-disabled:only-child td height:.5rem来解决。空白仅在表格为空时显示。【参考方案2】:

我有同样的问题,并设法通过这样做解决了一半:

$('table').sortable(

    connectWith: 'table',
    items: 'tbody tr'
);

这允许我将行移动到一个空表中,它看起来不错,但是元素是在 tbody 之后插入的,而不是在它里面。我认为 Danny Robert 的回答对我有用,但我有兴趣看到非 hack 解决方案。

【讨论】:

您可以通过添加来解决此问题:receive: function(e, ui) $(this).find("tbody").append(ui.item); 【参考方案3】:

很难强制使用表 esp。 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 并解决了。谢谢! 我改用var $parent = ui.item.parent(); if($parent.is('table'))$parent.find('tbody').append(ui.item); 解决了我的问题,这与您所拥有的非常接近。【参考方案4】:

结帐my post about this - 您可以通过将方法附加到增加空容器高度的点击来解决:

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 添加高度无济于事,因为 tbody 不会在没有内容的情况下显示 - 即使设置了 display: table-row-group 或类似的设置。【参考方案5】:

以下是我解决无法将 tr 放入空 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>');
    

【讨论】:

【参考方案6】:

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

我所做的是检查列表是否为空,如果是,则创建一个新的行元素并将其注入到 tbody 中。我在 td 中放了一条消息,例如“No more items”。

一旦将一个项目放入“空”列表,空消息将被销毁。

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

【讨论】:

【参考方案7】:

我使用:

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

);

【讨论】:

【参考方案8】:

js

$(".sortable").sortable(
    items: 'tbody > tr',
    connectWith: ".sortable"
);

css

.sortable 
    background-color: silver;    
    height: 10px;


.sortable td  background-color: white; 

html

<table class='sortable'>    
    <tbody>
        <tr><td colspan="2" class="drop-row" style="display: none;"></td></tr>
    </tbody>    
</table>

更多细节,甚至更好的代码 https://devstuffs.wordpress.com/2015/07/31/jquery-ui-sortable-with-connected-tables-and-empty-rows/

【讨论】:

【参考方案9】:

简单的解决方案(纯 CSS):

tbody:after 
    content:" ";
    height:30px;

空格不是标准空格。它是一个不可见的空白字符,如下所示: Invisible characters - ASCII

在 FF 和 Chrome 中为我工作。

【讨论】:

工作中途,因为现在可以丢弃但在 tbody 之外:&lt;tbody&gt;&lt;/tbody&gt;[here]【参考方案10】:

在我的情况下,当没有项目存在时,table 和 tbody 折叠到大小为 0x0。有效的是为 table 和 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;

这就是我们所需要的。

【讨论】:

【参考方案11】:

根据 Ismael Miguel 对 Cetnar 答案的评论,这是我的工作解决方案。

为每个表发送不同的 ajax 调用(紧急、正常、低 优先任务),它可以很好地处理空表删除。 在数据库中,我更新了 ajax 发送的数组中的所有任务 sorting 专栏。

jQuery 代码:

$('.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 模板(仅限 1 个表格):

<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>
...

【讨论】:

以上是关于Jquery ui-sortable - 无法在空 tbody 中删除 tr的主要内容,如果未能解决你的问题,请参考以下文章

使用jquery在空输入字段中获取占位符的值?

Angular ui-sortable + angular-gridster

我怎样才能使它只有一个空状态或 ui-sortable 显示的放置目标占位符?

两个带有 angular-ui/ui-sortable 的连接列表,在一个中禁用占位符,同时在另一个中启用它

无法从列表视图中获取项目位置:尝试在空对象引用上调用虚拟方法...

尝试扩展 SonataMediaBundle 时出错“无法在空变量上调用方法(“id”)”