世界上最伟大的投资就是投资自己的教育
如何在 Rails 中添加拖拽排序
Mikasa·Ackerman发布于3355 次阅读
准备
需要使用的 gem
gem 'acts_as_list'
gem 'jquery-ui-rails'
需要的 js 文件
//= require jquery-ui/jquery-ui.js
页面添加想要排序的列表
<table class="table table-bordered table-hover">
<thead>
<th>视频编号</th>
...
<th>操作</th>
</thead>
<tbody data-url="<%= sort_admin_round_manage_good_videos_path %>" data-behavior='sortable'>
<% @good_videos.each_with_index do |g, index| %>
<tr id="<%= dom_id(g) %>">
<td><%= g.id %></td>
...
<td><%= operate_buttons(good_video_operation(g)) %></td>
</tr>
<% end %>
</tbody>
</table>
<script>
$( "[data-behavior='sortable']" ).sortable({
update: function(e, ui) {
$.ajax({
url: $(this).data("url"),
type: "PATCH",
data: $(this).sortable('serialize')
})
}
});
</script>
第一种方式我们将排序后的序列整体发送到后台,后台需要添加响应的排序字段
rails g migration AddPositionToGoodVideo position:integer
rails db:migrate
控制器添加列表和排序 action
def index
@q = GoodVideo.ransack(params[:q])
@good_videos = @q.result.order(position: :desc)
end
# 这里使用第一种排序方式(优点:如果position值为空或者0,在经过之后将会按排序赋值,缺点:每次排序根据当前页面数据量生成大量sql,大量操作不建议使用。)
def sort
params[:good_video].reverse.each_with_index do |id, index|
GoodVideo.find_by(id: id).update(position: index + 1)
end
head :ok
end
路由配置
resources :good_videos do
collection do
patch :sort
end
end
总结:第一种方法 这样既可实现拖拽排序(这种方法弊端:如果有分页的话第二页的排序会有问题,所以这种排序是不可以有分页的,所有数据只能在一个页面,也就限制了不适用太大的数据量和频繁的操作。)
第二种方法
页面基本保持一致 js 有一些变化,这里我们获取了当前拖拽元素 id 释放后的位置的前后元素的 id
$( "[data-behavior='sortable']" ).sortable({
update: function(e, ui) {
params = "prev_id=" + $(ui.item[0]).prev().attr("id").split("_")[2] + "&id=" + $(ui.item[0]).attr("id").split("_")[2] + "&next_id=" + $(ui.item[0]).next().attr("id").split("_")[2];
$.ajax({
url: $(this).data("url"),
type: "PATCH",
data: params
})
}
});
排序方法也有相应修改并且 position 字段应采用 decimal 类型长度应尽量长一些,防止因长度不够,而造成多个 position 都为 0.00 的情况;对移动到第一位,或者最后一位做 if 处理。
def sort
good_video = GoodVideo.find(params[:id])
next_task = params[:next_id] && GoodVideo.find(params[:next_id])
prev_task = params[:prev_id] && GoodVideo.find(params[:prev_id])
position = if params[:prev_id].blank?
next_task.position / 2
elsif params[:next_id].blank?
prev_task.position + 100000
else
(prev_task.position + next_task.position) / 2
end
good_video.update(position: position)
end
总结:第二种方法排序生成的 sql 更少,仅仅通过上一位置和下一位置来生当前选择元素的排序值。分页的话也不会有问题,不过对于很多初始值就是 0.0 的排序来将不会给赋值,要手动拖拽后才会生成排序值。
本站文章均为原创内容,如需转载请注明出处,谢谢。
© 汕尾市求知科技有限公司 | Rails365 Gitlab | 知乎 | b 站 | csdn
粤公网安备 44152102000088号 | 粤ICP备19038915号
Top
不错