解決策の 1 つは、 acts_as_list および ActiveAdmin を使用したソート可能なリストで説明されています。ソリューションは非常に優れており、自分で追加できるのは、少し異なるシリアライゼーション関数といくつかの装飾的なものだけです。
まず第一に、目的のリソースを指定された位置に移動する方が、その後にあるすべてをシフトするよりも効率的であると考えました。これが私の更新されたupdate
関数です:
$("#shows tbody").sortable({
update: function(event, ui){
var request
if (ui.item.next().length == 0)
request = {method: 'move_to_bottom', target: ui.item.find("span.show").data("id")}
else
request = {method: 'put_at_index', data: ui.item.next().find("span.show").data("id"), target: ui.item.find("span.show").data("id")}
$.ajax({
url: "/admin/shows/sort",
type: 'post',
headers: {
'X-Transaction': 'sort shows',
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
},
data: request,
complete: function(){
$(".paginated_collection").effect("highlight");
repaintTable();
}
});
}
});
ご覧のとおり、put_at_index
何を配置するか、どのアイテムのインデックス (実際にはドラッグしたアイテムの下のアイテム) にデータを含むメソッドを送信し、それがリストの一番下にドラッグされた場合、その下には何もありません。 (その後)次に、move_to_bottom
何を一番下に移動するかをデータとともにメソッドに送信します。
sort
アクションも変更され、次のように機能するようになりました。
collection_action :sort, :method => :post do
case params[:method]
when 'move_to_bottom'
Show.find(params[:target]).move_to_bottom
when 'put_at_index'
Show.find(params[:target]).insert_at(Show.find(params[:data]).position)
end
head 200
end
したがって、acts_as_list のメソッドをinsert_at
使用するだけです。move_to_bottom
また、切り替え後も奇数行と偶数行の色が異なるように追加しrepaintTable
、ajaxリクエストが完了した後に呼び出します。
function repaintTable()
{
$("#shows tr").removeClass('even odd');
$("#shows tr").filter(":odd").addClass('odd');
$("#shows tr").filter(":even").addClass('even');
}
欠点は、スコープ、フィルター、および列による並べ替えではうまく機能しないことです。