Ordnen Sie HTML-Tabellenzeilen per Drag-and-Drop neu an

Lesezeit: 8 Minuten

Benutzer-Avatar
Farshad

Ich habe eine jQuery-Funktion, um Tabellenzeilen nach oben und unten zu verschieben. Ich weiß nicht, wie ich die Daten speichern oder die Position jeder Zeile abrufen kann. Ich verwende PHP, um die Tabellenzeilen anzuzeigen.

Wie erhalte ich den Positionswert jeder Tabellenzeile, wenn der Benutzer die Tabellenzeilen neu anordnet?

Benutzer-Avatar
Jim Petkus

Die jQuery-UI sortierbares Plugin bietet Drag-and-Drop-Neuordnung. Eine Schaltfläche zum Speichern kann die IDs jedes Elements extrahieren, um eine durch Kommas getrennte Zeichenfolge dieser IDs zu erstellen, die einem versteckten Textfeld hinzugefügt wird. Das Textfeld wird mit einem asynchronen Postback an den Server zurückgegeben.

Dies Geige Beispiel ordnet Tabellenelemente neu an, speichert sie aber nicht in einer Datenbank.

Das sortierbare Plugin benötigt eine Codezeile, um jede Liste in eine sortierbare Liste umzuwandeln. Wenn Sie sie verwenden möchten, bietet es auch CSS und Bilder, um der sortierbaren Liste eine visuelle Wirkung zu verleihen (siehe das Beispiel, auf das ich verlinkt habe). Entwickler müssen jedoch Code bereitstellen, um Elemente in ihrer neuen Reihenfolge abzurufen. Ich bette eindeutige IDs jedes Elements in der Liste als HTML-Attribut ein und rufe diese IDs dann über jQuery ab.

Zum Beispiel:

// ----- 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(",");
}

  • Wenn Sie mein Beispiel genauer untersuchen, ist der Code unabhängig davon, wie Sie ihn tatsächlich sortieren (in Ihrem Fall fragen Sie einfach nach tr anstelle von li ab, um Ihre Zeilen zu erhalten). Sie können jeden gewünschten Wert aus Ihrer Liste abrufen, indem Sie ihn als HTML-Attribut speichern und dann jquery attr() verwenden, um die Werte in sortierter Reihenfolge abzurufen. Ich möchte noch hinzufügen, dass ich Ihren Ton überhaupt nicht schätze. Ich habe die Antwort gegeben, nach der Sie gefragt haben, und empfohlen, dass Sie sich eine sehr beliebte Methode zum Sortieren ansehen, falls Sie sich dessen nicht bewusst sind.

    – Jim Petkus

    15. Januar 2010 um 16:25 Uhr


  • Ihre Linie var linkIDs = [items.size()]; initialisiert NICHT ein Array der Größe items.size(). Sie erstellen einfach ein Array mit einem einzelnen Element, das diese Größe enthält. Was in der ersten Iteration von items.each überschrieben wird.

    – Dany Khalife

    9. Juli 2016 um 22:22 Uhr

  • Jim, wie kann ich dieses Array in einer MySQL-Datenbank speichern? weißt du wo es ein Tutorial dazu gibt?

    – Renan

    14. Juni 2019 um 20:01 Uhr

  • Funktioniert super. Vielen Dank.

    – moreirapontocom

    17. Oktober 2019 um 16:14 Uhr

Benutzer-Avatar
NateS

Anscheinend beschreibt die Frage das Problem des OP schlecht, aber diese Frage ist das beste Suchergebnis für das Ziehen, um Tabellenzeilen neu anzuordnen, also werde ich darauf antworten. Ich war nicht daran interessiert, die jQuery-Benutzeroberfläche für etwas so Einfaches einzuführen, also ist hier eine reine jQuery-Lösung:

$(".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">&#9776;</td>
    <td>Table Cell 1</td>
  </tr>
  <tr>
    <td class="grab">&#9776;</td>
    <td>Table Cell 2</td>
  </tr>
  <tr>
    <td class="grab">&#9776;</td>
    <td>Table Cell 3</td>
  </tr>
</table>

Notiz si == 0 und i > 0 ignoriert die erste Zeile, die für mich enthält TH Stichworte. Ersetze das alert mit Ihrer Logik “Ziehen beendet”.

  • Toller Arbeiter. Das hat mir den Tag versüßt. Hier ist meine Geige, falls jemand sie nützlich findet. jsfiddle.net/7ko9ay1e

    – Tim

    24. September 2018 um 23:24 Uhr


  • Wie können wir das für mehrere Zeilen machen?

    – Omi

    10. Oktober 2019 um 9:28 Uhr

Ich arbeite gut damit

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

Einfach für das Plugin 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);
        }
    });
});

Plugin (TableDnD):
https://github.com/isocra/TableDnD/

Demo:
http://jsfiddle.net/DenisHo/dxpLrcd9/embedded/result/

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

Sie können sich gerne ansehen jQuery sortierbar. Ich habe es verwendet, um Tabellenzeilen neu zu ordnen.

  • danke aber hast du meine frage überhaupt gelesen?! Ich suche kein neues D&D-Plugin. Ich frage mich nur, wie ich das Problem meines aktuellen Skripts beim Abrufen jedes Zeilenwerts lösen kann

    – Farshad

    15. Januar 2010 um 16:07 Uhr

  • @Ghazanfari, ich kann in Ihrer Frage kein Skript sehen, das jeder lösen kann.

    – Amit Kumar Gupta

    23. Januar 2018 um 6:50 Uhr

Benutzer-Avatar
SAUERSTOFF

Aufbauend auf der Fiddle von @tim strafft diese Version den Umfang und die Formatierung und konvertiert bind() -> on(). Es wurde entwickelt, um eine dedizierte zu binden td als Griff anstelle der gesamten Reihe. In meinem Anwendungsfall habe ich input Felder, so dass sich der Ansatz “irgendwo in der Zeile ziehen” verwirrend anfühlte.

Getestet auf dem Desktop. Nur Teilerfolg mit Mobile Touch. Kann es aus irgendeinem Grund nicht richtig auf dem lauffähigen Snippet von SO ausführen …

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>

  • danke aber hast du meine frage überhaupt gelesen?! Ich suche kein neues D&D-Plugin. Ich frage mich nur, wie ich das Problem meines aktuellen Skripts beim Abrufen jedes Zeilenwerts lösen kann

    – Farshad

    15. Januar 2010 um 16:07 Uhr

  • @Ghazanfari, ich kann in Ihrer Frage kein Skript sehen, das jeder lösen kann.

    – Amit Kumar Gupta

    23. Januar 2018 um 6:50 Uhr

1205600cookie-checkOrdnen Sie HTML-Tabellenzeilen per Drag-and-Drop neu an

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy