Nested form fields trong rails
Là một gem của rails giúp tạo ra form cho model cùng với quan hệ nested has_many Gem này sử dụng JQuery để tự động thêm vào xóa đi quan hệ nested Làm việc với các quan hệ nested lồng nhau (có thể lên đến mức 4) Làm việc cùng với form builders giống như simple_form Yêu cầu ruby 1.9 trở lên ...
Là một gem của rails giúp tạo ra form cho model cùng với quan hệ nested has_many Gem này sử dụng JQuery để tự động thêm vào xóa đi quan hệ nested
- Làm việc với các quan hệ nested lồng nhau (có thể lên đến mức 4)
- Làm việc cùng với form builders giống như simple_form
- Yêu cầu ruby 1.9 trở lên
Cài đặt
Thêm dòng này vào Gemfile trong ứng dụng của bạn
gem "nested_form_fields"
và chạy lệnh
$ bundle
Trong file application.js của ứng dụng bạn thêm vào dòng sau để có thể sử dụng được file nested_form_fields.js.coffee //= require nested_form_fields
Sử dụng
Giả sử bạn có model User cùng với nested videos:
class User < ActiveRecord::Base has_many :videos accepts_nested_attributes_for :videos, allow_destroy: true end
Sử dụng nested_fields_for hepler bên trong user form của bạn để thêm vào các videos
= form_for user do |f| = f.nested_fields_for :videos do |ff| = ff.text_field :video_title ..
Đường link để thêm và xóa các field là add_nested_fields_link and remove_nested_fields_link
= form_for user do |f| = f.nested_fields_for :videos do |ff| = ff.remove_nested_fields_link = ff.text_field :video_title .. = f.add_nested_fields_link :videos
Chú ý rằng remove_nested_fields_link được gọi bên trong nested_fields_for và add_nested_fields_link được gọi từ bên ngoài thông qua parent builder.
Sửa đổi link
Chúng ta có thể thay đổi tên link của remove_nested_fields_link và add_nested_fields_link như thế này:
... ff.remove_nested_fields_link "Remove me" ... f.add_nested_fields_link :videos, "Add another funtastic video"
Chúng ta có thể thêm class/addtributes vào remove_nested_fields_link and add_nested_fields_link giống như:
... ff.remove_nested_fields_link "Remove me", class: "btn btn-danger", role: "button" ... f.add_nested_fields_link :videos, "Add another funtastic video", class: "btn btn-primary", role: "button"
Bạn có thể thêm vào một khối vào remove_nested_fields_link và the add_nested_fields_link như thể bạn dùng link_to
= ff.remove_nested_fields_link do Remove me %span.icon-trash
Bạn có thể thêm vào thuộc tính data-confirm vào remove_nested_fields_link nếu bạn muốn người dùng confirm bất kể khi nào họ muốn xóa một nested field:
= ff.remove_nested_fields_link "Remove me", data: {confirm: "Are you sure?"}
Custom Container
Bạn có thể định nghĩa một custom container để thêm vào trong nested forms bằng cách cung cấp một id thông qua thuộc tính data-insert-into của add_nested_fields_link:
f.add_nested_fields_link :videos, "Add another funtastic video", data: {insert_into: "<container_id>"}
Custom Fields Wrapper
Bạn có thể thay đổi kiểu của các phần tử wrapping trong nested fields sử dụng thuộc tính wrapper_tag:
= f.nested_fields_for :videos, wrapper_tag: :div do |ff|
Các phần tử wrapper mặc định là một fieldset. Để thêm phần tử legend vào fieldset thì sử dụng:
= f.nested_fields_for :videos, legend: "Video" do |ff|
Bạn có thể dùng wrapper_options để truyền vào một hash các lựa chọn, giống như bạn sử dụng phương thức content_tag
= f.nested_fields_for :videos, wrapper_options: {class: "row"} do |ff|
Parameter trong rails 4
Trong rails 4 để truyền về các params bạn phải khai báo {{ NESTED_MODEL }}_attributes trong controller. Nếu bạn muốn xóa các nested model bạn nên thêm vào :_destroy and :id. Ví dụ:
# app/views/users/_form.haml.erb = form_for user do |f| = f.nested_fields_for :videos do |ff| = ff.remove_nested_fields_link = ff.text_field :video_title .. = f.add_nested_fields_link :videos
# app/controllers/users_controller .. def user_params params.require(:user) .permit(:name,:email,videos_attributes[:video_title,:_destroy,:id]) end
Sự kiện
Có 4 sự kiện javascript trước và sau khi thêm/xóa các field trong nested_form_fields tên là:
- fields_adding
- fields_added
- fields_removing
- fields_removed
Sự kiện fields_added and fields_removed được trigger trên phần tử khi đang được thêm hoặc xóa bỏ. Dễ dàng để thêm các listener khi mà có nhiều nested_form_fields trên những các trang tương tự nhau.
Ví dụ CoffeeScript:
# Listen on an element initializeSortable -> ($el) $el.sortable(...) $el.on 'fields_added.nested_form_fields', (event, param) -> console.log event.target # The added field console.log $(this) # $el # Listen on document $(document).on "fields_added.nested_form_fields", (event, param) -> switch param.object_class when "video" console.log "Video object added" else console.log "INFO: Fields were successfully added, callback not handled."
Bạn có thể truyền bất kỳ dữ liệu mở rộng nào trong sự kiện callback
# Trigger button click programmatically and pass an object `{hello: 'world'}` $('.add_nested_fields_link').trigger('click', [{hello: "world"}]) # Listen for the event $(document).on "fields_added.nested_form_fields", (event, param) -> console.log param.additional_data #=> {hello: "world"}