使用拖放重新排列 HTML 表格行
Posted
技术标签:
【中文标题】使用拖放重新排列 HTML 表格行【英文标题】:Reorder HTML table rows using drag-and-drop 【发布时间】:2011-01-05 13:58:53 【问题描述】:我有一个 jQuery 函数来上下移动表格行。我不知道如何保存数据,也不知道每一行的位置。我正在使用 php 来显示表格行。
当用户对表格行重新排序时,如何获取每个表格行的位置值?
【问题讨论】:
【参考方案1】: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(",");
【讨论】:
如果您更仔细地检查我的示例,代码与您实际对其进行排序的方式无关(在您的情况下,只需查询 tr 而不是 li 来获取您的行)。您可以通过将列表存储为 html 属性然后使用 jquery attr() 以排序顺序检索值来从列表中检索您想要的任何值。我将进一步补充说,我根本不欣赏你的语气。我提供了您所要求的答案,并建议您查看一种非常流行的排序方法,以防您不知道。 您的行var linkIDs = [items.size()];
未初始化大小为 items.size()
的数组。您只是在创建一个包含该大小的单个元素的数组。这会在 items.each 的第一次迭代中被覆盖..
Jim,我怎样才能将这个数组保存在数据库 mysql 中?你知道哪里有关于它的教程吗?
效果很好。谢谢。【参考方案2】:
显然这个问题描述了 OP 的问题,但这个问题是拖动以重新排序表行的***搜索结果,所以这就是我要回答的问题。我对为这么简单的事情引入 jQuery UI 不感兴趣,所以这是一个仅 jQuery 的解决方案:
$(".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);
);
.grab
cursor: grab;
.grabbed
box-shadow: 0 0 13px #000;
.grabCursor,
.grabCursor *
cursor: grabbing !important;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<th></th>
<th>Table Header</th>
</tr>
<tr>
<td class="grab">☰</td>
<td>Table Cell 1</td>
</tr>
<tr>
<td class="grab">☰</td>
<td>Table Cell 2</td>
</tr>
<tr>
<td class="grab">☰</td>
<td>Table Cell 3</td>
</tr>
</table>
注意si == 0
和i > 0
忽略第一行,对我来说它包含TH
标签。将 alert
替换为您的“拖动完成”逻辑。
【讨论】:
伟大的工作人员。这让我很快乐。如果有人觉得它有用,这是我的小提琴。 jsfiddle.net/7ko9ay1e 我们如何为多行做到这一点【参考方案3】:我用得很好
<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>
【讨论】:
【参考方案4】:易于插件 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
【讨论】:
嗨,这个插件也可以和 JSF 一起使用吗?【参考方案5】:您可能想查看jQuery Sortable。我用它来重新排序表格行。
【讨论】:
谢谢,但你有没有读过我的问题?!我不是在寻找新的 d&d 插件。只是想知道如何解决我当前脚本在获取每一行值时遇到的问题 @Ghazanfari,我在你的问题中看不到任何人都可以解决的脚本。【参考方案6】:在@tim 的基础上,这个版本收紧了范围和格式,并转换了bind()
-> on()
。它旨在绑定专用的td
作为句柄而不是整行。在我的用例中,我有 input
字段,因此“拖动行中的任意位置”方法让人感到困惑。
测试在桌面上工作。移动触控仅取得部分成功。由于某种原因,它无法在 SO 的可运行 sn-p 上正确运行...
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'>⋮</td>
<td><input type="text" value="Row 1" /></td>
</tr>
<tr>
<td class='grab'>⋮</td>
<td><input type="text" value="Row 2" /></td>
</tr>
<tr>
<td class='grab'>⋮</td>
<td><input type="text" value="Row 3" /></td>
</tr>
</tbody>
</table>
【讨论】:
以上是关于使用拖放重新排列 HTML 表格行的主要内容,如果未能解决你的问题,请参考以下文章
通过拖动委托向上或向下拖动一行来重新排列表格中的部分(iOS 11)
通过使用拖动委托向上或向下拖动一行来重新排列表格中的部分(iOS 11)
有没有办法在 devexpress TreeListControl 中通过拖放重新排列节点时预览元素的位置?