使用 jQuery UI sortable 对多个表行进行排序

问题描述 投票:0回答:3

我正在使用 jQuery UI 附带的可排序函数来对表行重新排序。它工作正常,这里是一个 JSFiddle,下面是我的 HTML 和 JS

<table style="width: 100%;">
  <thead>
    <tr>
      <th>ID</th>
      <th>Fruit</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>Apple</td>
    </tr>
      <tr>
      <td>2</td>
      <td>Pear</td>
    </tr>
    <tr class="sticky">
      <td>3</td>
      <td>Banana</td>
    </tr>
      <tr>
      <td>4</td>
      <td>Raspberry</td>
    </tr>
      <tr>
      <td>5</td>
      <td>Mango</td>
    </tr>
  </tbody>
</table>


$(function(){
    $("table tbody").sortable();
});

但是我希望能够同时拖动多行。基本上,当您拖动

tr
时,如果其正下方的
tr
具有
sticky
类,则需要将
tr
与其一起拖动。因此,在我的示例中,任何时候您想要拖动并重新排序“Pear”行,下面的“Banana”行都会随之移动。

我认为可以使用辅助函数来做到这一点,但我真的不知道从哪里开始。如果有人可以建议我最好的方法并为我指明正确的方向,那就太好了。

javascript jquery jquery-ui
3个回答
3
投票

您可以使用

start
事件检查下一个
tr
class
是否为
sticky
并将其插入到
stop
事件上拖动的项目之后。我正在使用
css
方法来为“粘性”项目设置动画。

$(function() {
  var $draggedItem, $stickyItem, itemWidth, itemHeight;
  $("table tbody").sortable({
    start: function(event, ui) {
      $draggedItem = $(ui.item[0]);
      //Store the constant width and height values in variables.
      itemWidth = $draggedItem.width();
      itemHeight = $draggedItem.height();
      //next is called twice because a hidden "tr" is added when sorting.
      var $nextChild = $(ui.item[0]).next().next();
      if ($nextChild.hasClass('sticky')) {
        $stickyItem = $nextChild;
      }
      else {
        $stickyItem = undefined;
      }
    },
    sort: function() {
      if ($stickyItem != undefined) {
        //Set the css to match the dragged item's css, with the exception of "top", which includes an offset.
        $stickyItem.css({
          "z-index": $draggedItem.css('z-index'),
          "position": "absolute",
          "width": itemWidth,
          "height": itemHeight,
          "left": $draggedItem.css('left'),
          "top": $draggedItem.position().top + itemHeight,
        });
      }
    },
    stop: function() {
      if ($stickyItem != undefined) {
        $stickyItem.insertAfter($draggedItem);
        //Remove the style attribute to reset to thed default style.
        $stickyItem.removeAttr('style');
      }
    }
  });
});

小提琴演示

注意: 如果存在粘性项目,您可以通过仅绑定

sort
stop
事件来进一步改进上述内容。


0
投票

对于那些想要防止在粘性行与其上方的行之间插入行的人,这里是 Yass 解决方案的稍微修改版本:

$(function () {
    let $draggedItem, $stickyItem, itemWidth, itemHeight, cancelSortable;
    $("table tbody").sortable({
        start: function (event, ui) {
            $draggedItem = $(ui.item[0]);
            //Store the constant width and height values in variables.
            itemWidth = $draggedItem.width();
            itemHeight = $draggedItem.height();
            //next is called twice because a hidden "tr" is added when sorting.
            let $nextChild = $(ui.item[0]).next().next();
            if ($nextChild.hasClass('sticky')) {
                $stickyItem = $nextChild;
            } else {
                $stickyItem = undefined;
            }
        },
        sort: function (event, ui) {
            if ($stickyItem !== undefined) {
                //Set the css to match the dragged item's css, with the exception of "top", which includes an offset.
                $stickyItem.css({
                    "z-index": $draggedItem.css('z-index'),
                    "position": "absolute",
                    "width": itemWidth,
                    "height": itemHeight,
                    "left": $draggedItem.css('left'),
                    "top": $draggedItem.position().top + itemHeight,
                });
            }
            if (ui.placeholder.next() !== undefined && ui.placeholder.next().hasClass("sticky")) {
                ui.placeholder.hide();
                cancelSortable = true;
            } else {
                ui.placeholder.show();
                cancelSortable = false;
            }
        },
        stop: function () {
            if (cancelSortable) {
                $(this).sortable("cancel");
            }
            if ($stickyItem !== undefined) {
                $stickyItem.insertAfter($draggedItem);
                //Remove the style attribute to reset to the default style.
                $stickyItem.removeAttr('style');
            }
        }
    });
});

0
投票

可对两行以上进行分组的可排序选项(编辑连续两次使用 next() 的“start”参数中的行):

let $nextChildren = $(ui.item[0]).nextAll(".sticky:visible").not(".ui-sortable-placeholder");
if ($(ui.item[0]).next().next().hasClass('sticky')) {
$stickyItem = $nextChildren;
}

此代码获取所有具有“粘性”类的下一行,即使它们之间存在没有该类的行。

© www.soinside.com 2019 - 2024. All rights reserved.