jquery UI Diurutkan dengan tabel dan lebar tr

155

Saya menggunakan jQuery UI sortable untuk membuat kotak tabel saya dapat diurutkan. Kode tampaknya berfungsi dengan baik tetapi karena saya tidak menambahkan lebar ke tds, ketika saya seret tritu menyusutkan konten.

Sebagai contoh; jika baris tabel saya adalah 500px ketika saya mulai menyeret, itu menjadi 300px. Saya berasumsi itu terjadi karena tidak ada lebar yang didefinisikan dalam kisi. Itu karena saya menggunakan dua kelas untuk tds ( fixdan liquid).

The fixkelas membuat tdsama dengan lebar konten dan liquidmembuat tdlebar 100%. Ini pendekatan saya untuk tabel kisi tanpa harus menetapkan lebar ke tds.

Adakah yang tahu bagaimana membuat pekerjaan yang bisa diurutkan dengan pendekatan saya?

j0k
sumber
3
Jawaban Yaroslav adalah mvp NYATA!
Brade
Saya memiliki masalah yang sama, saya pikir @Yaroslav memiliki jawaban yang benar untuk berurusan dengan tabel yang merupakan pertanyaan OP
doz87

Jawaban:

254

Saya menemukan jawabannya di sini .

Saya memodifikasinya sedikit untuk mengkloning baris, alih-alih menambahkan lebar ke aslinya:

  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
sumber
@ Dave James Miller Bagaimana Anda membuat opsi placeholder berfungsi?
shaun5
5
Dave, terima kasih telah berbagi ini, saya telah membuat jsFiddle untuk menunjukkan perbedaan antara yang asli, yang dimodifikasi, dan tidak ada perbaikan yang diterapkan: jsfiddle.net/bgrins/tzYbU . Saya juga akan memperbarui posting asli dengan solusi Anda.
Brian Grinstead
9
Ini bekerja cukup baik, tapi saya pikir masih ada sedikit masalah; ketika Anda menyeret / menjatuhkan baris, kolom kolom lainnya mungkin berubah lebar karena baris yang hilang. Saya kira lebar mereka perlu diperbaiki juga ...
Jez
1
Ini menyelamatkan saya begitu banyak pekerjaan. Itu harus ditandai sebagai jawaban yang benar.
Andrew Bessa
3
Saya menemukan lebar menghasilkan sel yang empuk tidak cukup benar. Saya bertukar untuk$(this).width($originals.eq(index).outerWidth());
Barry Carlyon
166

Saya pikir itu dapat membantu:

.ui-sortable-helper {
    display: table;
}
Yaroslav
sumber
13
Bagaimana ini bukan jawaban teratas? Satu baris sederhana perbaikan CSS untuk saya.
jcrowson
8
Saya setuju! Anda tidak akan PERCAYA bagaimana satu baris sederhana CSS memperbaiki tabel Anda yang dapat diurutkan - pakar Stackoverflow bingung!
Brade
3
Ini adalah jawabannya. Terima kasih @Yaroslav
Steffi
3
Ini BUKAN solusi umum dan akan menghasilkan tampilan berbeda dari baris yang diseret
Tomas M
13
Solusi ini sangat bagus, tetapi dapat memengaruhi daftar lain yang bukan tabel. Saran saya adalah Anda mengedit jawaban Anda untuk dibuat lebih spesifik. Seperti ini => tabel tr.ui-sortable-helper {display: table! Important; }
Rafael Gomes Francisco
29

Jawaban yang dipilih di sini adalah solusi yang sangat bagus, tetapi memiliki satu bug parah yang terlihat pada JS biola asli ( http://jsfiddle.net/bgrins/tzYbU/ ): coba seret baris terpanjang ( God Bless You, Mr Rosewater ), dan sisa sel lebarnya runtuh.

Ini berarti bahwa memperbaiki lebar sel pada sel yang diseret tidak cukup - Anda juga perlu memperbaiki lebar pada tabel.

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

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

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

Ini memperbaiki masalah tabel runtuh setelah Anda menyeret kolom pertama, tetapi memperkenalkan yang baru: jika Anda mengubah konten tabel ukuran sel sekarang diperbaiki.

Untuk mengatasinya saat menambahkan atau mengubah konten, Anda harus menghapus set lebar:

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

Kemudian tambahkan konten Anda, lalu perbaiki lagi lebar.

Ini masih bukan solusi yang lengkap, karena (terutama dengan tabel) Anda membutuhkan tempat penampung drop. Untuk itu kita perlu menambahkan fungsi saat start yang membangun placeholder:

$('#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
sumber
Terima kasih, Anda menghemat waktu saya
super pantera
Teknik placeholder di sini adalah pembunuh! Benar-benar menyelesaikan masalah saya.
jessegavin
1
Solusi ini sebenarnya sangat bagus, dan teknik placeholder sangat solid, ini harus menjadi jawaban yang dipilih menurut saya.
Chris James Champeau
1
Ini masih menyebabkan perilaku yang tidak menyenangkan ketika Anda memiliki barisan yang sangat tinggi. Semua baris lain akan bersembunyi di baliknya. Saya akan menambahkan ini ke metode awal:$(".must-have-class").css("height", $(ui.item).outerHeight());
Itzik Ben Hutta
6

Tampaknya mengkloning baris tidak berfungsi dengan baik pada IE8, tetapi solusi aslinya tidak.

Diuji dengan jsFiddle .

vincentp
sumber
Terima kasih telah menyiapkan jsFiddle. Saya akan menggunakan solusi asli karena seperti yang dicatat Jez, sel-sel baris lain dapat berubah lebar ketika menyeret sebuah baris.
Roger
4

Panggil kode berikut ini ketika meja Anda siap untuk disortir, ini akan memastikan elemen td Anda telah diperbaiki tanpa merusak struktur tabel.

 $(".tableToSort td").each(function () {
            $(this).css("width", $(this).width());
        });  
Teoman shipahi
sumber
Ya, itu hampir sama dengan jawaban saya, meskipun punyaku thjuga td. Ini memperbaiki runtuhnya baris yang diseret dan tabel runtuh, tetapi dengan biaya memperbaiki lebar.
Keith
1

jsFiddle

Setelah banyak upaya yang berbeda, saya hanya mencoba solusi sederhana yang melengkapi solusi Dave James Miller untuk mencegah tabel menyusut sambil menyeret baris terbesar. Saya harap ini akan membantu :)

// 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
sumber
0

Solusi Keith baik-baik saja tetapi menghasilkan sedikit kekacauan di Firefox yang tidak menambah colspans tetapi memberi isyarat. (The tipe js string sakit di lutut)

mengganti baris ini:

 cellCount += colspan;

dengan:

 cellCount += colspan-0;

Memperbaiki masalah. (Karena js dipaksa untuk memperlakukan variabel sebagai angka, bukan string)

Maks
sumber
0

Jawaban Dave James Miller bekerja untuk saya, tetapi karena tata letak wadah div pada halaman saya, pembantu yang menyeret dengan kursor mouse diimbangi dari posisi mouse saya. Untuk memperbaikinya, saya menambahkan yang berikut ke callback pembantu

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

Ini adalah panggilan balik lengkap dengan baris di atas ditambahkan:

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

Saya akan menambahkan ini sebagai komentar untuk jawaban Dave, tetapi saya tidak memiliki cukup perwakilan di akun ini.

Shea Riley
sumber
Setelah membaca dokumentasi jQuery, saya menemukan bahwa sortable juga mengambil opsi "appendTo" yang menentukan elemen apa yang ditambahkan oleh helper.
Shea Riley
0

Sepertinya disableSelection()- metode buruk dan usang saat ini. Saya tidak dapat menggunakan input teks di dalam baris yang dapat disortir lagi Mozilla Firefox 35.0. Itu sudah tidak fokus lagi.

Miika Kontio
sumber
-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));
      });
    }
  });
Peter
sumber
1
Penjelasan lebih lanjut diperlukan!
Afsanefda
-1
.sortable({
    helper: function (e, ui) {
        ui.children().each(function () {
            $(this).width($(this).width());
        });
        return ui;
    }
});
mspiderv
sumber
-4

Terapkan sortable ke elemen tabel tbody dan hanya mengatur helper ke 'clone', seperti yang dijelaskan dalam API jquery-ui

$("$my-table-tbody").sortable({
    helper: "clone"
});
Regis Zaleman
sumber
1
Sepertinya tidak membantu.
Andrew