#197 Nested Model Form Part 2
Add and remove nested model fields dynamically through JavaScript using either Prototype or jQuery.
- Download:
- source codeProject Files in Zip (121 KB)
- mp4Full Size H.264 Video (17.1 MB)
- m4vSmaller H.264 Video (12.4 MB)
- webmFull Size VP8 Video (34.2 MB)
- ogvFull Size Theora Video (23.6 MB)
Resources
_form.html.erb
<p><%= link_to_add_fields "Add Question", f, :questions %></p>
_question_fields.html.erb
<%= link_to_remove_fields "remove", f %> ... <p><%= link_to_add_fields "Add Answer", f, :answers %></p>
_answer_fields.html.erb
<%= link_to_remove_fields "remove", f %>
application.js
function remove_fields(link) { $(link).previous("input[type=hidden]").value = "1"; $(link).up(".fields").hide(); } function add_fields(link, association, content) { var new_id = new Date().getTime(); var regexp = new RegExp("new_" + association, "g") $(link).up().insert({ before: content.replace(regexp, new_id) }); }
application_jquery.js
function remove_fields(link) { $(link).prev("input[type=hidden]").val("1"); $(link).closest(".fields").hide(); } function add_fields(link, association, content) { var new_id = new Date().getTime(); var regexp = new RegExp("new_" + association, "g") $(link).parent().before(content.replace(regexp, new_id)); }
Update: The code below has been changed slightly to work with Rails 3.x (the h
escape call is removed)
helpers/application_helper.rb
module ApplicationHelper def link_to_remove_fields(name, f) f.hidden_field(:_destroy) + link_to_function(name, "remove_fields(this)") end def link_to_add_fields(name, f, association) new_object = f.object.class.reflect_on_association(association).klass.new fields = f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder| render(association.to_s.singularize + "_fields", :f => builder) end link_to_function(name, "add_fields(this, \"#{association}\", \"#{escape_javascript(fields)}\")") end end