Submit
    list as parameter array in Rails 4 form, adding params values to params hash using javascript

后端 未结 2 943
后悔当初
后悔当初 2021-01-07 11:57

I have a Rails 4 form that builds a list of parts using AJAX on the form page. Once the list of parts is built in the

    I want to submit the list as an
相关标签:
2条回答
  • 2021-01-07 12:37

    I was overthinking this and found a much easier answer. It has been a long time since I've worked on this so I've had to go back over my work to refresh my memory.

    Basically I had the Javascript that builds inserts the default parts and any parts added as just a list of checkboxes with their boxes already checked. That way if the user decides they don't need one of the default parts, or want to remove a part they can just uncheck the box and it doesn't get submitted with the form. The empty checkbox lists start out in form shown above like this:

         Default Parts:<br>
            <div id="default_parts_list" class="checkbox inline">
    
            </div>
              <br>
         Other Parts:<br>
            <div id="parts_expended" class="checkbox inline">
    
            </div>
       <br>
       <br>
    

    when the dropdown for the type of service is changed on the form it fires the javascript shown in my question above. This gets the parts list and hands it off to this JS:

    $("#default_parts_list").empty();
    
    $("#default_parts_list").append('<%= escape_javascript(render :partial => 'get_default_parts' ) %>');
    

    which renders the _get_default_parts partial thus:

      <%= collection_check_boxes(:service, :part_ids, @parts_list, :id, :sku_name, {}, {checked: true}) do |b| %>
      <%= b.label { b.check_box + b.object.name + " " + b.object.sku} %>
      <% end %>
    

    this creates html appended to the form like this:

    <div id="default_parts_list" class="checkbox inline">
    
        <label for="service_part_ids_14">
           <input checked="checked" id="service_part_ids_14" name="service[part_ids][]" type="checkbox" value="14">Stihl/Denso Spark Plug W22mp-u 042511060272
        </label>
    
        <label for="service_part_ids_24">
            <input checked="checked" id="service_part_ids_24" name="service[part_ids][]" type="checkbox" value="24">Bar Oil - Stihl 795711145835
        </label>
    
        <label for="service_part_ids_10">
            <input checked="checked" id="service_part_ids_10" name="service[part_ids][]" type="checkbox" value="10">Stihl MS660/066 Air Filter 795711478179
        </label>
    
        <input name="service[part_ids][]" type="hidden" value="">
    </div>
    

    So they are just plain old checkboxes that end up being submitted with the form and end up in the params hash like this:

    Parameters: {"utf8"=>"✓", "authenticity_token"=>"IHXcV0H8NnySxGIBXi8ZA=", 
      "service"=>{"tool_id"=>"121", "name"=>"refresher", "due_date"=>"2014-12-27", 
      "completed"=>"2014-12-27", "service_type_id"=>"2", 
      "part_ids"=>["14", "24", "10", ""], "note"=>""}, "parts_used"=>"", 
      "commit"=>"Create Service", "tool_id"=>"121"}
    

    When this same form is used to edit and exiting service it has to use a different form rather than the form partial above. The edit form looks like this:

    <h1>Editing service for <%=" #{@tool.category.name.singularize} / #{@tool.serial}" %></h1>
    
    <%= form_for ([@tool, @service]) do |f| %>
    <% if @service.errors.any? %>
        <div id="error_explanation">
          <h2><%= pluralize(@service.errors.count, "error") %> prohibited this service from being saved:</h2>
    
          <ul>
            <% @service.errors.full_messages.each do |msg| %>
                <li><%= msg %></li>
            <% end %>
          </ul>
        </div>
    <% end %>
    
    <div class="row">
    
      <div class="span4 offset1">
    
        <div class="form-inline">
          <%= f.hidden_field :tool_id , :value=>params[:tool_id] %>
          <%= f.label :name %><br>
          <%= f.text_field :name %>
        </div>
        <br>
        <br>
        <div class="form-inline">
          <%= f.label :due_date %><br>
          <%= f.text_field :due_date, 'data-behaviour' => 'datepicker' %>
        </div>
        <br>
        <br>
        <div class="form-inline">
          <%= f.label :completed %><br>
          <%= f.text_field :completed, 'data-behaviour' => 'datepicker' %>
        </div>
        <br>
        <div class="field">
          <%= f.label 'Service Type:' %>
          <%= f.select :service_type_id, ServiceType.all.collect{|s| [s.name, s.id] }, {include_blank: false} %>
        </div>
        <br>
    
      </div>
    
      <div class="span7">
        <div class="form-inline">
          <div class="part_list_element">
            Parts Used <br>
            <%= text_field_tag :parts_used %>
          </div>
        </div>
        <br>
        <strong class="alert-danger">Any parts that get unchecked here will be returned to inventory</strong><br>
        <b>Parts Used:</b> <br>
        <div id="parts_used_list" class="checkbox inline">
    
              <%= f.collection_check_boxes :part_ids, @service.parts, :id, :name %>
    
    
        </div>
        <br>
        <b>Other Parts:</b> <br>
        <div id="parts_expended" class="checkbox inline">
    
        </div>
        <br>
        <br>
    
        <div class="form-inline">
          <%= f.label :note %><br>
          <%= f.text_area :note %>
        </div>
        <br>
        <br>
        <div class="actions">
          <%= f.submit  %>
        </div>
    
      </div>
    </div>
    
    <% end %>
    

    I hope this helps anyone doing something similar. You can view the full source app on github: EquipDB on github.com

    0 讨论(0)
  • 2021-01-07 12:40

    You have to remember Rails doesn't care about HTMl, so when you mention you want to send "<ul> list as params", it's got nothing to do with the <ul>, but how you're porting those items into Rails


    Routes

    The most robust way to do this is to use a route, and pass the params through JS to it:

    #config/routes.rb
    post "your_route(/:items)", to: "controller#action"
    
    #app/views/parts/index.html.erb
     <ul id="serv_parts_list">
         <li id="1">1</li>
         <li id="2">2</li>
         <li id="3">3</li> 
     </ul>
     <%= link_to "Submit", class: "submit_link" %>
    
    #app/assets/application.js.erb
    $("a.submit_link").on("click", function() { 
        var data = jQuery('#serv_parts_list li').map(function(){
             return 'id[]=' + this.id.match(/(\d+)$/)[1]
        }).get()
    
        $.ajax ({
           url: "your_route",
           data: data.join('&')
           success: function(data) {
               //success
           },
           error: function(data) {
               //error
           }
        });
    });
    
    0 讨论(0)
提交回复
热议问题