[Rails] Cocoon動態Nested Form使用方式
前言
Cocoon可以方便快速建立動態Nested Form,避免手動寫一堆jQuery, 適合懶人、新手、不想用前端框架之人。
使用方式
# [path] gemfile
gem "cocoon"
// [path] application.js
//= require cocoon
基本用法
假設你有一個Project model:
rails g scaffold Project name:string description:string
而且這個 project 有很多 tasks:
rails g model Task description:string done:boolean project:belongs_to
你的模型是這樣關聯的:
class Project < ActiveRecord::Base
has_many :tasks, inverse_of: :project
accepts_nested_attributes_for :tasks, reject_if: :all_blank, allow_destroy: true
end
class Task < ActiveRecord::Base
belongs_to :project
end
現在我們需要一個可以動態新增和刪除任務的項目表單。
為此,我們需要一個新的或現有的 partial 取名為 _task_fields.html
params驗證部分需要加入
# [path] ProjectsController
def project_params
params.require(:project).permit(:name, :description, tasks_attributes: [:id, :description, :done, :_destroy])
end
範例
Cocoon預設要求使用link_to_add_association helper新增項目, 並將每個項目部份用partial包裝。下面的例子說明了簡單的佈局。
這邊使用SimpleForm舉例
<!-- [path] projects/_form -->
<%= simple_form_for @project do |f| %>
<%= f.input :name %>
<%= f.input :description %>
<h3>Tasks</h3>
<div id="tasks">
<%= f.simple_fields_for :tasks do |task| %>
<%= render 'task_fields', f: task %>
<% end %>
<div class="links">
<%= link_to_add_association 'add task', f, :tasks %>
</div>
</div>
<%= f.submit %>
<% end %>
另外,我們需要新增 _task_fields 這個partial
<div class="nested-fields">
<%= f.input :description %>
<%= f.input :done, as: :boolean %>
<%= link_to_remove_association "remove task", f %>
</div>
可以參考此範例 cocoon_simple_form_demo
Helper使用方式
###link_to_add_association
參數 | 值 | 說明 |
---|---|---|
name | String | |
f | from builder | |
association | from builder | 需要添加新實例的關聯(複數)的名稱(符號或字符串) |
html_options | 額外的html選項(參見link_to) | |
data-association-insertion-traversal | closest,next,children | jquery遍歷方法允許相對於鏈接的節點選擇。 |
data-association-insertion-node | 默認值:父節點 | 將節點的jquery選擇器作為字符串,或者以link_to_add_association節點為參數並返回節點的函數 |
data-association-insertion-method | before,after,append,prepend,等默認值:before | 插入新數據的jquery方法。 |
partial | String | 明確聲明將要使用的partial的名稱 |
render_options | String | 傳遞給表單構建器函數的選項(例如simple_fields_for,semantic_fields_for或fields_for)。如果它包含一個:locals包含哈希的選項,那麼它將被傳遞給部分。 |
wrap_object | 一個允許包裝對象的proc,特別是在使用裝飾器(例如draper)時很有用。見下面的例子。 |
例如:指定partial和產生項目的地方 <%= link_to_add_association ‘新增’, f, :barcodes, partial: ‘stock/products/forms/barcode/form_barcode’, ‘data-association-insertion-method’ => ‘before’, ‘data-association-insertion-node’ => ‘.panel-items’, ‘data-association-insertion-traversal’ => ‘closest’ %>
link_to_remove_association
參數 | 值 | 說明 |
---|---|---|
name | String | |
f | from builder | |
html_options | 額外的html選項(參見link_to) |
例如: 可以使用wrapper_class指定刪除的部份(原本預設是nested-fields)
<div class="barcode-fields">
<%= f.input :description %>
<%= f.input :done, as: :boolean %>
<%= link_to_remove_association "remove task", f, wrapper_class: 'barcode-fields' %>
</div>
參考
留言