jQuery UI Sorting with table and tr width


155

我正在使用可排序的jQuery UI,以使我的表网格可排序。该代码似乎可以正常工作,但是因为我没有在tds上添加width ,所以当我拖动s时tr它会缩小内容。

例如; 如果我开始拖动时表格行为500px,则该行变为300px。我认为是因为没有在网格中定义宽度而发生了。那是因为我正在为tds(fixliquid)使用两个类。

fix类使得td等于所述内容的宽度和liquid使td宽度100%。这是我的网格表方法,无需为tds 分配宽度。

知道如何使用我的方法进行可排序的工作吗?


3
雅罗斯拉夫的答案是真正的MVP!
布拉德,2015年

我遇到了同样的问题,我认为@Yaroslav对于OP处理的表格有正确的答案
doz87

Answers:


254

我在这里找到了答案。

我对其进行了少许修改以克隆该行,而不是为原始行添加宽度:

  helper: function(e, tr)
  {
    var $originals = tr.children();
    var $helper = tr.clone();
    $helper.children().each(function(index)
    {
      // Set helper cell sizes to match the original sizes
      $(this).width($originals.eq(index).width());
    });
    return $helper;
  },

@Dave James Miller您将如何使占位符选项起作用?
shaun5'3-3-26

5
戴夫,感谢您的分享,我做了一个jsFiddle来展示原始,修改和未应用修复之间的区别:jsfiddle.net/bgrins/tzYbU。我还将用您的解决方案更新原始帖子。
布莱恩·格林斯特德

9
这很好,但是我认为仍然存在一个小问题。当您拖放行时,由于缺少行,表的其余列可能会更改宽度。我猜他们的宽度也需要固定...
Jez 2012年

1
这节省了我很多工作。应该将其标记为正确答案。
安德鲁·贝萨

3
我发现宽度导致填充单元格不正确。我换了$(this).width($originals.eq(index).outerWidth());
Barry Carlyon

166

我认为它可以帮助您:

.ui-sortable-helper {
    display: table;
}

13
这不是最高答案吗?一行简单的CSS为我修复了它。
jcrowson 2015年

8
我同意!您不会相信一排简单的CSS如何解决可排序表的问题-Stackoverflow专家感到困惑!
Brade 2015年

3
这就是答案。感谢@Yaroslav
Steffi

3
这不是一般的解决方案,并且会导致拖动行的外观有所不同
Tomas M,

13
这个解决方案非常好,但是会影响其他不在列表中的列表。我的建议是您修改答案以使其更具体。像这样=>表tr.ui-sortable-helper {display:table!important; }
拉斐尔·戈麦斯Francisco

29

这里选择的答案是一个非常好的解决方案,但是它有一个严重的错误,这在原始的JS小提琴(http://jsfiddle.net/bgrins/tzYbU/)中很明显:尝试拖动最长的行(上帝保佑您,先生(Rosewater),其余单元格宽度会崩溃。

这意味着仅固定所拖动单元格上的单元格宽度是不够的-您还需要固定表格上的宽度。

$(function () {
    $('td, th', '#sortFixed').each(function () {
        var cell = $(this);
        cell.width(cell.width());
    });

    $('#sortFixed tbody').sortable().disableSelection();
});

JS小提琴:http//jsfiddle.net/rp4fV/3/

这解决了在拖动第一列后表格崩溃的问题,但是引入了一个新的问题:如果更改表格的内容,则现在单元格大小已固定。

要在添加或更改内容时解决此问题,您需要清除设置的宽度:

$('td, th', '#sortFixed').each(function () {
    var cell = $(this);
    cell.css('width','');
});

然后添加您的内容,然后再次固定宽度。

这仍然不是一个完整的解决方案,因为(特别是在一个表中)您需要放置占位符。为此,我们需要在启动时添加一个构建占位符的函数:

$('#sortFixed tbody').sortable({
    items: '> tr',
    forcePlaceholderSize: true,
    placeholder:'must-have-class',
    start: function (event, ui) {
        // Build a placeholder cell that spans all the cells in the row
        var cellCount = 0;
        $('td, th', ui.helper).each(function () {
            // For each TD or TH try and get it's colspan attribute, and add that or 1 to the total
            var colspan = 1;
            var colspanAttr = $(this).attr('colspan');
            if (colspanAttr > 1) {
                colspan = colspanAttr;
            }
            cellCount += colspan;
        });

        // Add the placeholder UI - note that this is the item's content, so TD rather than TR
        ui.placeholder.html('<td colspan="' + cellCount + '">&nbsp;</td>');
    }
}).disableSelection();

JS小提琴:http//jsfiddle.net/rp4fV/4/


谢谢,您节省了我的时间
super pantera

这里的占位符技术是杀手!!彻底解决了我的问题。
jessegavin 2014年

1
此解决方案实际上非常好,并且占位符技术非常可靠,我认为这应该是选择的答案。
克里斯·詹姆士

1
当您的行数很高时,这仍然会导致令人不快的行为。所有其他行将隐藏在它后面。我将其添加到启动方法中:$(".must-have-class").css("height", $(ui.item).outerHeight());
Itzik Ben Hutta

6

似乎克隆行在IE8上效果不佳,但原始解决方案可以。

经过jsFiddle测试。


感谢您设置jsFiddle。我要使用原始解决方案,因为正如Jez指出的那样,其他行单元格在拖动行时可能会改变宽度。
罗杰2013年

4

当您准备好对表进行排序时,请调用以下代码,这将确保您的td元素具有固定的且不会破坏表结构。

 $(".tableToSort td").each(function () {
            $(this).css("width", $(this).width());
        });  

是的,这与我的答案几乎相同,尽管我的工作原理th和一样td。它修复了拖动的行折叠和表折叠,但是以固定宽度为代价。
基思(Keith)

1

jsFiddle

经过许多不同的尝试,我只是尝试了一个简单的解决方案,该解决方案完善了Dave James Miller的解决方案,以防止在拖动最大行时缩小表。我希望这会有所帮助:)

// Make sure the placeholder has the same with as the orignal
var start = function(e, ui) {
    let $originals = ui.helper.children();
    ui.placeholder.children().each(function (index) {
        $(this).width($originals.eq(index).width());
    });
}
// Return a helper with preserved width of cells
var helper = function(e, tr) {
    let $helper = tr.clone();
    let $originals = tr.children();
    $helper.children().each(function (index) {
        $(this).width($originals.eq(index).outerWidth(true));
    });
    return $helper;
};

0

Keith的解决方案还不错,但在Firefox中造成了一些破坏,但并没有增加colspan的数量,但提示了它们。(旧的js字符串类型膝盖疼痛)

替换此行:

 cellCount += colspan;

与:

 cellCount += colspan-0;

解决问题。(由于js被迫将变量视为数字而不是字符串)


0

Dave James Miller的答案对我有用,但是由于容器div在我的页面上的布局,用鼠标光标拖动的帮助程序偏离了鼠标的位置。为了解决这个问题,我在辅助回调中添加了以下内容

$(document.body).append($helper);

这是添加以上行的完整回调:

helper: function (e, tr) {
  var $originals = tr.children();
  var $helper = tr.clone();
  $helper.children().each(function (index) {
    // Set helper cell sizes to match the original sizes
    $(this).width($originals.eq(index).width());
  });

  // append it to the body to avoid offset dragging
  $(document.body).append($helper);

  return $helper;
}

我会将其添加为Dave的答案的注释,但该帐户没有足够的代表。


阅读jQuery文档后,我发现sortable还带有一个“ appendTo”选项,该选项指定将助手添加到哪个元素。
Shea Riley


-1
$(function() {
    $( "#sort tbody" ).sortable({
        update: function () {
                                var order = $(this).sortable("toArray").join();
                                $.cookie("sortableOrder", order);
                        }
    });
    if($.cookie("sortableOrder")){
        var order = $.cookie("sortableOrder").split(",");
        reorder(order, $("#sort tbody"));
    }
    function reorder(aryOrder, element){
      $.each(aryOrder, function(key, val){
              element.append($("#"+val));
      });
    }
  });

1
需要更多说明!
Afsanefda

-1
.sortable({
    helper: function (e, ui) {
        ui.children().each(function () {
            $(this).width($(this).width());
        });
        return ui;
    }
});

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.