【问题标题】:Submit <ul> list as parameter array in Rails 4 form, adding params values to params hash using javascript提交 <ul> 列表作为 Rails 4 表单中的参数数组,使用 javascript 将参数值添加到参数哈希
【发布时间】:2023-03-12 00:20:01
【问题描述】:

我有一个 Rails 4 表单,它在表单页面上使用 AJAX 构建部件列表。在&lt;ul&gt; 中构建零件列表后,我想将该列表作为参数散列中参数中的值数组提交。

我的表格:

<%= form_for ([@tool, @service]),:html => { :onSubmit => 'getParts' } 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>

     Default Parts:
     <ul id="serv_parts_list">

     </ul>
   <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 %>

当用户从选择列表中选择默认服务时,此 javascript 会触发:

$('#service_service_type_id').change(function() {
    var id = this.value;
    $.ajax
    ({
        url:'/get_default_parts',
        type:"POST",
        data: {
          service_type: {
            id:  id
          }
        }
    });
  });

这会根据选择从数据库中获取零件列表。然后它通过 JS 返回一个数组,然后将其附加到空的 Default Parts 列表中:

  Default Parts:
     <ul id="serv_parts_list">

     </ul>

变成:

 <ul id="serv_parts_list">
     <li id="042511060272">042511060272 - Stihl/Denso Spark Plug W22mp-u<a class="service_parts">&lt;-Remove</a></li>
     <li id="795711145835">795711145835 - Bar Oil - Stihl<a class="service_parts">&lt;-Remove</a></li>
     <li id="795711478179">795711478179 - Stihl MS660/066 Air Filter<a class="service_parts">&lt;-Remove</a></li>
 </ul>

在我的 application.js 我有:

$(document).ready(function(){
  $("#commit").click(function() {
    $("#expended_parts").val(('#serv_parts_list').text());
  });
});

但这并没有做任何事情。我一直在试图弄清楚如何将&lt;ul&gt; 中的&lt;li&gt; 元素放入一个数组并作为参数传递。但是当前的参数哈希看起来像:

Parameters: {"utf8"=>"✓",   "authenticity_token"=>"s/....=", "service"=> 
 {"tool_id"=>"113", "name"=>"test without hash", "due_date"=>"", "completed"=>"", 
  "service_type_id"=>"2", "note"=>""}, "parts_used"=>"", "commit"=>"Create Service"}  

由于部件列表可以在页面加载后多次更新,无论是从 AJAX 调用获取附加到 &lt;li&gt; 的默认部件列表,我认为这必须绑定到 @987654331 @ 事件。任何帮助表示赞赏。

【问题讨论】:

  • 您介意分享您对此问题的解决方案吗?我现在也在经历同样的事情。
  • @seong-Lee 请参阅下面的答案。

标签: javascript jquery ruby-on-rails ruby


【解决方案1】:

我想多了,找到了一个更简单的答案。自从我从事这项工作以来已经有很长时间了,所以我不得不回顾我的工作以刷新我的记忆。

基本上,我构建的 Javascript 插入了默认部分和任何添加的部分,它们只是一个复选框列表,并且它们的框已经被选中。这样,如果用户决定他们不需要默认部分之一,或者想要删除一个部分,他们可以取消选中该框并且它不会与表单一起提交。空的复选框列表以上面显示的形式开始,如下所示:

     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>

当服务类型的下拉菜单在表单上发生更改时,它会触发上面我的问题中显示的 javascript。这将获取零件清单并将其交给这个 JS:

$("#default_parts_list").empty();

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

从而呈现 _get_default_parts 部分:

  <%= 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 %>

这会创建附加到表单的 html,如下所示:

<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>

所以它们只是普通的旧复选框,最终与表单一起提交并最终出现在 params 哈希中,如下所示:

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"}

当使用相同的表单来编辑和退出服务时,它必须使用不同的表单,而不是上面的部分表单。编辑表单如下所示:

<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 %>

我希望这可以帮助任何做类似事情的人。您可以在 github 上查看完整的源应用程序: EquipDB on github.com

【讨论】:

  • @seong-lee 如果您还有任何问题,请告诉我。
  • 感谢您花时间分享您的解决方案!
【解决方案2】:

你必须记住 Rails 并不关心 HTMl,所以当你提到你想发送“&lt;ul&gt; 列表作为参数”时,它与 &lt;ul&gt; 无关,而是你如何移植这些项目进入 Rails


路线

最稳健的方法是使用路由,并通过 JS 将参数传递给它:

#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
       }
    });
});

【讨论】:

  • 这会在一个参数哈希中提交我所有的表单元素(上面列出的页面上的其他元素)吗?我还想我可以为每个列表项使用隐藏的表单值。我不确定我是否理解你的解释。我知道 Rails 不关心 html,但表单结构是提交嵌套参数哈希的内容,所以我只是想适应它。
  • 我知道&lt;ul&gt; 与参数无关。我的问题是我是否可以在提交时使用 JS 将数组变量设置为数组中的值,并返回我所有的其他表单参数。我没有通过 JS 传递我的所有参数,而是将 JS 更新设置为构建一个复选框集合。这样,用户可以将它们全部保留为默认部件列表,或者取消选中他们不想使用的部件。谢谢你的努力。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-01
  • 2011-09-18
  • 2017-09-12
  • 2023-04-08
  • 2016-05-22
相关资源
最近更新 更多