jquery UI Сортировка із шириною таблиці та tr


155

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

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

fixКлас робить tdдорівнює ширині вмісту і liquidробить td100% ширини. Це мій підхід до таблиці сітки, не привласнюючи ширину tds.

Будь-яка ідея, як змусити сортувати роботу з моїм підходом?


3
Відповідь Ярослава - РЕАЛЬНА mvp!
Брейд

У мене було те саме питання, я думаю, що @Yaroslav має правильну відповідь для роботи з таблицями, про що запитує ОП
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;
  },

@Dave Джеймс Міллер Як би ви зробили, що варіант заповнення заповнення працює?
shaun5

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

9
Це працює досить добре, але я думаю, що існує ще одна незначна проблема; коли ви перетягуєте / відпускаєте рядок, решта стовпців таблиці можуть змінити ширину через відсутність рядка. Я думаю, їх ширину потрібно також фіксувати ...
Jez

1
Це врятувало мені стільки роботи. Це слід позначити як правильну відповідь.
Андрій Бесса

3
Я виявив, що ширина призводила до того, що вкладені комірки НЕ ВЖЕ були правильними. Я помінявся на$(this).width($originals.eq(index).outerWidth());
Barry Carlyon

166

Я думаю, що це може допомогти:

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

13
Як це не найкраща відповідь? Один простий рядок CSS виправляє це для мене.
jcrowson

8
Я згоден! Ви не вірите, як один простий рядок CSS виправляє вашу сортову таблицю - фахівці Stackoverflow викликають здивування!
Брейд

3
Це відповідь. Дякуємо @Yaroslav
Steffi

3
Це НЕ загальне рішення і призведе до різного вигляду перетягнутого ряду
Tomas M

13
Це рішення дуже добре, але може вплинути на інші списки, які не є таблицею. Моя пропозиція - ви відредагуєте свою відповідь для більш конкретної. Приблизно так => таблиця tr.ui-sortable-helper {дисплей: таблиця! Важливо; }
Рафаель Гомес Франсіско

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/


Дякую, ти економиш мій час
super pantera

Техніка заповнення тут вбивця! Повністю вирішив мою проблему.
jessegavin

1
Це рішення насправді дуже добре, а техніка заповнення дійсно міцна, на мою думку, це має бути обрана відповідь.
Кріс Джеймс Шампо

1
Це все ще викликає неприємну поведінку, коли у вас дуже високий ряд. Усі інші ряди будуть ховатися за ним. Я додав би це до стартового методу:$(".must-have-class").css("height", $(ui.item).outerHeight());
Itzik Ben Hutta

6

Здається, що клонування рядка не працює добре на IE8, але оригінальне рішення все-таки є.

Тестується за допомогою jsFiddle .


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

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 було трохи хаосу, який не додав колпанів, а підказав їх. (Старий 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.