Skip to content

Instantly share code, notes, and snippets.

@matsales28
Created April 12, 2023 14:57
Show Gist options
  • Save matsales28/d820a0f1ac8a70cd137518edc2e0ae49 to your computer and use it in GitHub Desktop.
Save matsales28/d820a0f1ac8a70cd137518edc2e0ae49 to your computer and use it in GitHub Desktop.
This is a gist for creating nested dynamic forms with JS
## This is the helper method used to create the button to add multiple records
def link_to_add_new_record(name, f, association, **html_options)
new_object = f.object.send(association).klass.new
id = new_object.object_id
fields = f.fields_for(association, new_object, child_index: id) do |builder|
render(association.to_s.singularize, builder: builder)
end
link_to(name, '#', class: html_options[:class], id: "add-new-record", data: {id: id, fields: fields.gsub("\n", "")})
end
# We can use it like that
<%= link_to_add_new_question('Add Question', f, :questions, class: "proui-button rounded mt-h") %>
# And this is the JS part
class QuestionnaireForm {
constructor() {
this.addNewQuestionButtonEventListener()
}
addNewQuestionButtonEventListener = () => {
const addNewQuestionButton = document.getElementById('add-new-record');
addNewQuestionButton.addEventListener('click', this.addNewQuestion, { passive: true })
}
addNewQuestion = ({target}) => {
const uniqueId = new Date().getTime();
const regexp = new RegExp(target.getAttribute('data-id'), 'g');
document.querySelector('#question-container').insertAdjacentHTML('beforeend', target.getAttribute('data-fields').replace(regexp, uniqueId));
event.preventDefault();
}
}
const questionnaireForm = new QuestionnaireForm();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment