Search code examples
javascriptruby-on-railsarrayssimple-form

Rails Simple form array text input


I am using SimpleForm to build my form.

Having a model with two arrays of decimals, weights[] and repetitions[], I used this tutorial to make an input form for each number in these arrays seperately.

My problem is i don't know how to add/remove fields from the form with javascript. The author of the tutorial didn't put any code "because it’s rather trivial task". Where and how do i need to put javascript to perform these tasks?


Solution

  • Well unlike adding nested records, where you need to query rails to create a new associated object, this really is just about using javascript to add another input. I would probably use a help, because it will make your view cleaner. So you have to create a helper that constructs your input field, call to that helper in your view, use a few lines of javascript to put the data from the helper onto the page where you want it.

    The helper

    module ApplicationHelper
        def link_to_add_weights(name)
        link_to name, '#', class: "add_weight_fields", :"data-field" => "<input class='text optional' type='text'  name='yourmodelname[weights][]' id='yourmodelname_'>"
      end
    end
    

    so what this does is takes a single argument, the name you want in the link and sets the input field as a data attribute on the link that is to be generated.

    The javascript

    $(document).ready(function(){
      $(".add_weight_fields").click(function(){
        $("#weights").append($(this).data("field"));
      });
    });
    

    The helper is generating a link with the class of .add_weight_fields so you want to trigger your javascript when that link is clicked. Once that happens, you simply want to append the data from the data-field attribute, in this example I'm using the css idd of weights.

    The view

    <%= simple_form_for(@yourmodelname) do |f| %>
      <%= f.input :repetitions, as: :array %>
      <div id="weights">
        <%= f.input :weights, as: :array %>
        <%= link_to_add_weights "Add New Weight" %>
      </div>
      <div class="actions">
        <%= f.submit %>
      </div>
    <% end %>
    

    Then you'd do the same fore repetitions. Create a new helper, create a new js method (or you could make it DRY and use the same method for both with a little conditional), and add some identifying css to the view for the js to find along with another link.