简体   繁体   中英

How can I make a form with a user defined number of fields? - Ruby on Rails

I'm making a ruby on rails app with a settings page where a user can enter two fields, a name and value field which will be translated upon form submit to the key and value of a hash.

The only complicated aspect is that the user needs to be able to add additional "rows" to this form. The form on the page currently looks like this:

在此处输入图像描述

So as you can see, clicking on the 'plus' icon will create another 'Conversion Action' and clicking on the 'minus' icon will remove a row from the field. The user should be able to add as many Conversion Actions as they wish.

It's pretty standard to load this hash from the database and populate the form with existing values, but I'm not satisfied with my current way of adding additional form fields to the form.

This is the code for the HTML form in use on the page:

<%= parent_form.fields_for :conversion_trackers_to_pull do |form| %>
  <div id="conversion-trackers-to-pull">
    <% section.conversion_trackers_to_pull.each_with_index do |(conversion_tracker_name, conversion_tracker_id), index| %>
      <div class="mb-2">
        <%= form.fields_for "conversion_tracker_#{index}".to_sym do |conversion_tracker| %>
          <%= conversion_tracker.label :conversion_action, "Conversion Action #{index+1}: " %>
          <%= conversion_tracker.text_field :name, value: conversion_tracker_name, placeholder: "Name" %>
          <%= conversion_tracker.text_field :id, value: conversion_tracker_id, placeholder: "ID" %>
        <% end %>
        <%= button_tag '<i class="fas fa-minus-circle"></i>'.html_safe, type: "button", class: "remove-conversion-tracker" %>
        <span class="index d-none"><%= index + 1 %></span>
      </div>
    <% end %>
  </div>
  <i class="far fa-plus-square" id="<%= "#{section_name}" %>-new-conversion-tracker"></i>
<% end %>

And this is the JQuery code being used on the plus button click event:

$('#search-new-conversion-tracker').on('click', function() {
      var index = parseFloat(($('#search-conversion-trackers-to-pull').find('.index').last().text()));
      if (!index) {
        index = 0;
      }
      $(this).prev('#conversion-trackers-to-pull').append(
       '<div class="mb-2">' +
          '<label for="_search_section_config_conversion_trackers_to_pull_conversion_tracker_' + index + '_conversion_action">Conversion Action ' + (index+1) + ': </label>&nbsp;' +
          '<input type="text" name="[search_section_config][conversion_trackers_to_pull][conversion_tracker_' + index + '][name]" id="_search_section_config_conversion_trackers_to_pull_conversion_tracker_' + index + '_name" placeholder="Name">&nbsp;' +
          '<input type="text" name="[search_section_config][conversion_trackers_to_pull][conversion_tracker_' + index + '][id]" id="_search_section_config_conversion_trackers_to_pull_conversion_tracker_' + index + '_id" placeholder="ID">&nbsp;' +
          '<button name="button" type="button" class="remove-conversion-tracker"><i class="fas fa-minus-circle"></i></button>' +
          '<span class="index d-none">' + (index + 1) + '</span>' +
       '</div>'
      );
      bindRemoveConversionTracker();
    });

So this solution does work, albeit it's very clunky. I know a rails helper would probably be doing this exact same thing under the hood, but I need to replicate a similar type of form on other pages and I feel like there should be a cleaner way than to just repeat the code I've already got.

Does anyone have experience making this kind of form in Ruby on Rails? What technique did you use? Thanks!

To replicate a similar type of form on other pages, use partials . Keep what ever you feel redundant in the partial file and use it whenever you want. For better understanding of partials follow official documentation https://guides.rubyonrails.org/layouts_and_rendering.html#using-partials

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM