Rails问题accepts_nested_attributes_for
我有这个问题:
我的网络应用程序有一个表单,用户可以在其中自定义他们的个人资料。 在每个配置文件中可以指定许多技能,我希望允许用户按一个按钮(添加新技能)以便指定他们想要的任意数量的技能。 这是控制器代码:
accepts_nested_attributes_for :skills, :allow_destroy=>true, :reject_if => lambda {|a| a[:name].blank?}
这是表单(只是带有嵌套属性技能的部分):
<%= f.fields_for :skills do |builder|%>
<div class="field">
<%= builder.label :skill %>
<%= builder.text_field :name%>
<%= builder.hidden_field :_destroy %>
<%= link_to 'remove', '#', :onclick=>'removeField()'%>
</div>
<%end%>
这个表单工作完美,显示了用户的每项技能,它允许编辑等。现在的问题是,我想添加一个链接到“添加新技能”,这样一个javascript函数可以更改表单并添加新技能输入字段,我真的不知道如何操作,主要是因为嵌套属性在中具有特定的id和名称我不明白的形式:
<input id="profile_skills_attributes_0_name" name="profile[skills_attributes][0][name]" size="30" type="text" value="Mathematicansszz" />
它还添加了另一个隐藏的输入字段包含技能的 id(无法预测技能是否未创建),导致无法从 HTML 静态页面创建新技能?
<input id="profile_skills_attributes_0_id" name="profile[skills_attributes][0][id]" type="hidden" value="3" />
有什么想法或解决方法吗?谢谢
I have this problem:
My web application has a form where the users can customize their profile.
In each profile can be specified many skills and I want to allow the users to press one button (add new skill) in order to specify as many skills as they want.
So this is the controller code:
accepts_nested_attributes_for :skills, :allow_destroy=>true, :reject_if => lambda {|a| a[:name].blank?}
This is the form (just the part with the nested attribute skill):
<%= f.fields_for :skills do |builder|%>
<div class="field">
<%= builder.label :skill %>
<%= builder.text_field :name%>
<%= builder.hidden_field :_destroy %>
<%= link_to 'remove', '#', :onclick=>'removeField()'%>
</div>
<%end%>
This form work perfectly and shows each skill of the user, it allows editing etc. The problem now, is that I want to add a link to "add new skill" so a javascript function that change the form and add new skill input field, I really have no idea to how to act, mainly because the nested attributes have specific id and name in the form that I don't understand:
<input id="profile_skills_attributes_0_name" name="profile[skills_attributes][0][name]" size="30" type="text" value="Mathematicansszz" />
It also add another hidden input field with the id of the skill (impossible to predict if the skill is not created), make impossible to create new skill from an HTML static pages?
<input id="profile_skills_attributes_0_id" name="profile[skills_attributes][0][id]" type="hidden" value="3" />
Any idea or workaround ? Thank you
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我编写了一个 gem,它可以使动态处理嵌套表单变得更容易:cocoon。
gem 可以与标准的 Rails formhelpers 一起使用,也可以与 formattastic 或 simple_form 一起使用。
我还建议您检查 formtastic 或 simple_form,因为这些都是很棒的宝石,可以使表单处理更容易。但与 HAML 一样,这是个人选择。
I have written a gem that can handle that makes handling nested forms dynamically easier: cocoon.
The gem works with the standard rails formhelpers, but also with formtastic or simple_form.
I would also advise you to checkout formtastic or simple_form, as those are awesome gems to make form-handling easier. But as with HAML, that is a personal choice.
fields_for 创建一个字段数组。名称中的“0”代表数组中的索引。由于您正在创建新记录,因此您可以简单地忽略隐藏的 id 字段。
所以通过 javascript 你只需要做两件事:
1. 计算子集合现有输入的数量以获得新索引。
2. 使用新索引添加新文本字段。
使用 jQuery 使用通配符选择器(如 $('input[name$="][name]"]').length; )相对容易做到这一点。检索计数(对于新索引)。如果您有另一个带有名称字段的数组字段,您可能需要使用正则表达式选择器(通过插件)。一种更简单的方法可能是在每个技能名称输入中添加一个类,并在计数时使用该类作为选择器。
要附加新输入,请参阅:
http://api.jquery.com/append/
如果您'如果不使用 jquery,那么在其他框架中应该类似,只需稍微谷歌一下即可。
fields_for creates an array of fields. The "0" in the name represents the index in the array. Since you're creating new records you can simply ignore the hidden id field.
So via javascript you just need to do two things:
1. Count the number of existing inputs for the child collection in order to get a new index.
2. Add a new text field using the new index.
This is relatively easy to do with jQuery using a wildcard selector like $('input[name$="][name]"]').length; to retrieve a count (for the new index). If you have another field for array with name fields you may want to use a regex selector instead (via plugin). An easier way might be to just add a class to each of your skill name inputs and use that class as the selector when counting.
To append the new input see:
http://api.jquery.com/append/
If you're not using jquery, then it should be similar in other frameworks with a little googling.