UI jquery Sắp xếp theo bảng và chiều rộng tr


155

Tôi đang sử dụng jQuery UI sortable để sắp xếp lưới bảng của tôi. Mã có vẻ hoạt động tốt nhưng vì tôi không thêm chiều rộng cho tds nên khi tôi kéo trnó sẽ thu nhỏ nội dung.

Ví dụ; nếu hàng trong bảng của tôi là 500px khi tôi bắt đầu kéo, nó sẽ trở thành 300px. Tôi cho rằng điều đó xảy ra bởi vì không có chiều rộng được xác định trong lưới. Đó là bởi vì tôi đang sử dụng hai lớp cho tds ( fixliquid).

Các fixlớp học làm cho tdbằng với chiều rộng nội dung và liquidlàm cho tdchiều rộng 100%. Đó là cách tiếp cận của tôi cho bảng lưới mà không phải gán chiều rộng cho tds.

Bất kỳ ý tưởng làm thế nào để làm việc sắp xếp với cách tiếp cận của tôi?


3
Câu trả lời của Yaroslav là mvp THỰC SỰ!
Brade

Tôi đã cùng một vấn đề, tôi nghĩ @Yaroslav có câu trả lời đúng để đối phó với bảng đó là những gì OP được hỏi về
doz87

Câu trả lời:


254

Tôi tìm thấy câu trả lời ở đây .

Tôi đã sửa đổi nó một chút để sao chép hàng, thay vì thêm chiều rộng cho bản gốc:

  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 Bạn sẽ làm cho tùy chọn giữ chỗ hoạt động như thế nào?
shaun5

5
Dave, cảm ơn vì đã chia sẻ điều này, tôi đã tạo một jsFiddle để cho thấy sự khác biệt giữa bản gốc, bản sửa đổi và không có bản sửa lỗi nào được áp dụng: jsfiddle.net/bgrins/tzYbU . Tôi cũng sẽ cập nhật bài viết gốc với giải pháp của bạn.
Brian Grinstead

9
Điều này hoạt động khá độc đáo, nhưng tôi nghĩ vẫn còn một vấn đề nhỏ; khi bạn kéo / thả hàng, phần còn lại của các cột trong bảng có thể thay đổi độ rộng do hàng bị thiếu. Tôi đoán chiều rộng của chúng cũng cần phải được sửa ...
Jez

1
Điều này đã tiết kiệm cho tôi rất nhiều công việc. Nó nên được đánh dấu là câu trả lời đúng.
Andrew Bessa

3
Tôi thấy chiều rộng đã dẫn đến các ô được đệm không phải QUITE là đúng. Tôi đổi chỗ cho$(this).width($originals.eq(index).outerWidth());
Barry Carlyon

166

Tôi nghĩ rằng nó có thể giúp:

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

13
Làm thế nào đây không phải là câu trả lời hàng đầu? Một dòng CSS đơn giản sửa nó cho tôi.
jcrowson

8
Tôi đồng ý! Bạn sẽ KHÔNG TIN làm thế nào một dòng CSS đơn giản sửa bảng có thể sắp xếp của bạn - Các chuyên gia của Stackoverflow đang gặp khó khăn!
Brade

3
Đây là câu trả lời. Cảm ơn @ Nam Tư
Steffi

3
Đây KHÔNG phải là một giải pháp chung và sẽ dẫn đến giao diện khác nhau của hàng được kéo
Tomas M

13
Giải pháp này rất tốt, nhưng nó có thể ảnh hưởng đến các danh sách khác không có bảng. Đề nghị của tôi là bạn chỉnh sửa câu trả lời của bạn để làm cho cụ thể hơn. Như thế này => bảng tr.ui-sortable-helper {display: bảng! Quan trọng; }
Rafael Gomes Francisco

29

Câu trả lời được chọn ở đây là một giải pháp thực sự hay, nhưng nó có một lỗi nghiêm trọng rõ ràng trong fiddle JS gốc ( http://jsfiddle.net/bgrins/tzYbU/ ): hãy thử kéo hàng dài nhất ( God Bless You, Mr Nước hoa hồng ) và phần còn lại của chiều rộng tế bào sụp đổ.

Điều này có nghĩa là việc sửa độ rộng ô trên ô được kéo là không đủ - bạn cũng cần sửa độ rộng trên bảng.

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

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

Câu đố về JS: http://jsfiddle.net/rp4fV/3/

Điều này khắc phục sự cố sập bảng sau khi bạn kéo cột đầu tiên, nhưng giới thiệu một cột mới: nếu bạn thay đổi nội dung của bảng thì kích thước ô hiện đã được sửa.

Để khắc phục điều này khi thêm hoặc thay đổi nội dung, bạn sẽ cần xóa độ rộng được đặt:

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

Sau đó thêm nội dung của bạn, sau đó sửa chữa độ rộng một lần nữa.

Đây vẫn chưa phải là một giải pháp hoàn chỉnh, vì (đặc biệt là với một bảng) bạn cần một trình giữ chỗ thả. Vì vậy, chúng ta cần thêm một chức năng khi bắt đầu xây dựng trình giữ chỗ:

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

Câu đố về JS: http://jsfiddle.net/rp4fV/4/


Cảm ơn, bạn tiết kiệm thời gian của tôi
siêu pantera

Kỹ thuật giữ chỗ ở đây là sát thủ! Hoàn toàn giải quyết vấn đề của tôi.
jessegavin

1
Giải pháp này thực sự rất tốt và kỹ thuật giữ chỗ thực sự vững chắc, đây nên là câu trả lời được lựa chọn theo ý kiến ​​của tôi.
Chris James Champeau

1
Điều này vẫn gây ra hành vi khó chịu khi bạn có một hàng rất cao. Tất cả các hàng khác sẽ ẩn đằng sau nó. Tôi sẽ thêm điều này vào phương thức bắt đầu:$(".must-have-class").css("height", $(ui.item).outerHeight());
Itzik Ben Hutta

6

Có vẻ như nhân bản hàng không hoạt động tốt trên IE8, nhưng giải pháp ban đầu thì có.

Đã thử nghiệm với jsFiddle .


Cảm ơn bạn đã thiết lập jsFiddle. Tôi đang đi với giải pháp ban đầu vì như Jez lưu ý các ô hàng khác có thể thay đổi độ rộng khi kéo một hàng.
Roger

4

Gọi mã sau đây khi bảng của bạn đã sẵn sàng để được sắp xếp, điều này sẽ đảm bảo các phần tử td của bạn được cố định mà không phá vỡ cấu trúc bảng.

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

Vâng, đó là khá giống như câu trả lời của tôi, mặc dù tôi cũng làm việc thnhư vậy td. Nó sửa lỗi sụp đổ hàng kéo và sụp đổ bảng, nhưng với chi phí sửa chữa chiều rộng.
Keith

1

jsFiddle

Sau rất nhiều lần thử khác nhau, tôi chỉ thử một giải pháp đơn giản, hoàn thành giải pháp của Dave James Miller để ngăn bảng co lại trong khi kéo hàng lớn nhất. Tôi hy vọng nó sẽ giúp :)

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

Giải pháp của Keith vẫn ổn nhưng đã tạo ra một sự tàn phá nhỏ trong Firefox, thứ không bổ sung colspans mà chỉ ôm lấy chúng. (Loại đau js cũ ở đầu gối)

thay thế dòng này:

 cellCount += colspan;

với:

 cellCount += colspan-0;

Khắc phục sự cố. (Vì js buộc phải coi các biến là số thay vì chuỗi)


0

Câu trả lời của Dave James Miller có tác dụng với tôi, nhưng do cách bố trí các div container trên trang của tôi, trình trợ giúp kéo bằng con trỏ chuột được bù từ vị trí chuột của tôi. Để khắc phục điều đó, tôi đã thêm phần sau vào hàm gọi lại của trình trợ giúp

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

Đây là cuộc gọi lại hoàn chỉnh với dòng trên được thêm vào:

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

Tôi đã có thể thêm điều này như một nhận xét cho câu trả lời của Dave, nhưng tôi không có đủ đại diện cho tài khoản này.


Sau khi đọc tài liệu jQuery, tôi thấy rằng phần sắp xếp cũng có tùy chọn "appendTo" chỉ định phần tử nào mà trình trợ giúp được thêm vào.
Shea Riley

0

Có vẻ như disableSelection()- phương pháp này là xấu và không dùng nữa. Tôi không thể sử dụng đầu vào văn bản trong hàng có thể sắp xếp được nữa Mozilla Firefox 35.0. Nó không thể tập trung được nữa.


-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
Giải thích thêm là cần thiết!
Afsanefda

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

-4

Áp dụng khả năng sắp xếp cho phần tử tbody của bảng và chỉ cần đặt trình trợ giúp thành 'bản sao', như được mô tả trong API của jquery-ui

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

1
Dường như không giúp được gì.
Andrew
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.