一直想實現表格的排序,網上查到wice_grid是個很不錯的gem,看了例子也覺得超炫酷。所以bundle install來嘗試一下。但不知道為何總有一些莫明其妙的問題使用不上。所以想自己嘗試寫一下。
剛開始準備用AJAX來實現,正好顯擺一下自己前兩天剛剛學會的技巧,但苦于基礎太差。嘗試失敗。
又想排序即使用同步實現的話,從用戶的角度上來說,應該可以接受。所以就嘗試用同步的方式來做。
代碼寫的很亂,性能也沒有驗證,但萬幸功能實現了。具體如下:
- routes中增加一個路由:
match "/products/sort_by/:sort_id", to: "products#sort_by", via: "get"
- 在products/index.html.erb中修改一下代碼,使得表頭變成鏈接:
<table class="table table-striped">
<thead>
<tr>
<th><%= link_to "ID", "/products/sort_by/#{@order[:p_id]}" %></th>
<th><%= "Name" %></th>
<th><%= link_to "Price", "/products/sort_by/#{@order[:p_price]}" %></th>
<th><%= link_to "Description", "/products/sort_by/#{@order[:p_description]}" %></th>
<th><%=t '.actions', :default => t("helpers.actions") %></th>
</tr>
</thead>
需要注意的是, @order[:p_id]中的”:p_id",定義在controller的order_init
方法中。
- 對應的productscontroller中增加下面的代碼:
def index
@products = Product.all.paginate(page: params[:page], per_page: 12)
#初始化排序相關的數據
@order = order_init
end
def sort_by
@order = order_init
#判斷傳過來的參數是否是正確的值,如果是,進行排序,如果不是,跳轉到root_path
#@order[:p_by]是一個數組,包含所有字段正序和倒序的情況
if @order[:p_by].include?(params[:sort_id])
@products = Product.all.order("%s %s" % params[:sort_id].split("_")[1..2])
#在前面已經把所有列的排序情況初始化了,下面是當某一列進行排序后,下一次點擊則變為反序
order_change(@order, params[:sort_id])
@products = @products.paginate(page: params[:page], per_page: 12)
respond_to do |format|
#一定要用render,這樣@products才是排序后的數據
format.html {render 'index'}
end
else
redirect_to root_path
end
end
private
#初始化@order,如果要增加可排序的列,只需要在這個方法增加order[:column] = "column_desc"即可
def order_init
order = {}
order_by = ["desc", "asc"]
order[:p_price] = "p_price_desc"
order[:p_id] = "p_id_desc"
order[:p_description] = "p_description_desc"
order[:p_by] = []
order.keys.each do |key|
order_by.each { |ele| order[:p_by] << "#{key.to_s}_#{ele}" }
end
return order
end
#當某一列進行排序后,下一次點擊則變為反序
def order_change(order, string)
temp = string.split("_")
key = temp[0] + "_" + temp[1]
value = temp[2]
value = value == "desc" ? "#{key}_asc" : "#{key}_desc"
order[key.to_sym] = value
end
這樣就OK了