jquery UI Sortierbar mit Tabelle und tr Breite


155

Ich verwende die jQuery-Benutzeroberfläche sortierbar, um mein Tabellenraster sortierbar zu machen. Der Code scheint gut zu funktionieren, aber da ich tds keine Breite hinzufüge , wird trder Inhalt beim Ziehen verkleinert.

Beispielsweise; Wenn meine Tabellenzeile beim Ziehen 500 Pixel groß ist, wird sie 300 Pixel groß. Ich gehe davon aus, dass dies geschieht, weil im Raster keine Breite definiert ist. Das liegt daran, dass ich zwei Klassen für das tds ( fixund liquid) verwende.

Die fixKlasse macht das tdgleich der Inhaltsbreite und liquidmacht die tdBreite 100%. Es ist mein Ansatz für die Rastertabelle, ohne tds die Breite zuweisen zu müssen .

Irgendeine Idee, wie ich mit meinem Ansatz sortierbar arbeiten kann?


3
Jaroslaws Antwort ist das ECHTE MVP!
Brade

Ich hatte das gleiche Problem, ich denke, @Yaroslav hat die richtige Antwort für den Umgang mit Tabellen, worüber das OP fragt
doz87

Antworten:


254

Ich habe die Antwort hier gefunden .

Ich habe es leicht geändert, um die Zeile zu klonen, anstatt dem Original Breiten hinzuzufügen:

  helper: function(e, tr)
  {
    var $originals = tr.children();
    var $helper = tr.clone();
    $helper.children().each(function(index)
    {
      // Set helper cell sizes to match the original sizes
      $(this).width($originals.eq(index).width());
    });
    return $helper;
  },

@ Dave James Miller Wie würden Sie die Platzhalteroption zum Laufen bringen?
Shaun5

5
Dave, danke, dass du das geteilt hast. Ich habe eine jsFiddle erstellt, um die Unterschiede zwischen original, modifiziert und ohne Fix zu zeigen: jsfiddle.net/bgrins/tzYbU . Ich werde auch den ursprünglichen Beitrag mit Ihrer Lösung aktualisieren.
Brian Grinstead

9
Das funktioniert ganz gut, aber ich denke, es gibt immer noch ein kleines Problem. Wenn Sie die Zeile ziehen / ablegen, kann sich die Breite der restlichen Tabellenspalten aufgrund der fehlenden Zeile ändern. Ich denke, ihre Breiten müssen ebenfalls
Jez

1
Das hat mir so viel Arbeit erspart. Es sollte als die richtige Antwort markiert werden.
Andrew Bessa

3
Ich fand, dass die Breite dazu führte, dass gepolsterte Zellen nicht ganz richtig waren. Ich tauschte gegen$(this).width($originals.eq(index).outerWidth());
Barry Carlyon

166

Ich denke, es kann helfen:

.ui-sortable-helper {
    display: table;
}

13
Wie ist das nicht die Top-Antwort? Eine einfache Zeile CSS behebt es für mich.
JCrowson

8
Genau! Sie werden nicht glauben, wie eine einfache Zeile CSS Ihre sortierbare Tabelle repariert - Stackoverflow-Experten sind verblüfft!
Brade

3
Das ist die Antwort. Danke @Yaroslav
Steffi

3
Dies ist KEINE allgemeine Lösung und führt zu einem anderen Aussehen der gezogenen Reihe
Tomas M

13
Diese Lösung ist sehr gut, kann jedoch andere Listen betreffen, die keine Tabellen sind. Mein Vorschlag ist, dass Sie Ihre Antwort bearbeiten, um sie genauer zu gestalten. So => Tabelle tr.ui-sortable-helper {Anzeige: Tabelle! Wichtig; }
Rafael Gomes Francisco

29

Die ausgewählte Antwort hier ist eine wirklich nette Lösung, aber es gibt einen schwerwiegenden Fehler, der in der ursprünglichen JS-Geige ( http://jsfiddle.net/bgrins/tzYbU/ ) offensichtlich ist : Versuchen Sie, die längste Reihe zu ziehen ( God Bless You, Mr. Rosenwasser ) und der Rest der Zellbreiten kollabieren.

Dies bedeutet, dass das Festlegen der Zellenbreiten in der gezogenen Zelle nicht ausreicht. Sie müssen auch die Breite der Tabelle festlegen.

$(function () {
    $('td, th', '#sortFixed').each(function () {
        var cell = $(this);
        cell.width(cell.width());
    });

    $('#sortFixed tbody').sortable().disableSelection();
});

JS Fiddle: http://jsfiddle.net/rp4fV/3/

Dies behebt das Problem, dass die Tabelle nach dem Ziehen der ersten Spalte zusammenfällt, führt jedoch eine neue ein: Wenn Sie den Inhalt der Tabelle ändern, werden die Zellengrößen jetzt behoben.

Um dies beim Hinzufügen oder Ändern von Inhalten zu umgehen, müssen Sie die eingestellten Breiten löschen:

$('td, th', '#sortFixed').each(function () {
    var cell = $(this);
    cell.css('width','');
});

Fügen Sie dann Ihren Inhalt hinzu und korrigieren Sie die Breite erneut.

Dies ist immer noch keine vollständige Lösung, da Sie (insbesondere bei einer Tabelle) einen Platzhalter benötigen. Dazu müssen wir beim Start eine Funktion hinzufügen, die den Platzhalter erstellt:

$('#sortFixed tbody').sortable({
    items: '> tr',
    forcePlaceholderSize: true,
    placeholder:'must-have-class',
    start: function (event, ui) {
        // Build a placeholder cell that spans all the cells in the row
        var cellCount = 0;
        $('td, th', ui.helper).each(function () {
            // For each TD or TH try and get it's colspan attribute, and add that or 1 to the total
            var colspan = 1;
            var colspanAttr = $(this).attr('colspan');
            if (colspanAttr > 1) {
                colspan = colspanAttr;
            }
            cellCount += colspan;
        });

        // Add the placeholder UI - note that this is the item's content, so TD rather than TR
        ui.placeholder.html('<td colspan="' + cellCount + '">&nbsp;</td>');
    }
}).disableSelection();

JS Fiddle: http://jsfiddle.net/rp4fV/4/


Danke, Sie sparen meine Zeit
Super Pantera

Die Platzhaltertechnik hier ist Killer! Mein Problem vollständig gelöst.
Jessegavin

1
Diese Lösung ist wirklich sehr gut und die Platzhaltertechnik ist wirklich solide. Dies sollte meiner Meinung nach die ausgewählte Antwort sein.
Chris James Champeau

1
Dies führt immer noch zu unangenehmem Verhalten, wenn Sie eine sehr hohe Reihe haben. Alle anderen Zeilen werden dahinter versteckt. Ich würde dies zur $(".must-have-class").css("height", $(ui.item).outerHeight());
Startmethode

6

Es scheint, dass das Klonen der Zeile unter IE8 nicht gut funktioniert, aber die ursprüngliche Lösung funktioniert.

Getestet mit der jsFiddle .


Vielen Dank, dass Sie die jsFiddle eingerichtet haben. Ich gehe mit der ursprünglichen Lösung vor, da, wie Jez bemerkte, die anderen Zeilenzellen beim Ziehen einer Zeile die Breite ändern können.
Roger

4

Rufen Sie diesen folgenden Code auf, wenn Ihre Tabelle zum Sortieren bereit ist. Dadurch wird sichergestellt, dass Ihre td-Elemente eine feste Struktur haben, ohne die Tabellenstruktur zu beschädigen.

 $(".tableToSort td").each(function () {
            $(this).css("width", $(this).width());
        });  

Ja, das ist so ziemlich das Gleiche wie meine Antwort, obwohl meine thgenauso gut funktioniert wie td. Es behebt den Zusammenbruch von gezogenen Zeilen und den Zusammenbruch von Tabellen, jedoch auf Kosten der Festlegung der Breiten.
Keith

1

jsFiddle

Nach vielen verschiedenen Versuchen habe ich gerade eine einfache Lösung ausprobiert, die die Lösung von Dave James Miller vervollständigt, um zu verhindern, dass die Tabelle beim Ziehen der größten Zeile schrumpft. Ich hoffe es wird helfen :)

// Make sure the placeholder has the same with as the orignal
var start = function(e, ui) {
    let $originals = ui.helper.children();
    ui.placeholder.children().each(function (index) {
        $(this).width($originals.eq(index).width());
    });
}
// Return a helper with preserved width of cells
var helper = function(e, tr) {
    let $helper = tr.clone();
    let $originals = tr.children();
    $helper.children().each(function (index) {
        $(this).width($originals.eq(index).outerWidth(true));
    });
    return $helper;
};

0

Die Lösung von Keith ist in Ordnung, hat aber in Firefox ein wenig Chaos angerichtet, das die Colspans nicht addierte, sondern aufforderte. (Der alte js Saitentyp Schmerz im Knie)

Ersetzen dieser Zeile:

 cellCount += colspan;

mit:

 cellCount += colspan-0;

Behebt das Problem. (Da js gezwungen ist, die Variablen als Zahlen anstelle von Zeichenfolgen zu behandeln)


0

Die Antwort von Dave James Miller hat bei mir funktioniert, aber aufgrund des Layouts der Container-Divs auf meiner Seite ist der Helfer, der mit dem Mauszeiger gezogen wird, von der Position meiner Maus versetzt. Um dies zu beheben, habe ich dem Helfer-Rückruf Folgendes hinzugefügt

$(document.body).append($helper);

Hier ist der vollständige Rückruf mit der obigen Zeile hinzugefügt:

helper: function (e, tr) {
  var $originals = tr.children();
  var $helper = tr.clone();
  $helper.children().each(function (index) {
    // Set helper cell sizes to match the original sizes
    $(this).width($originals.eq(index).width());
  });

  // append it to the body to avoid offset dragging
  $(document.body).append($helper);

  return $helper;
}

Ich hätte dies als Kommentar zu Daves Antwort hinzugefügt, aber ich hatte nicht genug Repräsentanten für dieses Konto.


Nach dem Lesen der jQuery-Dokumentation stellte ich fest, dass die Sortierfunktion auch die Option "appendTo" verwendet, die angibt, an welches Element der Helfer angehängt wird.
Shea Riley

0

Es scheint wie disableSelection()- Methode ist schlecht und heutzutage veraltet. Ich kann keine Texteingaben mehr in sortierbaren Zeilen verwenden Mozilla Firefox 35.0. Es ist einfach nicht mehr fokussierbar.


-1
$(function() {
    $( "#sort tbody" ).sortable({
        update: function () {
                                var order = $(this).sortable("toArray").join();
                                $.cookie("sortableOrder", order);
                        }
    });
    if($.cookie("sortableOrder")){
        var order = $.cookie("sortableOrder").split(",");
        reorder(order, $("#sort tbody"));
    }
    function reorder(aryOrder, element){
      $.each(aryOrder, function(key, val){
              element.append($("#"+val));
      });
    }
  });

1
Weitere Erklärungen sind erforderlich!
Afsanefda

-1
.sortable({
    helper: function (e, ui) {
        ui.children().each(function () {
            $(this).width($(this).width());
        });
        return ui;
    }
});

-4

Wenden Sie die Sortierbarkeit auf das tbody-Element der Tabelle an und setzen Sie den Helfer einfach auf 'clone', wie in der API von jquery-ui beschrieben

$("$my-table-tbody").sortable({
    helper: "clone"
});

1
Scheint nicht zu helfen.
Andrew
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.