D
D
Denis Lysenko2014-05-04 22:30:28
ruby
Denis Lysenko, 2014-05-04 22:30:28

How to dynamically add fields to a Rails form?

Actually, there is a form for creating/editing the Page entity. Inside this form, we need to render all existing Blocks that are bound to this Page (Page has_many :blocks). The question itself is this - how in the rails way style to make the "Add block" button through AJAX render new block fields (which are rendered for already existing blocks inside fields_for).

<%= form_for([@page.site, @page]) do |f| %>

  <%= model_errors(@page) %>
    
  <div class="form-group">
    <%= f.label :slug, 'Адрес' %><br>
    <%= f.text_field :slug, class: 'form-control' %>
  </div>

  <h2 class="sub-header">Блоки</h2>
  <div id="pageBlocks" class="page-blocks">
    <%= f.fields_for :blocks do |ff| %>
      <div class="form-group">
        <%= ff.label :name, 'Название' %><br>
        <%= ff.text_field :name, class: 'form-control' %>
      </div>
      <div class="form-group">
        <%= ff.label :content, 'Содержание' %><br>
        <%= ff.text_area :content, class: 'form-control' %>
      </div>
    <% end %>

    <%= link_to 'Новый блок', "#", :class => 'btn btn-default', id: 'addBlock' %>
  </div>

  <%= f.submit class: 'btn btn-default' %>

<% end %>

The form now looks like this:
<form accept-charset="UTF-8" action="/account/sites/1/pages/1" class="edit_page" id="edit_page_1" method="post"><div style="display:none"><input name="utf8" type="hidden" value="&#x2713;" /><input name="_method" type="hidden" value="patch" /><input name="authenticity_token" type="hidden" value="/kqBgcHd+97ICZaE0YrwXDtX4/TzGaawetMUawJCsss=" /></div>

  <div class="form-group">
    <label for="page_slug">Адрес</label><br>
    <input class="form-control" id="page_slug" name="page[slug]" type="text" value="/" />
  </div>

  <h2 class="sub-header">Блоки</h2>
  <div id="pageBlocks" class="page-blocks">
    
      <div class="form-group">
        <label for="page_blocks_attributes_0_name">Название</label><br>
        <input class="form-control" id="page_blocks_attributes_0_name" name="page[blocks_attributes][0][name]" type="text" value="sections5" />
      </div>
      <div class="form-group">
        <label for="page_blocks_attributes_0_content">Содержание</label><br>
        <textarea class="form-control" id="page_blocks_attributes_0_content" name="page[blocks_attributes][0][content]"></textarea>
      </div>
      <input id="page_blocks_attributes_0_id" name="page[blocks_attributes][0][id]" type="hidden" value="1" />
    
      <a class="btn btn-default" href="#" id="addBlock">Новый блок</a>
  </div>

  <input class="btn btn-default" name="commit" type="submit" value="Сохранить" />

</form>

Answer the question

In order to leave comments, you need to log in

1 answer(s)
V
Viktor Vsk, 2014-05-04
@viktorvsk

The input itself should eventually just have a name similar to those already created (for example, page[blocks][id]), if I understood you correctly. And the id will need to be calculated with a javascript depending on how many blocks are on the page, and then feed api.rubyonrails.org/classes/ActiveRecord/NestedAtt...
That is, 2 new labels and 2 new inputs will simply be created, with name in that the same form as the one already created, but with a different ID. The rest of the work will be done by nested_attributes

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question