jquery UI Sortable with table and tr width


155

テーブルグリッドを並べ替え可能にするためにjQuery UIを並べ替え可能にしています。コードは問題なく動作するようですが、tdsに幅を追加していないため、ドラッグするtrとコンテンツが縮小します。

例えば; ドラッグを開始したときにテーブルの行が500pxの場合、300pxになります。グリッドで幅が定義されていないので、それが起こっていると思います。これは、tds fixとに2つのクラスを使用しているためですliquid

fixクラスが行うtdコンテンツ幅に等しいとliquidなるtd幅100%。これは、tds に幅を割り当てる必要がないグリッドテーブルの私のアプローチです。

私のアプローチでソート可能な作業を行う方法はありますか?


3
ヤロスラフの答えはREAL 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;
  },

@Dave James Millerプレースホルダーオプションをどのように機能させますか?
shaun5 2012年

5
デイブ、これを共有してくれてありがとう、私はjsFiddleを作成して、元の、変更された、適用された修正なしの違いを示しています:jsfiddle.net/bgrins/tzYbU。また、元の投稿をソリューションで更新します。
ブライアングリンステッド

9
これは非常にうまく機能しますが、まだ1つのわずかな問題があると思います。行をドラッグ/ドロップすると、行が欠落しているため、残りのテーブル列の幅が変わる場合があります。幅も固定する必要があると思います...
Jez

1
これにより、多くの作業を節約できました。正解としてマークする必要があります。
Andrew Bessa

3
幅が原因で埋め込みセルが発生し、QUITEが正しくないことがわかりました。交換しました$(this).width($originals.eq(index).outerWidth());
Barry Carlyon

166

私はそれが役立つと思います:

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

13
これが一番の答えではないのはなぜですか?CSSの簡単な1行でそれが修正されます。
jcrowson

8
同意する!CSSの簡単な1行でソート可能なテーブルを修正する方法を信じられません-Stackoverflowの専門家は困惑しています!
Brade

3
これが答えです。おかげで@Yaroslav
Steffi

3
これは一般的な解決策ではなく、ドラッグされた行の外観が異なります
Tomas M

13
このソリューションは非常に優れていますが、テーブルではない他のリストに影響を与える可能性があります。私の提案は、より具体的にするためにあなたの答えを編集することです。このように=> table tr.ui-sortable-helper {display:table!important; }
ラファエルゴメスフランシスコ

29

ここで選択した答えは本当に良い解決策ですが、元のJSフィドル(http://jsfiddle.net/bgrins/tzYbU/)に明らかな重大なバグが1つあります。最長の行をドラッグしてみてください(God Bless You、Mr .Rosewater)、および残りのセル幅は縮小します。

これは、ドラッグされたセルのセル幅を固定するだけでは不十分であることを意味します。テーブルの幅も固定する必要があります。

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

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

JSフィドル: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フィドル:http : //jsfiddle.net/rp4fV/4/


ありがとう、あなたは私の時間を節約します
スーパーパンテラ2013

ここのプレースホルダーテクニックはキラーです!私の問題を完全に解決しました。
jessegavin 14

1
この解決策は実際に非常に優れており、プレースホルダーテクニックは非常にしっかりしています。これが私の意見では選択された答えになるはずです。
Chris James Champeau 2016年

1
行が非常に多い場合でも、これは不快な動作を引き起こします。他のすべての行はその後ろに隠れます。私は、startメソッドにこれを追加します。$(".must-have-class").css("height", $(ui.item).outerHeight());
ItzikベンHutta

6

行のクローンはIE8ではうまく機能しないようですが、元のソリューションではうまくいきます。

jsFiddleでテストされています


jsFiddleを設定していただきありがとうございます。Jezが指摘したように、行をドラッグすると他の行のセルの幅が変わる可能性があるため、元のソリューションを使用します。
Roger

4

テーブルを並べ替える準備ができたら、次のコードを呼び出します。これにより、td要素がテーブル構造を壊すことなく修正されます。

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

はい、それは私の答えとほとんど同じですが、私のthものも同様に機能しtdます。ドラッグされた行の折りたたみとテーブルの折りたたみは修正されますが、幅は修正されます。
キース

1

jsFiddle

さまざまな試みを繰り返した後、最大の行をドラッグしているときにテーブルが縮小するのを防ぐために、Dave James Millerのソリューションを完成させる単純なソリューションを試しました。それが役に立てば幸いです:)

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

Dave James Millerの答えは私にとってはうまくいきましたが、私のページのコンテナー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;
}

私はこれをデイブの回答へのコメントとして追加しましたが、このアカウントに対する十分な担当者がいませんでした。


jQueryのドキュメントを読んだ後、sortableがヘルパーを追加する要素を指定する「appendTo」オプションも取ることがわかりました。
Shea Riley

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
詳細な説明が必要です!
Afsanefda

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

-4

jquery-uiのAPIで説明されているように、ソータブルをテーブルのtbody要素に適用し、ヘルパーを 'clone'に設定するだけです

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

1
役に立たないようです。
アンドリュー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.