jquery UI Możliwość sortowania według szerokości tabeli i tr

155

Używam sortowania interfejsu użytkownika jQuery, aby umożliwić sortowanie siatki tabeli. Wydaje się, że kod działa dobrze, ale ponieważ nie dodam szerokości do tds, przeciąganie trgo zmniejsza zawartość.

Na przykład; jeśli mój wiersz tabeli ma rozmiar 500 pikseli, kiedy zacznę przeciągać, zmieni się na 300 pikseli. Zakładam, że dzieje się tak, ponieważ w siatce nie określono szerokości. Dzieje się tak, ponieważ używam dwóch klas dla tds ( fixi liquid).

fixKlasa sprawia, że tdrówna szerokości zawartości i liquidsprawia, że tdszerokość 100%. To moje podejście do tabeli grid bez konieczności przypisywania szerokości do tds.

Masz jakiś pomysł, jak zrobić sortowalną pracę z moim podejściem?

j0k
źródło
3
Odpowiedzią Jarosława jest PRAWDZIWY mvp!
Brade
Miałem ten sam problem, myślę, że @Yaroslav ma poprawną odpowiedź na radzenie sobie ze stołami, o co pyta OP
tuz87

Odpowiedzi:

254

Tutaj znalazłem odpowiedź .

Zmodyfikowałem go nieznacznie, aby sklonować wiersz, zamiast dodawać szerokości do oryginału:

  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
źródło
@Dave James Miller Jak sprawiłbyś, aby opcja symbolu zastępczego działała?
shaun5
5
Dave, dzięki za udostępnienie tego, stworzyłem jsFiddle, aby pokazać różnice między oryginalnym, zmodyfikowanym i bez zastosowanej poprawki: jsfiddle.net/bgrins/tzYbU . Zaktualizuję również oryginalny post z Twoim rozwiązaniem.
Brian Grinstead
9
Działa to całkiem nieźle, ale myślę, że jest jeszcze jeden drobny problem; kiedy przeciągasz / upuszczasz wiersz, pozostałe kolumny tabeli mogą zmienić szerokość z powodu brakującego wiersza. Wydaje mi się, że ich szerokości też muszą zostać poprawione ...
Jez.
1
To zaoszczędziło mi dużo pracy. Powinna być oznaczona jako prawidłowa odpowiedź.
Andrew Bessa,
3
Odkryłem, że szerokość powodowała, że ​​wyściełane komórki nie były w porządku. Zamieniłem się na$(this).width($originals.eq(index).outerWidth());
Barry Carlyon
166

Myślę, że to może pomóc:

.ui-sortable-helper {
    display: table;
}
Jarosław
źródło
13
Dlaczego to nie jest najlepsza odpowiedź? Jedna prosta linia CSS rozwiązuje to za mnie.
jcrowson
8
Zgadzam się! Nie uwierzysz, jak jedna prosta linia kodu CSS naprawia twoją sortowalną tabelę - eksperci Stackoverflow są zdumieni!
Brade
3
To jest odpowiedź. Dzięki @Yaroslav
Steffi
3
To NIE jest rozwiązanie ogólne i spowoduje inny wygląd przeciągniętego rzędu
Tomas M
13
To rozwiązanie jest bardzo dobre, ale może mieć wpływ na inne listy, które nie są tabelami. Sugeruję, abyś zredagował swoją odpowiedź, aby była bardziej szczegółowa. W ten sposób => tabela tr.ui-sortable-helper {display: table! Important; }
Rafael Gomes Francisco
29

Wybrana tutaj odpowiedź jest naprawdę fajnym rozwiązaniem, ale ma jeden poważny błąd, który jest widoczny w oryginalnych skrzypcach JS ( http://jsfiddle.net/bgrins/tzYbU/ ): spróbuj przeciągnąć najdłuższy wiersz ( God Bless You, Mr. . Rosewater ), a pozostałe szerokości komórek zapadają się.

Oznacza to, że ustalenie szerokości komórek w przeciągniętej komórce nie wystarczy - musisz również naprawić szerokości w tabeli.

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

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

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

Rozwiązuje to problem zwijania tabeli po przeciągnięciu pierwszej kolumny, ale wprowadza nową: jeśli zmienisz zawartość tabeli, rozmiary komórek są teraz ustalone.

Aby obejść ten problem podczas dodawania lub zmiany treści, musisz wyczyścić ustawione szerokości:

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

Następnie dodaj zawartość, a następnie ponownie popraw szerokość.

To wciąż nie jest kompletne rozwiązanie, ponieważ (szczególnie w przypadku tabeli) potrzebujesz symbolu zastępczego kropli. W tym celu musimy dodać na początku funkcję, która buduje symbol zastępczy:

$('#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/

Keith
źródło
Dzięki, oszczędzasz mój czas
super pantera
Ta technika zastępcza jest zabójcza! Całkowicie rozwiązało mój problem.
jessegavin
1
To rozwiązanie jest naprawdę dobre, a technika zastępcza jest naprawdę solidna, moim zdaniem powinna to być wybrana odpowiedź.
Chris James Champeau
1
Nadal powoduje to nieprzyjemne zachowanie, gdy masz bardzo wysoki rząd. Wszystkie inne rzędy ukryją się za nim. Dodałbym to do metody startowej:$(".must-have-class").css("height", $(ui.item).outerHeight());
Itzik Ben Hutta
6

Wygląda na to, że klonowanie wiersza nie działa dobrze w IE8, ale oryginalne rozwiązanie tak.

Przetestowane za pomocą jsFiddle .

vincentp
źródło
Dzięki za skonfigurowanie jsFiddle. Idę z oryginalnym rozwiązaniem, ponieważ Jez zauważył, że inne komórki wiersza mogą zmieniać szerokość podczas przeciągania wiersza.
Roger,
4

Wywołaj poniższy kod, gdy tabela jest gotowa do posortowania, dzięki czemu upewnisz się, że elementy td są ustalone z bez przerywania struktury tabeli.

 $(".tableToSort td").each(function () {
            $(this).css("width", $(this).width());
        });  
Teoman shipahi
źródło
Tak, to prawie to samo, co moja odpowiedź, chociaż moja działa thrównie dobrze dla jak td. Naprawia zwijanie się przeciągniętego wiersza i zwijanie tabeli, ale kosztem naprawy szerokości.
Keith
1

jsFiddle

Po wielu różnych próbach po prostu wypróbowałem proste rozwiązanie, które uzupełnia rozwiązanie Dave'a Jamesa Millera, aby zapobiec kurczeniu się tabeli podczas przeciągania największego wiersza. Mam nadzieję, że to pomoże :)

// 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;
};
Ach
źródło
0

Rozwiązanie Keitha jest w porządku, ale spowodowało małe spustoszenie w Firefoksie, które nie zsumowało parametrów, ale je wskazało. (Stary js typu struna ból w kolanie)

zastępując tę ​​linię:

 cellCount += colspan;

z:

 cellCount += colspan-0;

Rozwiązuje problem. (Ponieważ js jest zmuszony traktować zmienne jako liczby zamiast łańcuchów)

Maks
źródło
0

Odpowiedź Dave'a Jamesa Millera zadziałała dla mnie, ale ze względu na układ kontenerów div na mojej stronie, element pomocniczy, który przeciąga kursor myszy, jest przesunięty w stosunku do pozycji mojej myszy. Aby to naprawić, do wywołania zwrotnego pomocnika dodałem następujący kod

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

Oto pełne wywołanie zwrotne z dodaną powyższą linią:

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

Dodałbym to jako komentarz do odpowiedzi Dave'a, ale nie miałem wystarczającej reputacji na tym koncie.

Shea Riley
źródło
Po przeczytaniu dokumentacji jQuery stwierdziłem, że sortable przyjmuje również opcję „appendTo”, która określa, do jakiego elementu dołączany jest helper.
Shea Riley
0

Wygląda na to, że disableSelection()metoda jest obecnie zła i przestarzała. Nie mogę już używać wprowadzania tekstu w wierszu z możliwością sortowania w Mozilla Firefox 35.0. Po prostu nie można już na nim skupić się.

Miika Kontio
źródło
-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));
      });
    }
  });
Piotr
źródło
1
Potrzeba więcej wyjaśnień!
Afsanefda
-1
.sortable({
    helper: function (e, ui) {
        ui.children().each(function () {
            $(this).width($(this).width());
        });
        return ui;
    }
});
mspiderv
źródło
-4

Zastosuj sortable do elementu tbody tabeli i po prostu ustaw helpera na 'clone', jak opisano w API jquery-ui

$("$my-table-tbody").sortable({
    helper: "clone"
});
Regis Zaleman
źródło
1
Nie wydaje się pomagać.
Andrew,