Rails params没有将GUI上的动态行值提取到控制器

时间:2018-01-07 13:36:56

标签: javascript ruby-on-rails

我正在尝试将值从GUI传递到rails控制器,其中我的GUI由表组成,其中行由Javascript动态生成。我需要两个静态行,其余的应该根据客户的需求生成。

问题是只有静态行中的值以参数形式发送,动态生成的行值不会被发送。

前端代码:

<%= render 'shared/page_title', title: "Order Details" %>
<br>
<table id="tabledata">
    <thead>
        <th>Item Name</th>
        <th>Quantity</th>
        <th>Unit Price</th>
        <th>Tax</th>
        <th>Discount</th>
        <th>Item Total Price</th>
    </thead>
    <tbody id="input"></tbody>
    <tbody id="template">
          <%= form_for @order do |f| %>
          <%= f.label :ordertype %>
          <%= f.text_field :ordertype %> &nbsp; &nbsp; &nbsp; &nbsp;

          <%= f.label :totalprice %>
          <%= f.text_field :totalprice %> &nbsp;&nbsp;&nbsp;&nbsp; 

          <%= f.label :paymentmethod %>
          <%= f.text_field :paymentmethod %>

          <br>

        <tr>
           <td><input name="order[order_placed][][itemname]" type="text" /></td>
            <td><input name="order[order_placed][][quantity]" type="text" /></td>
            <td><input name="order[order_placed][][unitprice]" type="text" /></td>
            <td><input name="order[order_placed][][tax]" type="text" /></td>
            <td><input name="order[order_placed][][discount]" type="text" /></td>
            <td><input name="order[order_placed][][itemtotalprice]" type="text" /></td>

        </tr>
        <tr>
           <td><input name="order[order_placed][][itemname]" type="text" /></td>
            <td><input name="order[order_placed][][quantity]" type="text" /></td>
            <td><input name="order[order_placed][][unitprice]" type="text" /></td>
            <td><input name="order[order_placed][][tax]" type="text" /></td>
            <td><input name="order[order_placed][][discount]" type="text" /></td>
            <td><input name="order[order_placed][][itemtotalprice]" type="text" /></td>

        </tr>

 </tbody>
</table>
<label id="ActionAddRow">Add Row</label>
<%= f.submit %>


 <% end %>

的JavaScript

$(function () {
    var addInputRow = function () {
       var tr = document.createElement("tr");
             function callback(attribname){
                 nameAttributitemname = 
                       "order[order_placed][][" + attribname + "]";

                //create input for itemname, set it's type, id and name attribute
                var inputitemname = document.createElement("INPUT");
                inputitemname.setAttribute("type", "text");
                inputitemname.setAttribute("name", nameAttributitemname);
                //and append it to <td> element and then <tr> 
                var td = document.createElement("td");
                td.appendChild(inputitemname);  
                tr.appendChild(td);
            }

            callback("itemname");
            callback("quantity");
            callback("unitprice");
            callback("tax");
            callback("discount");
            callback("itemtotalprice");

             document.getElementById("template").appendChild(tr);
  }; 

    var addAll = function (){
         addInputRow();
    };

    $('#ActionAddRow').on('click', addAll);
});

服务器端:

Started POST "/orders" for 127.0.0.1 at 2018-01-07 12:57:14 +0530
Processing by OrdersController#create as HTML
  Parameters: {"order"=>{"ordertype"=>"", "totalprice"=>"", "paymentmethod"=>"", "order_placed"=>[{"itemname"=>"11", "quantity"=>"", "unitprice"=>"", "tax"=>"", "discount"=>"", "itemtotalprice"=>""}, {"itemname"=>"22", "quantity"=>"", "unitprice"=>"", "tax"=>"", "discount"=>"", "itemtotalprice"=>""}]}, "utf8"=>"Γ£ô", "authenticity_token"=>"/YfKgSt/lgDgC2L1Wa0fDdBjY+zTfEBcblp1rB/St89jsmU52pDnbTCwACyy+qiuZhxyVil63FMlOiq2YEUBhA==", "addresses"=>[{"line1"=>"", "line2"=>"", "city"=>""}, {"line1"=>"", "line2"=>"", "city"=>""}], "commit"=>"Create Order"}
  Customer Load (1.0ms)  SELECT  "customers".* FROM "customers" ORDER BY "customers"."id" ASC LIMIT $1  [["LIMIT", 1]]
   (0.0ms)  BEGIN
  SQL (2.0ms)  INSERT INTO "orders" ("ordertype", "order_placed", "paymentmethod", "created_at", "updated_at", "customer_id") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id"  [["ordertype", ""], ["order_placed", "\"---\\n- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\\n  itemname: '11'\\n  quantity: ''\\n  unitprice: ''\\n  tax: ''\\n  discount: ''\\n  itemtotalprice: ''\\n- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\\n  itemname: '22'\\n  quantity: ''\\n  unitprice: ''\\n  tax: ''\\n  discount: ''\\n  itemtotalprice: ''\\n\""], ["paymentmethod", ""], ["created_at", "2018-01-07 07:27:14.631269"], ["updated_at", "2018-01-07 07:27:14.631269"], ["customer_id", 1]]
   (1.0ms)  COMMIT

GUI截图传递三行。

enter image description here

1 个答案:

答案 0 :(得分:0)

这是因为当调用document.getElementById("template").appendChild(tr);时,所有新的tr和包含的输入都会附加在<tbody id="template"></tbody>下,导致生成的HTML结构变成这样:

<tbody id="template">
  <form ...>
    <!-- Static rendered rows -->
    <tr>
      ...
      <input ... />
      ...
    </tr>
  </form>
  <!-- Dynamically generated rows -->
  <tr>
    ...
    <input ... />
    ...
  </tr>
</tbody>

合理的行为,<form>标记之外的输入不会与提交的表单一起发送。您可以在<%= form_for @order do |f| %>之外移动生成<form>标记的<tbody id="template">行,以便动态添加的输入也位于表单内。

更多需要注意的事项:

您似乎错误地写了一对不匹配的<%= form_for @order do |f| %><% end %>标记,您将开始标记放在tbody内,结束标记放在tbody之外:< / p>

...
<tbody>
  <form>
    ...
</tbody>
  </form>
...

这是无效的HTML,浏览器可能会认为您的意思是:

...
<tbody>
  <form>
    ...
  </form>
</tbody>
...

这会导致一些意想不到的行为。开始标记和结束标记应始终与HTML文档处于同一级别。

以及其他一些问题:

  1. 对于语义正确性,您应该考虑使用button而不是label作为ActionAddRow按钮,表示用户可以点击该内容。
  2. 标签和输入应放在tbodytable之外,因为它不是表格的一部分。
  3. 以下是.html.erb代码的结构良好的示例:

    <%= render 'shared/page_title', title: "Order Details" %>
    
    <br>
    
    <%= form_for @order do |f| %>
        <%= f.label :ordertype %>
        <%= f.text_field :ordertype %>
    
        &nbsp;&nbsp;&nbsp;&nbsp;
    
        <%= f.label :totalprice %>
        <%= f.text_field :totalprice %>
    
        &nbsp;&nbsp;&nbsp;&nbsp;
    
        <%= f.label :paymentmethod %>
        <%= f.text_field :paymentmethod %>
    
        <br>
    
        <table id="tabledata">
            <thead>
                <th>Item Name</th>
                <th>Quantity</th>
                <th>Unit Price</th>
                <th>Tax</th>
                <th>Discount</th>
                <th>Item Total Price</th>
            </thead>
            <tbody id="input"></tbody>
            <tbody id="template">
                <tr>
                    <td><input name="order[order_placed][][itemname]" type="text" /></td>
                    <td><input name="order[order_placed][][quantity]" type="text" /></td>
                    <td><input name="order[order_placed][][unitprice]" type="text" /></td>
                    <td><input name="order[order_placed][][tax]" type="text" /></td>
                    <td><input name="order[order_placed][][discount]" type="text" /></td>
                    <td><input name="order[order_placed][][itemtotalprice]" type="text" /></td>
                </tr>
    
                <tr>
                    <td><input name="order[order_placed][][itemname]" type="text" /></td>
                    <td><input name="order[order_placed][][quantity]" type="text" /></td>
                    <td><input name="order[order_placed][][unitprice]" type="text" /></td>
                    <td><input name="order[order_placed][][tax]" type="text" /></td>
                    <td><input name="order[order_placed][][discount]" type="text" /></td>
                    <td><input name="order[order_placed][][itemtotalprice]" type="text" /></td>
                </tr>
            </tbody>
        </table>
    
        <button id="ActionAddRow">Add Row</button>
    
        <%= f.submit %>
    <% end %>