简体   繁体   中英

How to dynamically add a (HABTM) collection_select + associated text_field in a Rails form?

For a personal invoicing app in rails I could use some advice on the following: In a new invoice form, how to dynamically add a new row consisting of a collection_select for products and an associated text_field for amount by clicking add new product ?

Since one invoice has many products and a product has many invoices, I figured this is a HABTM relationship both ways. Therefore I have created the tables invoices , products , and their join table invoices_products .

I would like the invoices/new page to have a form where a user can use a collection_select to pick a product (all products are already preloaded in the products table) and fill in the amount in a text field behind it. A user should be able to duplicate these two fields (collection_select and text_field) by clicking add new product , something like RailsCast #403 Dynamic Forms 04:50 .

Now how would I go about doing that? And in what table would I put the data from the amount text_field, since there are multiple products per invoice so multiple amounts?

Any answer in the right direction will be greatly appreciated!

This depends on how many additional fields you want

A good tutorial for this can be found here


Ajax

The right way would be to add the element dynamically with Ajax

This is tricky because it means you're not going to have the form_builder object available for the dynamically added items. Regardless, you can still do it with this code:

#config/routes.rb
get "new_field_path", to: "invoices#new_item"

#app/views/controller/index.html.erb
<%= ... form %>
<%= link_to "Add Field", new_field_path, remote: :true %>

Controller

#app/controllers/invoices_controller.rb
def new_item
   @invoice = Invoice.new
   @invoice.products.build
   render "new_item", layout: false
end

#app/views/invoices/new_item.html.erb
<%= form_for @invoice do |f| %>
    <%= render partial: "products_fields", locals: { f: f } %>
<% end %>

#app/views/invoices/_products_fields.html.erb
<%= f.fields_for :products, child_index: Time.now.to_i do |p| %>
    <%= p.text_field :name %>
<% end %>

Form

#app/views/invoices/new.html.erb
<%= form_for @invoice do |f| %>
   <%= render partial: "products_fields", locals: { f: f } %>
   <%= link_to "Add Field", new_field_path, remote: :true %>
   <%= f.submit %>
<% end %>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM