Пользовательский интерфейс jquery Сортируемый с таблицей и tr шириной


155

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

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

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

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


3
Ответ Ярослава - НАСТОЯЩИЙ mvp!
Brade

У меня была та же проблема, я думаю, у @Yaroslav есть правильный ответ для работы с таблицами, о котором спрашивает OP
doz87

Ответы:


254

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

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

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

@ Дэйв Джеймс Миллер Как бы вы использовали опцию заполнителя?
shaun5

5
Дэйв, спасибо за то, что поделился этим, я сделал jsFiddle, чтобы показать различия между оригинальным, модифицированным и не примененным исправлением: jsfiddle.net/bgrins/tzYbU . Я также обновлю оригинальный пост с вашим решением.
Брайан Гринстед

9
Это работает довольно хорошо, но я думаю, что есть еще одна небольшая проблема; при перетаскивании строки остальные столбцы таблицы могут изменить ширину из-за отсутствующей строки. Я думаю, что их ширины должны быть исправлены ...
Jez

1
Это спасло мне столько работы. Это должно быть помечено как правильный ответ.
Андрей Бесса

3
Я обнаружил, что ширина привела к тому, что ячейки с подкладкой не совсем правы. Я поменялся на$(this).width($originals.eq(index).outerWidth());
Барри Карлайон

166

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

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

13
Как это не лучший ответ? Одна простая строка CSS исправляет это для меня.
jcrowson

8
Я согласен! Вы не поверите, как одна простая строка CSS исправляет вашу сортируемую таблицу - эксперты Stackoverflow озадачены!
Brade

3
Это ответ. Спасибо @Ярослав
Штеффи

3
Это НЕ общее решение и приведет к другому виду перетаскиваемого ряда
Томас М

13
Это решение очень хорошо, но оно может повлиять на другие списки, которые не являются таблицами. Я предлагаю вам отредактировать свой ответ на более конкретный. Вот так => таблица tr.ui-sortable-helper {display: table! Важный; }
Рафаэль Гомес Франсиско

29

Выбранный здесь ответ является действительно хорошим решением, но в нем есть одна серьезная ошибка, которая проявляется в оригинальной скрипке 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','');
});

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

Это все еще не полное решение, так как (особенно с таблицей) вам нужен заполнитель для удаления. Для этого нам нужно добавить функцию при запуске, которая создает заполнитель:

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


Спасибо, вы экономите мое время
супер пантера

Техника заполнителя здесь убийца! Полностью решил мою проблему.
Джессегавин

1
На самом деле это решение действительно хорошо, а метод заполнителя действительно солидный, по моему мнению, это должен быть выбранный ответ.
Крис Джеймс Шампо

1
Это все еще вызывает неприятное поведение, когда у вас очень высокий ряд. Все остальные ряды будут прятаться за ним. Я бы добавил это к методу старта:$(".must-have-class").css("height", $(ui.item).outerHeight());
Ицик Бен Хатта

6

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

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


Спасибо за настройку jsFiddle. Я иду с оригинальным решением, потому что, как заметил Джез, другие ячейки строки могут изменить ширину при перетаскивании строки.
Роджер

4

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

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

Да, это почти так же, как мой ответ, хотя мой работает для thтак же, как td. Он исправляет коллапс перетаскиваемой строки и таблицы, но за счет исправления ширины.
Кит

1

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

0

Решение Кейта прекрасно, но в Firefox возникло небольшое хаос, который не суммировал colspans, а привлек их внимание. (Старый JS строки типа боли в колене)

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

 cellCount += colspan;

с участием:

 cellCount += colspan-0;

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


0

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

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

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


Прочитав документацию jQuery, я обнаружил, что сортируемая также принимает опцию «appendTo», которая указывает, к какому элементу добавляется помощник.
Шей Райли

0

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


-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
Требуется больше объяснений!
Афсанефда

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

-4

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

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

1
Кажется, не помогает.
Андрей
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.