Skip to content
This repository was archived by the owner on May 28, 2019. It is now read-only.

Multi level Nested Fields

Sergey A. Glukhov edited this page Sep 26, 2013 · 4 revisions

Multi-level Nested Fields

It is possible to have multi-level nested items. To do this, you will need to use some other options when calling nested_fields_for and nestedFields(), so awesome nested fields can identify which item it is dealing with.

When calling nested_fields_for

You will need to use the view option new_item_index, so the different form items can be identified.

<!-- ERB Code -->
<%= f.nested_fields_for :resources, new_item_index: 'new_resource_item' do |f| %>
  <% ... %>
<% end %>

Besides, the template of the outer item (that has another item inside) has to be rendered manually to avoid templates to be recursively repeated.

<!-- ERB Code -->
<div class="tasks-container">
  <%= f.nested_fields_for :tasks, render_template: false, new_item_index: 'new_task_item' do |f| %>
    <% ... %>
  <% end %>
</div>
<%= nested_fields_templates %>

The code above generates all templates with respective new_item_index like below:

<input id="project_tasks_attributes_new_task_item_resources_attributes_new_resource_item_name" name="project[tasks_attributes][new_task_item][resources_attributes][new_resource_item][name]" size="30" type="text"/>

When calling nestedFields()

It is necessary to call nestedFields() in each level of fields, so you need to differentiate the elements (items, container, add, remove) of each model. It is also necessary to identify which template should be used by itemTemplateSelector option. Additionally when a first-level nested field is added you have to use afterInsert callback to:

  1. Apply nestedFields() to its nested field (so this deeper item can take advantage of awesome nested fields).

  2. Insert an item of the deeper model, so the user can gracefully fill it.

     // JS Code
    
     // Options for deeper nested fields
     resourcesOptions = {
       itemSelector: '.resource',
       containerSelector: '.resources-container',
       addSelector: '.resource-add',
       removeSelector: '.resource-remove',
       itemTemplateSelector: '.resource.template', // Identifies which template to use
       newItemIndex: 'new_resource_item' // Same used on view options
     };
    
     // Apply nestedFields to the outsider nested fields (first nested fields level)
     $('.project-form').nestedFields({
       itemSelector: '.task',
       containerSelector: '.tasks-container',
       addSelector: '.task-add',
       removeSelector: '.task-remove',
       itemTemplateSelector: '.task.template',
       newItemIndex: 'new_task_item',
       afterInsert: function(item) {
         // Applies nestedFields to this task's resources (deeper field)
         item.find('.nested-level-2').nestedFields(resourcesOptions);
         // Inserts a resource item (of the deeper field)
         item.find('.nested-level-2').nestedFields('insert');
       }
     });
    
     // Applies nestedFields to all projects tasks on page (to the second nested fields level)
     $('.project-form').find('.nested-level-2').nestedFields(resourcesOptions);
    

You can view a demo of multi level nested fields at https://github.com/julianalucena/multi_level_awesome_nested_fields_demo.

Clone this wiki locally