Frage

Wollten Sie schon immer eine HTML -Drag & Drop -sortierbare Tabelle, in der Sie sowohl Zeilen als auch Spalten sortieren können? Ich weiß, dass es etwas ist, für das ich sterben würde. Es gibt viele sortierbare Listen, aber es scheint unmöglich zu finden, einen sortierbaren Tisch zu finden.

Ich weiß, dass Sie sich mit den Tools, die script.aculo.us bietet, ziemlich eng kommen können, aber ich bin auf einige Probleme mit dem Cross-Browser mit ihnen gestoßen.

War es hilfreich?

Lösung

Ich habe verwendet DHTMLXGRID in der Vergangenheit. Unter anderem unterstützt es Drag-and-Drop-Zeilen/-spalten, clientseitige Sortierung (String, Ganzzahl, Datum, benutzerdefinierte) und Multi-Browser-Unterstützung.

Antwort auf Kommentar: Nein, nichts Besseres gefunden - hat sich gerade von diesem Projekt weiterentwickelt. :-)

Andere Tipps

Ich habe das sortierbare Plugin von JQuery UI mit guten Ergebnissen verwendet. Markup ähnlich wie folgt:

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

und dann im 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
            }
        });
    }
});

Dies veröffentlicht eine serialisierte Version der IDs der Elemente an die angegebene URL. Diese Funktion (in meinem Fall PHP) aktualisiert dann die Bestellungen der Elemente in der Datenbank.

Ich empfehle Sortables in JQuery. Sie können es auf Listenelementen oder so ziemlich alles verwenden, einschließlich Tabellen.

JQuery ist sehr browserfreundlich und ich empfehle es die ganze Zeit.

David Heggies Antwort war für mich die nützlichste. Es kann etwas prägnanter sein:

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

Funktioniert für mich mit dem gleichen Markup.

Most frameworks (Yui, MooTools, jQuery, Prototype/Scriptaculous, etc.) have sortable list functionality. Do a little research into each and pick the one that suits your needs most.

If you don't mind Java, there is a very handy library for GWT called GWT-DND check out the online demo to see how powerful it is.

How about sorttable? That would seem to fit your requirements nicely.

It's rather easy to use - load the sorttable Javascript file, then, for each table you want it to make sortable, apply class="sortable" to the <table> tag.

It will immediately understand how to sort most types of data, but if there's something it doesn't, you can add a custom sort key to tell it how to sort. The documentation explains it all pretty well.

If you find .serialize() returning null in David Heggie's solution then set the id values for the TRs as 'id_1' instead of simply '1'

Example:

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

The above will serialize as "id[]=1&id[]=2&id[]=3"

You can use '=', '-' or '_' instead of '_'. And any other word besides "id".

I am using JQuery Sortable to do so but in case, you are using Vue.js like me, here is a solution that creates a custom Vue directive to encapsulate the Sortable functionality, I am aware of Vue draggable but it doesnt sort table columns as per the issue HERE To see this in action, CHECK THIS

JS Code

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 Template 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]}}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top