Jquery UI Сортировка с таблицей и шириной

Я использую jQuery UI sortable, чтобы сортировать таблицу таблицы. Код работает нормально, но потому, что я не добавляю ширину к td s, когда я перетаскиваю tr, он сжимает содержимое.

Например; если моя строка таблицы 500px, когда я начинаю перетаскивать, она становится 300px. Я предполагаю, что это происходит потому, что в сетке не определена ширина. Это потому, что я использую два класса для td (fix и liquid).

Класс fix делает значение td равным ширине содержимого, а liquid составляет td ширину 100%. Это мой подход к таблице сетки без необходимости присваивать ширину td s.

Любая идея, как сделать сортировку с моим подходом?

Ответ 1

Я нашел ответ здесь.

Я немного изменил его, чтобы клонировать строку, вместо того, чтобы добавлять ширину к оригиналу:

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

Ответ 2

Я думаю, это может помочь:

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

Ответ 3

Выбранный ответ - действительно приятное решение, но у него есть одна серьезная ошибка, которая очевидна в оригинальной скрипте JS (http://jsfiddle.net/bgrins/tzYbU/): попробуйте перетащить самый длинный ряд (Бог благословит вас, г-н Розуотер), а остальная часть ширины ячейки разрушается.

Это означает, что фиксировать ширину ячеек в перетаскиваемой ячейке недостаточно - вам также нужно исправить ширины таблицы.

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

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

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

Это устраняет проблему свертывания таблицы после перетаскивания первого столбца, но вводит новую: если вы измените содержимое таблицы, размеры ячеек теперь будут исправлены.

Чтобы обойти это при добавлении или изменении содержимого, вам необходимо очистить установленные ширины:

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

Затем добавьте свой контент, затем снова закрепите ширину.

Это еще не полное решение, так как (особенно с таблицей) вам нужен заполнитель. Для этого нам нужно добавить функцию start, которая строит 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 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 content, so TD rather than TR
        ui.placeholder.html('<td colspan="' + cellCount + '">&nbsp;</td>');
    }
}).disableSelection();

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

Ответ 4

Кажется, что клонирование строки плохо работает на IE8, но оригинальное решение делает.

Протестировано с помощью jsFiddle.

Ответ 5

Вызовите этот следующий код, когда ваша таблица готова к сортировке, это гарантирует, что ваши td-элементы имеют фиксированную структуру без разбивки структуры таблицы.

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

Ответ 6

Решение Keith прекрасно, но создало небольшой хаос в Firefox, который не складывал колпаны, а приводил их. (Старая js строка типа боль в колене)

заменив эту строку:

 cellCount += colspan;

с:

 cellCount += colspan-0;

Устраняет проблему. (Поскольку js принудительно обрабатывает переменные как числа вместо строк)

Ответ 7

Ответ Дейва Джеймса Миллера работал у меня, но из-за расположения контейнеров div на моей странице помощник, который тащит с помощью курсора мыши, смещен от положения мыши. Чтобы исправить это, я добавил следующее для обратного вызова помощника

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

Вот полный обратный вызов с указанной выше линией:

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

Я бы добавил это как комментарий к ответу Дэйва, но мне не хватило репутации в этой учетной записи.

Ответ 8

Кажется, что disableSelection() - метод плохой и устаревший в настоящее время. Я не могу использовать текстовые входы внутри сортируемой строки больше в Mozilla Firefox 35.0. Это просто не фокусируется больше.

Ответ 9

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

Ответ 10

jsFiddle

После множества разных попыток я только что попробовал простое решение, которое завершает решение Дейва Джеймса Миллера, чтобы предотвратить сокращение таблицы при перетаскивании самой большой строки. Я надеюсь, что это поможет :)

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

Ответ 11

Примените сортировку к элементу таблицы tbody и просто установите помощника для "клонирования", как описано в jquery-ui API

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