HTML 拖放可排序表格
-
09-06-2019 - |
题
您是否曾经想过拥有一个 HTML 拖放式可排序表格,可以在其中对行和列进行排序?我知道这是我愿意为之而死的事情。有很多可排序的列表,但找到可排序的表似乎是不可能找到的。
我知道您可以非常接近 script.aculo.us 提供的工具,但我遇到了一些跨浏览器问题。
解决方案
我用过 dhtmlxGrid 在过去。除此之外,它还支持拖放行/列、客户端排序(字符串、整数、日期、自定义)和多浏览器支持。
回复评论:不,没有找到更好的东西 - 只是从那个项目继续前进。:-)
其他提示
我使用了 jQuery UI 的可排序插件,效果很好。类似这样的标记:
<table id="myTable">
<thead>
<tr><th>ID</th><th>Name</th><th>Details</th></tr>
</thead>
<tbody class="sort">
<tr id="1"><td>1</td><td>Name1</td><td>Details1</td></tr>
<tr id="2"><td>2</td><td>Name1</td><td>Details2</td></tr>
<tr id="3"><td>3</td><td>Name1</td><td>Details3</td></tr>
<tr id="4"><td>4</td><td>Name1</td><td>Details4</td></tr>
</tbody>
</table>
然后在 JavaScript 中
$('.sort').sortable({
cursor: 'move',
axis: 'y',
update: function(e, ui) {
href = '/myReorderFunctionURL/';
$(this).sortable("refresh");
sorted = $(this).sortable("serialize", 'id');
$.ajax({
type: 'POST',
url: href,
data: sorted,
success: function(msg) {
//do something with the sorted data
}
});
}
});
这会将项目 ID 的序列化版本 POST 到给定的 URL。然后,该函数(在我的例子中为 PHP)会更新数据库中的商品订单。
大卫·赫吉的回答对我来说最有用。它可以稍微简洁一些:
var sort = function(event, ui) {
var url = "/myReorderFunctionURL/" + $(this).sortable('serialize');
$.post(url, null,null,"script"); // sortable("refresh") is automatic
}
$(".sort").sortable({
cursor: 'move',
axis: 'y',
stop: sort
});
对我有用,具有相同的标记。
大多数框架(Yui、MooTools、jQuery、Prototype/Scriptaculous 等)都具有可排序列表功能。对每一个都进行一些研究,然后选择最适合您需求的一个。
如果您不介意 Java,有一个非常方便的 GWT 库,名为 GWT免打扰 查看在线演示,看看它有多强大。
怎么样 排序表?这似乎很符合您的要求。
它相当容易使用 - 加载可排序的 Javascript 文件,然后,对于您希望其可排序的每个表,将 class="sortable" 应用于 <table> 标记。
它将立即了解如何对大多数类型的数据进行排序,但如果有某些情况它不知道,您可以添加自定义排序键来告诉它如何排序。该文档很好地解释了这一切。
如果您发现 .serialize() 在 David Heggie 的解决方案中返回 null,则将 TR 的 id 值设置为“id_1”而不是简单的“1”
例子:
<tr id="id_1"><td>1</td><td>Name1</td><td>Details1</td></tr>
<tr id="id_2"><td>2</td><td>Name1</td><td>Details2</td></tr>
<tr id="id_3"><td>3</td><td>Name1</td><td>Details3</td></tr>
<tr id="id_4"><td>4</td><td>Name1</td><td>Details4</td></tr>
以上将序列化为“id[]=1&id[]=2&id[]=3”
您可以使用“=”、“-”或“_”代替“_”。以及除“id”之外的任何其他词。
我正在使用 JQuery Sortable 来执行此操作,但以防万一,您像我一样使用 Vue.js,这是一个创建自定义 Vue 指令来封装 Sortable 功能的解决方案,我知道 Vue Draggable 但它不会将表列排序为根据问题 这里 为了看到这一点的实际效果, 检查这个
JS代码
Vue.directive("draggable", {
//adapted from https://codepen.io/kminek/pen/pEdmoo
inserted: function(el, binding, a) {
Sortable.create(el, {
draggable: ".draggable",
onEnd: function(e) {
/* vnode.context is the context vue instance: "This is not documented as it's not encouraged to manipulate the vm from directives in Vue 2.0 - instead, directives should be used for low-level DOM manipulation, and higher-level stuff should be solved with components instead. But you can do this if some usecase needs this. */
// fixme: can this be reworked to use a component?
// https://github.com/vuejs/vue/issues/4065
// https://forum.vuejs.org/t/how-can-i-access-the-vm-from-a-custom-directive-in-2-0/2548/3
// https://github.com/vuejs/vue/issues/2873 "directive interface change"
// `binding.expression` should be the name of your array from vm.data
// set the expression like v-draggable="items"
var clonedItems = a.context[binding.expression].filter(function(item) {
return item;
});
clonedItems.splice(e.newIndex, 0, clonedItems.splice(e.oldIndex, 1)[0]);
a.context[binding.expression] = [];
Vue.nextTick(function() {
a.context[binding.expression] = clonedItems;
});
}
});
}
});
const cols = [
{name: "One", id: "one", canMove: false},
{name: "Two", id: "two", canMove: true},
{name: "Three", id: "three", canMove: true},
{name: "Four", id: "four", canMove: true},
]
const rows = [
{one: "Hi there", two: "I am so excited to test", three: "this column that actually drags and replaces", four: "another column in its place only if both can move"},
{one: "Hi", two: "I", three: "am", four: "two"},
{one: "Hi", two: "I", three: "am", four: "three"},
{one: "Hi", two: "I", three: "am", four: "four"},
{one: "Hi", two: "I", three: "am", four: "five"},
{one: "Hi", two: "I", three: "am", four: "six"},
{one: "Hi", two: "I", three: "am", four: "seven"}
]
Vue.component("datatable", {
template: "#datatable",
data() {
return {
cols: cols,
rows: rows
}
}
})
new Vue({
el: "#app"
})
CSS
.draggable {
cursor: move;
}
table.table tbody td {
white-space: nowrap;
}
哈巴狗模板 HTML
#app
datatable
script(type="text/x-template" id="datatable")
table.table
thead(v-draggable="cols")
template(v-for="c in cols")
th(:class="{draggable: c.canMove}")
b-dropdown#ddown1.m-md-2(:text='c.name')
b-dropdown-item First Action
b-dropdown-item Second Action
b-dropdown-item Third Action
b-dropdown-divider
b-dropdown-item Something else here...
b-dropdown-item(disabled='') Disabled action
tbody
template(v-for="row in rows")
tr
template(v-for="(col, index) in cols")
td {{row[col.id]}}