テーブルグリッドをソート可能にするために、jQuery UIソート可能を使用しています。コードは正常に動作するようですが、td
sに幅を追加していないため、tr
をドラッグするとコンテンツが縮小します。
例えば;ドラッグを開始したときにテーブルの行が500ピクセルの場合、300ピクセルになります。グリッドに幅が定義されていないため、それが起こっていると思います。 td
sに2つのクラス(fix
とliquid
)を使用しているためです。
fix
クラスはtd
をコンテンツの幅と等しくし、liquid
はtd
の幅を100%にします。 td
sに幅を割り当てる必要のないグリッドテーブルのアプローチです。
私のアプローチでソート可能な仕事をする方法はありますか?
私は答えを見つけました こちら 。
オリジナルに幅を追加する代わりに、行を複製するために少し変更しました:
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;
},
私はそれが役立つと思う:
.ui-sortable-helper {
display: table;
}
ここで選択した答えは本当に素晴らしい解決策ですが、元のJSフィドルで明らかな重大なバグが1つあります( http://jsfiddle.net/bgrins/tzYbU/ ):最も長いドラッグを試してください行(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 + '"> </td>');
}
}).disableSelection();
JSフィドル: http://jsfiddle.net/rp4fV/4/
IE8では行の複製はうまく機能しないようですが、元のソリューションではうまくいきます。
jsFiddle でテストしました。
テーブルを並べ替える準備ができたら、次のコードを呼び出します。これにより、td要素がテーブル構造を壊さずに固定されていることを確認できます。
$(".tableToSort td").each(function () {
$(this).css("width", $(this).width());
});
$(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));
});
}
});
disableSelection()
のように思われます-現在、メソッドは不良であり、非推奨です。 Mozilla Firefox 35.0
では、ソート可能な行内でテキスト入力を使用できなくなりました。もう焦点が合わないだけです。
Keithのソリューションは問題ありませんが、Firefoxで少し大混乱を引き起こしました。 (膝の古いjs文字列型の痛み)
この行を置き換える:
cellCount += colspan;
で:
cellCount += colspan-0;
問題を修正します。 (jsは変数を文字列ではなく数字として扱うことを強制されるため)
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;
}
Daveの回答へのコメントとしてこれを追加しますが、このアカウントには十分な担当者がいませんでした。
さまざまな試みを何度も行った後、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;
};