jquery - Rails Nested Attributes form_for for has_many with unlimited nested models using javascript -
so i've got pretty simple model nested attributes set up:
class property < activerecord::base has_many :trees accepts_nested_attributes :trees end then build them in controller:
class propertiescontroller < applicationcontroller def new @property = properties.new @trees = @property.trees.build end end and in view (using slim):
= form_for @property |p| = p.text_field :name .tree = p.fields_for :trees |t| = t.text_field :fruit = t.select :quantity, (1..1000).to_a = link_to 'add tree', new_properties_path, id: 'new-tree' and in js (coffeescript) file, bound click event of '#new-tree' anchor:
event.preventdefault() tree = $(event.target).parents('.tree') tree.after tree.clone(true) this works expect, when submit form, last tree params submitted. because in generated html of form_for this:
<input type="text" id="property_trees_attributes_0_fruit" name="property[trees_attributes][0][fruit]"> <select id="property_trees_attributes_0_quantity" name="property[trees_attributes][0][quantity]" class="valid"> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> ... </select> and when clone html name , id 0 in it, though believe should 1 add additional tree params, etc.
i tried compensate js doing this:
event.preventdefault() tree = $(event.target).parents('.tree') clone = tree.clone() number = parseint(clone.find('input[type=text]').attr('id').match /[0-9]/) next = number + 1 clone = clone.html().replace /_(#{number})_|\[(#{number})\]/, next section.after clone the point of regex replace numbers between 2 underscores or 2 brackets, _0_ or [0]
my regex doesn't seem work though. replaces _0_ 1 , solution seems messy me anyways. make regex simpler, have worry changing value of select menu options.
any suggestions cleaning up? missing obvious?
the problem have you're duplicating dom elements - imo hack, you're not building objects need before-hand (won't persist data etc)
we've implemented "add fields f.fields_for" using ajax before - there's great tutorial here , railscast here
child_index
the answer question use child_index option in fields_for helper, , make use integer timestamp:
<% index = time.now.to_i %> <%= f.fields_for :trees, child_index: index |fields| %> #your fields here <% end %> code
here's do:
#app/views/properties/new.html.erb <%= form_for @property |f| %> <%= render partial: "trees_fields", locals: { f: f, child_index: time.now.to_i } %> <%= link_to "new field", new_field_property_path %> <% end %> #app/views/properties/_trees_fields.html.erb <%= f.fields_for :trees, child_index: child_index |trees| %> <%= trees.text_field :your_attr %> <% end %> #app/controllers/properties_controller.rb def new_field @property = property.new @property.trees.build render "add_tree", layout: false end #app/views/properties/add_tree.html.erb <%= form_for @property |f| %> <%= render partial: "trees_fields", locals: {f: f, child_index: time.now.to_i} %> <% end %> #app/assets/javascripts/application.js.coffee $ -> $(document).on "click", "#add_tree", (e) -> e.preventdefault(); $.ajax url: '/messages/add_subscriber' success: (data) -> el_to_add = $(data).html() $('#trees_form').append(el_to_add) error: (data) -> alert "sorry, there error!"
Comments
Post a Comment