0

For example we have this Model fields: -name. -surname. -birthdate. -address.

How to be able to duplicate form in one page to fill data for everyone and create multiple Records at once.

<form>
    <input name />
    <input surname />
    <input birthdate />
    <input address />
</form>

<button>Additional+</button>

<button>Submit</button>

Logic is when user click on Additional+ button, there rendering second form. Every click render another bonus form.

<form>
    <input name />
    <input surname />
    <input birthdate />
    <input address />
</form>

<form>
    <input name />
    <input surname />
    <input birthdate />
    <input address />
</form>

<form>
    <input name />
    <input surname />
    <input birthdate />
    <input address />
</form>

<button>Additional+</button>

<button>Submit</button>

When user click on Submit whole data need to be sent to my Controller.

  • This requires javascript so it depends on your JS setup. [Related 1](https://stackoverflow.com/questions/72422571/how-can-i-create-a-button-which-adds-fields-to-a-rails-form) [Related 2](https://stackoverflow.com/questions/71713303/rails-7-dynamic-nested-forms-with-hotwire-turbo-frames) – Arctodus May 18 '23 at 14:05
  • There's not a feature of Rails that does this, what you're asking for is a significant amount of code and really you should look for a tutorial online that walks through this process. Voted to close. – smathy May 18 '23 at 15:05

1 Answers1

1

You must only have a single form, even to create multiple persons. So your form will look like this:

<%= form_for :person, url: person_index_path, method: 'post', id: 'form' do |f| %>
  <div id='new_persons'>
    <input name="persons[][first_name]">
  </div>
<%= f.submit 'Save names' %>
<% end %>
<button id="add">Add a person</button>

Note the parens [] in the field name for the text input field... this is the key to being able to submit multiple persons as an array.

Next define a template that will be used to add additional persons:

<template id='tmpl'>
  <input name="persons[][first_name]">
</template>

Next you'll need to be able to add additional fields for additional persons, this is done by javascript:

<script type='text/javascript'>
  const add_button = document.getElementById('add')
  const container = document.getElementById('new_persons')
  const person = document.getElementById('tmpl')

  add_field = ()=>{
    const new_person = person.content.cloneNode(true)
    container.appendChild(new_person)
  }

  add_button.addEventListener("click", add_field);
</script>

So every time you click the 'Add a person' button, another first_name field will be added to the form.

When you click 'Save names', you'll submit the form with a parameters hash that has an array of the first_names, like this:

"persons"=>[{"first_name"=>"John"}, {"first_name"=>"Paul"}, {"first_name"=>"George"}, {"first_name"=>"Ringo"}]

And in the controller you can create a new person for each of the members of the received array!

Les Nightingill
  • 5,662
  • 1
  • 29
  • 32