ryanb / nested_form

Rails plugin to conveniently handle multiple models in a single form.
MIT License
1.79k stars 505 forks source link

add/remove deep nested forms (tested it on 3 levels) #344

Open lior-greenblatt opened 9 years ago

lior-greenblatt commented 9 years ago

First, thanks a lot for this wonderful gem - made my life much easier! This is more of a solution to a problem that kept me up for a few hours which I think more can enjoy. I am working on a form with multiple nesting levels and came across a problem with getting add_link_to to add the third level element only to the second level it is related to, after some trials I was forced to hack the javascript code a little and to add another data attribute in order to get it to work the way I wanted. I made the following changes: in the js file I made these changes:

    insertFields: function(content, assoc, link) {
      var target = $(link).data('target');
+      var downParent = $(link).data('down-parent');
+      if (target) {
+       if (downParent && downParent.length > 0) {
+         target = $(link).closest(downParent).find(target);
+         return $(content).appendTo(target);
+       }
        return $(content).appendTo($(target));
      } else {
        return $(content).insertBefore(link);
      }
    },

once this was done it was easy, all I had to do was to tell add_link_to on which parent to hang the blueprint: First, mark the the appropriate fields, e.g.

<tr class="fields theTarget">
<table class="fieldsAddedToMe">
<tr class="fields">
....
</tr>
</table>
</tr>

Second, let js know what parent to start looking for the fields to hang the blueprint, e.g. <%= f.link_to_add(content_tag(:span, "clickme"), :your_model, data: { target: ".theTarget", down_parent: '.fieldsAddedToMe' }) %> This will search for fields related to fieldsAddedToMe only under the theTarget element, rails takes care of the rest.

Startouf commented 9 years ago

I had solved this problem by sending everytime all the form_builders variables in the nested partials with a different name : level1_f, level2_f.... Therefore i could generate appropriate IDs using ##{level1_f.index}-#{level2_f.index}...

(then I can tag some HTML with this ID, and use it as a target for link_to_add)