【问题标题】:HTML drag and drop sortable tablesHTML 拖放可排序表格
【发布时间】:2010-09-10 01:58:49
【问题描述】:

曾经想要一个 HTML 拖放可排序表,您可以在其中对行和列进行排序?我知道这是我会为之而死的东西。有很多可排序的列表,但似乎无法找到可排序的表。

我知道您可以非常接近 script.aculo.us 提供的工具,但我遇到了一些跨浏览器问题。

【问题讨论】:

    标签: javascript html drag-and-drop html-table


    【解决方案1】:

    我使用了 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 的序列化版本发布到给定的 URL。这个函数(在我的例子中是 PHP)然后更新数据库中项目的订单。

    【讨论】:

    • 如果它对其他人有帮助 - 我对示例有疑问 - serialize 调用返回 null。根据 Lathan 的回答 here,它在我更改 ID 时起作用。不知道是不是和jquery的版本有关
    【解决方案2】:

    我在jQuery 中推荐Sortables。您可以在列表项或几乎任何东西(包括表格)上使用它。

    jQuery 对跨浏览器非常友好,我一直推荐它。

    【讨论】:

    • 我无法让 jQuery sortable 在表格中工作。它只是拖动整个表格或单个单元格。但没有基于行的拖动。
    【解决方案3】:

    我过去使用过dhtmlxGrid。除其他外,它还支持拖放行/列、客户端排序(字符串、整数、日期、自定义)和多浏览器支持。

    对评论的回应: 不,没有找到更好的东西 - 只是从那个项目开始。 :-)

    【讨论】:

    • 你过去用过它。这是否意味着你找到了更好的东西;)我花了一些时间研究它,它似乎是我想要的一切。感谢您的帮助!
    【解决方案4】:

    David Heggie 的回答对我最有用。可以稍微简洁一点:

    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
    });
    

    为我工作,具有相同的标记。

    【讨论】:

      【解决方案5】:

      大多数框架(Yui、MooTools、jQuery、Prototype/Scriptaculous 等)都具有可排序的列表功能。对每一项进行一些研究,然后选择最适合您需求的一项。

      【讨论】:

        【解决方案6】:

        如果您不介意 Java,有一个非常方便的 GWT 库,名为 GWT-DND,请查看在线演示,了解它的强大功能。

        【讨论】:

        • 我不介意 Java,但其他人可能 :) 但说真的,Java 感觉有点沉重。
        • 因为想要一个可排序的表而使用 Java 就像用大锤敲打螺丝一样。
        【解决方案7】:

        如果您发现 .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”之外的任何其他词。

        【讨论】:

          【解决方案8】:

          我正在使用 JQuery Sortable 来执行此操作,但如果您像我一样使用 Vue.js,这是一个创建自定义 Vue 指令来封装 Sortable 功能的解决方案,我知道 Vue 可拖动,但它不排序根据问题HERE 的表列要查看此操作,CHECK THIS

          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;
          }
          

          Pug 模板 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]}}
          

          【讨论】:

            【解决方案9】:

            sorttable 怎么样?这似乎很符合您的要求。

            它相当容易使用 - 加载 sorttable Javascript 文件,然后,对于您希望它可排序的每个表,将 class="sortable" 应用于

            标记。

            它会立即了解如何对大多数类型的数据进行排序,但如果它不知道,您可以添加自定义排序键来告诉它如何排序。文档很好地解释了这一切。

            【讨论】:

            • 除了没有拖放。我需要能够按我想要的方式对表格进行逐行排序,而不是按照某种规则。
            猜你喜欢
            • 2012-03-16
            • 2018-09-11
            • 1970-01-01
            • 2012-06-19
            • 2012-05-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-01-05
            相关资源
            最近更新 更多