每天一剂Rails良药之Creating a Drag-and-Drop Sortable List

今天来看看用Rails创建一个可拖拽的List。

1,创建Rails项目,搭建数据库
[code]
Migration:
class AddPersonAndGroceryListsAndFoodItemsTables < ActiveRecord::Migration
def self.up
create_table :people do |t|
t.column :name, :string
end
create_table :grocery_lists do |t|
t.column :name, :string
t.column :person_id, :integer
end
create_table :food_items do |t|
t.column :grocery_list_id, :integer
t.column :position, :integer
t.column :name, :string
t.column :quantity, :integer
end
end

def self.down
drop_table :people
drop_table :grocery_lists
drop_table :food_items
end
end

Model:
class Person < ActiveRecord::Base
has_many :grocery_lists
end

class GroceryList < ActiveRecord::Base
has_many :food_items, :order => :position
belongs_to :person
end

class FoodItem < ActiveRecord::Base
belongs_to :grocery_list
acts_as_list :scope => :grocery_list
end
[/code]
这里一个Person对应多个GroceryList,一个GroceryList对应多个FoodItem
我们可以运行[b]ruby script/console[/b]或者直接访问数据库来初始化几条数据
这里我们创建一个Person,一个GroceryList和3个FoodItem,并保持外键关联

2,引入javascript
可以通过用一个layout文件来做这件事,如app/views/layouts/standard.rhtml:
[code]
<html>
<head>
<%= javascript_include_tag :defaults %>
</head>

<body>
<%= yield %>
</body>
</html>
[/code]

3,创建一个列表controller
如app/controllers/grocery_list_controller.rb:
[code]
class GroceryListController < ApplicationController
layout 'standard'

def show
@grocery_list = GroceryList.find(params[:id])
end

def sort
@grocery_list = GroceryList.find(params[:id])
@grocery_list.food_items.each do |food_item|
food_item.position = params['grocery-list'].index(food_item.id.to_s) + 1
print food_item.position
food_item.save
end
render :noting => true
end

end
[/code]

4,创建列表视图
如app/views/grocery_list/show.rhtml:
[code]
<h2><%= @grocery_list.person.name %>'s Grocery List</h2>
<h3><%= @grocery_list.name %></h3>
<ul id="grocery-list">
<% @grocery_list.food_items.each do |food_item| %>
<li id="item_<%= food_item.id %>">
<%= food_item.quantity %> units of <%= food_item.name %>
</li>
<% end %>
</ul>

<%= sortable_element 'grocery-list',
:url => { :action => "sort", :id => @grocery_list },
:complete => visual_effect(:highlight, 'grocery-list')
%>
[/code]

5,访问看看效果
打开浏览器访问[url]http://localhost:3000/grocery_list/show/1[/url]看看
我们拖拽一条数据在列表中的位置,然后刷新页面,发现该条数据的位置在数据库中保存了

6,原理
我们的FoodItem类有一个position列,并且声明为acts_as_list,并且GroceryList按照position来排序,我们的sortable_element()这个helper方法为我们生成一段为Sortable.create(...)的JavaScript代码为我们做Ajax调用,访问sort方法,而sort方法则在数据库中保存列表经拖拽后的新的position。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值