使用拖放重新排序HTML表行

时间:2010-01-15 15:55:12

标签: jquery

我有一个jQuery函数来上下移动表格行。我不知道如何保存数据,也不知道每行的位置。我正在使用PHP来显示表格行。

当用户重新排序表行时,如何获取每个表行位置值?

7 个答案:

答案 0 :(得分:85)

jQuery UI sortable plugin提供拖放重新排序。保存按钮可以提取每个项目的ID,以创建这些ID的逗号分隔字符串,并添加到隐藏文本框中。使用异步回发将文本框返回到服务器。

fiddle example重新排序表格元素,但不会将它们保存到数据库中。

可排序插件使用一行代码将任何列表转换为可排序列表。如果您想使用它们,它还提供CSS和图像,以便为可排序列表提供视觉效果(请参阅我链接到的示例)。但是,开发人员必须提供代码以检索新订单中的项目。我将列表中每个项目的唯一ID嵌入为HTML属性,然后通过jQuery检索这些ID。

例如:

// ----- code executed when the document loads
$(function() {
    wireReorderList();
});

function wireReorderList() {
    $("#reorderExampleItems").sortable();
    $("#reorderExampleItems").disableSelection();
}

function saveOrderClick() {
    // ----- Retrieve the li items inside our sortable list
    var items = $("#reorderExampleItems li");

    var linkIDs = [items.size()];
    var index = 0;

    // ----- Iterate through each li, extracting the ID embedded as an attribute
    items.each(
        function(intIndex) {
            linkIDs[index] = $(this).attr("ExampleItemID");
            index++;
        });

    $get("<%=txtExampleItemsOrder.ClientID %>").value = linkIDs.join(",");
}

答案 1 :(得分:18)

显然这个问题很难描述OP的问题,但是这个问题是拖动重新排序表行的最佳搜索结果,所以这就是我要回答的问题。我没有兴趣为简单的东西引入jQuery UI,所以这里只是一个jQuery解决方案:

<style>
.grab { cursor: grab; }
.grabbed { box-shadow: 0 0 13px #000; }
.grabCursor, .grabCursor * { cursor: grabbing !important; }
</style>

<table>
<tr><th>...</th></tr>
<tr><td class="grab">&#9776;</td><td>...</td></tr>
</table>

<script>
$(".grab").mousedown(function (e) {
    var tr = $(e.target).closest("TR"), si = tr.index(), sy = e.pageY, b = $(document.body), drag;
    if (si == 0) return;
    b.addClass("grabCursor").css("userSelect", "none");
    tr.addClass("grabbed");
    function move (e) {
        if (!drag && Math.abs(e.pageY - sy) < 10) return;
        drag = true;
        tr.siblings().each(function() {
            var s = $(this), i = s.index(), y = s.offset().top;
            if (i > 0 && e.pageY >= y && e.pageY < y + s.outerHeight()) {
                if (i < tr.index())
                    tr.insertAfter(s);
                else
                    tr.insertBefore(s);
                return false;
            }
        });
    }
    function up (e) {
        if (drag && si != tr.index()) {
            drag = false;
            alert("moved!");
        }
        $(document).unbind("mousemove", move).unbind("mouseup", up);
        b.removeClass("grabCursor").css("userSelect", "none");
        tr.removeClass("grabbed");
    }
    $(document).mousemove(move).mouseup(up);
});
</script>

注意si == 0i > 0会忽略第一行,对我来说,第一行包含TH个标记。用“拖动完成”逻辑替换alert

答案 2 :(得分:7)

我用得很好

<script>
    $(function () {

        $("#catalog tbody tr").draggable({
            appendTo:"body",
            helper:"clone"
        });
        $("#cart tbody").droppable({
            activeClass:"ui-state-default",
            hoverClass:"ui-state-hover",
            accept:":not(.ui-sortable-helper)",
            drop:function (event, ui) {
                $('.placeholder').remove();
                row = ui.draggable;
                $(this).append(row);
            }
        });
    });
</script>

答案 3 :(得分:3)

您可能需要查看jQuery Sortable。我用它来重新排序表行。

答案 4 :(得分:2)

易于插件jquery TableDnd

$(document).ready(function() {

    // Initialise the first table (as before)
    $("#table-1").tableDnD();

    // Make a nice striped effect on the table
    $("#table-2 tr:even').addClass('alt')");

    // Initialise the second table specifying a dragClass and an onDrop function that will display an alert
    $("#table-2").tableDnD({
        onDragClass: "myDragClass",
        onDrop: function(table, row) {
            var rows = table.tBodies[0].rows;
            var debugStr = "Row dropped was "+row.id+". New order: ";
            for (var i=0; i<rows.length; i++) {
                debugStr += rows[i].id+" ";
            }
            $(table).parent().find('.result').text(debugStr);
        },
        onDragStart: function(table, row) {
            $(table).parent().find('.result').text("Started dragging row "+row.id);
        }
    });
});

插件(TableDnD): https://github.com/isocra/TableDnD/

演示: http://jsfiddle.net/DenisHo/dxpLrcd9/embedded/result/

CDN: https://cdn.jsdelivr.net/jquery.tablednd/0.8/jquery.tablednd.0.8.min.js

答案 5 :(得分:0)

基于@tim的提琴,此版本加强了范围和格式,并转换了bind()-> on()。它旨在绑定到专用的td作为句柄而不是整个行。在我的用例中,我有input个字段,因此“拖动行中的任何地方”的方法让人感到困惑。

经过测试可以在桌面上使用。移动触摸只能部分成功。由于某种原因,它无法在SO的可运行代码段上正确运行...

let ns = {
  drag: (e) => {
    let el = $(e.target),
      d = $('body'),
      tr = el.closest('tr'),
      sy = e.pageY,
      drag = false,
      index = tr.index();

    tr.addClass('grabbed');

    function move(e) {
      if (!drag && Math.abs(e.pageY - sy) < 10)
        return;
      drag = true;
      tr.siblings().each(function() {
        let s = $(this),
          i = s.index(),
          y = s.offset().top;
        if (e.pageY >= y && e.pageY < y + s.outerHeight()) {
          i < tr.index() ? s.insertAfter(tr) : s.insertBefore(tr);
          return false;
        }
      });
    }

    function up(e) {
      if (drag && index !== tr.index())
        drag = false;

      d.off('mousemove', move).off('mouseup', up);
      //d.off('touchmove', move).off('touchend', up); //failed attempt at touch compatibility
      tr.removeClass('grabbed');
    }
    d.on('mousemove', move).on('mouseup', up);
    //d.on('touchmove', move).on('touchend', up);
  }
};

$(document).ready(() => {
  $('body').on('mousedown touchstart', '.drag', ns.drag);
});
.grab {
  cursor: grab;
  user-select: none
}

tr.grabbed {
  box-shadow: 4px 1px 5px 2px rgba(0, 0, 0, 0.5);
}

tr.grabbed:active {
  user-input: none;
}

tr.grabbed:active * {
  user-input: none;
  cursor: grabbing !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
  <thead>
    <tr>
      <th></th>
      <th>Drag the rows below...</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td class='grab'>&vellip;</td>
      <td><input type="text" value="Row 1" /></td>
    </tr>
    <tr>
      <td class='grab'>&vellip;</td>
      <td><input type="text" value="Row 2" /></td>
    </tr>
    <tr>
      <td class='grab'>&vellip;</td>
      <td><input type="text" value="Row 3" /></td>
    </tr>
  </tbody>
</table>

答案 6 :(得分:-3)

感谢Jim Petkus确实给了我一个很棒的答案。但我试图解决我自己的脚本,而不是将其更改为另一个插件。我主要关注的是不使用独立的插件,只使用jquery核心做我想做的事情!

并猜测我找到了什么问题。

var title = $("em").attr("title");
$("div").text(title);

这是我添加到我的脚本和吹嘘代码到我的html部分:

<td> <em title=\"$weight\">$weight</em></td>

并找到每行$ weight value

再次感谢Jim Petkus