Sortable Bootstrap Tables (in Rails)
Bài đăng này đã không được cập nhật trong 3 năm
Sau đây mình xin giới thiệu cho các bạn một gem trong rails hỗ trợ các bạn trong việc sắp xếp và thay đổi thứ tự các bản ghi trong danh sách các bản ghi. Nó sẽ hỗ trợ các bạn kéo thả bằng việc sử dụng thư viện của JQuery ( JQuery UI Gem) làm việc sắp xếp trở nên sinh động và dễ dàng hơn. Nào hãy cùng tìm hiểu cách sử dụng nó nhé, nó cũng không quá khó để cài đặt.
I. Tổng quan
Bài viết sẽ giúp các bạn làm sao để thêm sắp xếp bằng cách kéo thả vào bảng trong rails. Ở đây chúng ta sử dụng ranked-model
và JQuery-UI
II. Sortable list gems
ranked.rb
def update_index_from_position
case position
when Integer
neighbors = neighbors_at_position(position)
min = (neighbors[:lower] ? neighbors[:lower].rank : RankedModel::MIN_RANK_VALUE)
max = (neighbors[:upper] ? neighbors[:upper].rank : RankedModel::MAX_RANK_VALUE)
rank_at( ( ( max - min ).to_f / 2 ).ceil + min )
end
end
ranked-model thực hiện bằng cách tăng thứ hạng nằm giữa khoảng từ -8388607 đến 8388607 (mở rộng của MEDIUMMINT trong MySQL). Điều gì sẽ xảy ra nếu sau vài nghìn lần sắp xếp một danh sách các số được sắp xếp thứ tự sẽ gối lên nhau, hoặc chúng sẽ vượt ra khỏi giới hạn? Trong trường hợp này, tất cả bảng sẽ được cập nhật...
ranked.rb
def assure_unique_position
if ( new_record? || rank_changed? )
unless rank
rank_at( RankedModel::MAX_RANK_VALUE )
end
if (rank > RankedModel::MAX_RANK_VALUE) || current_at_rank(rank)
rearrange_ranks
end
end
end
Nói một cách thực tế, nếu số lượng sắp xếp trên web của bạn không quá nhiều thì vấn đề này hoàn toàn có thể được giải quyết. Tuy nhiên, ranked-model
khá dễ dàng để cài đặt và không có lý do gì để chúng ta không sử dụng nó.
III. Cài đặt
Cài đặt gem và thêm trường vào model.
Gemfile
gem "ranked-model"
models/thing.rb
class Thing < ActiveRecord::Base
include RankedModel
ranks :row_order
end
db/migrate/20140908010519_add_row_order_to_things.rb
class AddRowOrderToThings < ActiveRecord::Migration
def change
add_column :things, :row_order, :integer
end
end
Update Row Order Controller Action Đầu tiên chúng ta cần viết hàm để cập nhật việc sắp xếp row_order_position. Nó sẽ cần số thứ tự và id của model cần sắp xếp. Chúng ta sẽ làm rõ ở phần gửi chúng qua AJAX POST ở phần sau.
controllers/admin/things_controller.rb
class ThingsController < ApplicationController
def index
@things = Thing.rank(:row_order).all
end
def update_row_order
@thing = Thing.find(thing_params[:thing_id])
@thing.row_order_position = thing_params[:row_order_position]
@thing.save
render nothing: true # this is a POST action, updates sent via AJAX, no view rendered
end
private
# Use callbacks to share common setup or constraints between actions.
def set_thing
@thing = Thing.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def thing_params
params.require(:thing).permit(:thing_id, :title, :description, :row_order_position)
end
end
Thêm route cho sort
config/routes.rb
resources :things do
post :update_row_order, on: :collection
end
Bây giờ, chúng ta sẽ thêm JavaScript để kéo thả sử dụng JQuery UI Gem
Chúng ta cần sortable và highlight modules.
assets/javascripts/admin/application.js
//= require jquery
//= require jquery_ujs
//= require jquery-ui/sortable
//= require jquery-ui/effect-highlight
//= require turbolinks
//= require_tree .
assets/javascripts/admin/update_things_row_order.js.coffee
jQuery ->
if $('#sortable').length > 0
table_width = $('#sortable').width()
cells = $('.table').find('tr')[0].cells.length
desired_width = table_width / cells + 'px'
$('.table td').css('width', desired_width)
$('#sortable').sortable(
axis: 'y'
items: '.item'
cursor: 'move'
sort: (e, ui) ->
ui.item.addClass('active-item-shadow')
stop: (e, ui) ->
ui.item.removeClass('active-item-shadow')
# highlight the row on drop to indicate an update
ui.item.children('td').effect('highlight', {}, 1000)
update: (e, ui) ->
item_id = ui.item.data('item-id')
position = ui.item.index() # this will not work with paginated items, as the index is zero on every page
$.ajax(
type: 'POST'
url: '/things/update_row_order'
dataType: 'json'
data: { thing: {thing_id: item_id, row_order_position: position } }
)
)
Table Markup Bây giờ, chúng ta sẽ thêm bootstrap table markup. Mỗi hàng của bảng có 1 class của đối tượng chỉ định trong tùy chọn của JQuery UI sortable. Thing.id thích hơpj sẽ được thêm vào mỗi hàng và truyền vào update_row_controller.
views/admin/things/index.html.erb
<table class="table table-bordered table-striped" id="sortable">
<thead>
<tr>
<th>
Title
</th>
<th>
Description
</th>
</tr>
</thead>
<tbody>
<% @things.each do |thing| %>
<tr data-item-id=<%= thing.id %> class="item">
<td>
<%= thing.title %>
</td>
<td>
<%= link_to "show", thing_path(thing), class: "btn btn-default pull-right" %>
</td>
</tr>
<% end %>
</tbody>
</table>
Vậy là chúng ta đã có thể sắp xếp trong bảng chỉ với một số cài đặt đơn giản. Mong rằng bài viết này có thể giúp các bạn có thêm những lựa chọn cho việc sắp xếp dữ liệu. Các bạn có thể xem thêm tại:
Chúc các bạn thành công.
All rights reserved