【问题标题】:How do I send dynamic paramters with a nested form using jquery and rails 3?如何使用 jquery 和 rails 3 以嵌套形式发送动态参数?
【发布时间】:2013-03-17 22:44:46
【问题描述】:

我是 Rails 新手,我正在尝试使用 jquery 实现我自己的动态字段。我已经将字段添加到表单中,但是我的参数没有按照我想要的方式发送。这是我的 jQuery:

$('form').on('click', '#add_ingredient', function(){
    count = 1;
    field = $('#ingredient_list li').first()
        .clone()
            .find('input')
                .val('')
                    .end()
                        .find('input')
                            .prop({id: 'entry_ingredients_attributes_' + count + '_name', name: 'entry[ingredients_attributes][' + count +'][name]'  })
                                .end();
    $('#ingredient_list').append(field);
    count += 1;
})

这允许我添加多个列表项,并且它们的 id 和名称会递增,因此它们是唯一的。

我已正确设置模型以使用 Accepts_nested_attributes_for,我正在创建一个烘焙日志,其中包含模型条目、成分和关联条目成分。我的问题如下:

当我提交表单时,即使我添加了多个字段,我也只会发送一种成分,只有最后一个会被提交。这是我提交包含超过 1 个成分的表单时我的参数的输出:

"ingredients_attributes"=>{"0"=>{"name"=>"Flour", "_destroy"=>"false"}, "1"=>{"name"=>""}}}}

如果您有兴趣了解它是如何创建的,这也是我的表单:

  <div id="ingredients">
      <%= f.fields_for :ingredients, @entry.ingredients.build do |builder| %>
      <%= render 'ingredient_fields', :f => builder %>
      <% end %>
  </div>
  <div id='add_ingredient'>Add Ingredient</div>
  <div class="actions">
    <%= f.submit %>

#_ingredient_fields
<ul id="ingredient_list">
    <li>
      <%= f.label :name %>
      <%= f.text_field :name %>
      <%= f.hidden_field :_destroy %>
      <%= link_to "Remove", "#", :class => "remove_fields" %>
    </li>
</ul>

谁能指出我正确的方向?


解决方案

按照 Zaid Crouch 在下面答案中的建议,结果证明我的选择器没有做正确的事情。我的 JS 现在是这样的:

$('form').on('click', '#add_ingredient', function(){
    count = $('#ingredient_list li').length;
    field = $('#ingredient_list li').first()
        .clone()
            .find('input')
                .val('')
                    .end()
                        .find('input :first')
                            .prop({id: 'entry_ingredients_attributes_' + count + '_name', name: 'entry[ingredients_attributes][' + count +'][name]'  })
                                .end()
                                    .find('input :last')
                                        .prop({id: 'entry_ingredients_attributes_' + count + '__destroy', name: 'entry[ingredients_attributes][' + count +'][_destroy]', value: 'false'  })
                                            .end();
    $('#ingredient_list').append(field);
})

如果有人可以推荐一种更好的方法来选择那些我正在更改属性的元素,我将不胜感激。

【问题讨论】:

    标签: jquery ruby-on-rails parameters nested-forms


    【解决方案1】:

    如果您只收到提交的最后一个值,这可能是一个很好的提示,表明您有重复的 names 输入。您应该能够通过检查 .js 添加的 html(使用 firebug 或 webkit 检查器)来验证是否发生了这种情况。

    查看您的函数,您正在初始化函数中的count 变量;一旦函数返回,它就会超出范围,因此每次调用函数时都会使用count = 1。您应该可以通过更改来解决此问题

    count = 1;
    

    count = $('#ingredient_list li').length;
    

    (你也可以去掉函数末尾的增量,因为它什么都不做)。

    您还需要确保更新 _destroy 隐藏字段的名称和 ID。

    【讨论】:

    • 啊,很好,虽然现在我得到了超过 1 个,这很好,但它们仍然是空值。这是我现在的结果以及您修改后的计数"ingredients_attributes"=&gt;{"0"=&gt;{"name"=&gt;"Flour", "_destroy"=&gt;"false"}, "1"=&gt;{"name"=&gt;""}, "2"=&gt;{"name"=&gt;""}}}}
    • 这似乎有点奇怪。您检查过 js 添加的 HTML 是否符合您的预期?
    • 谢谢!事实证明,我的 JS 工作不正常, .find('input') 正在选择所有输入,所以正如你所说的那样,隐藏字段被弄乱了。我修复了这个问题,现在将它们全部提交 :)。非常感谢 Zaid,我已经更新了我的问题以包含解决方案代码
    • 实际上,如果您可以推荐一种更好的方法来选择没有 css 选择器的那些元素,我无法使用 next() 或 first() 来做到这一点
    • 您总是可以将特定的 CSS 类添加到隐藏字段和文本字段,例如。 &lt;%= f.text_field :name, class: "name-field" %&gt; 然后使用这些类名执行find(),这样会不那么脆弱。我怀疑这将是一个比尝试严格通过 next() 之类的遍历方法更好的选择,尽管它的性能可能稍差(但我怀疑这是否真的是一个问题)。
    猜你喜欢
    • 2014-08-14
    • 1970-01-01
    • 1970-01-01
    • 2013-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多