我一直在问这个问题的迭代一段时间了 - 但是在SO社区的帮助下我几乎得到了它的工作。首先,谢谢!
我有一个表单来创建一个新的student_group
并使用Cocoon
gem:
<%= form_for @student_group do |f| %>
<p>
The name of this group is
<span class="field form_field"><%= f.text_field :name %></span>
and it is a/an
<span class="field dropdown"><%= f.select :type_of_group, [["select a group type", ""], "young learners class (0-6)", "primary class (7-12)", "secondary class (13-17)", "adult class (18+)", "children's sport team", "adult's sport team"] %></span>
</p>
<p>
There are
<span id="nos" class="field dropdown"><%= f.select :number_of_students, (0..60) %></span>
students in this group.
</p>
<table id="students_form_table">
<tbody>
<!-- https://stackoverflow.com/questions/11445831/how-to-submit-multiple-new-items-via-rails-3-2-mass-assignment -->
<%= f.fields_for :students, @student, child_index: @student do |builder| %>
<%= render "student_fields", :f => builder %>
<% end %>
</tbody>
</table>
<p>
<%= f.submit "Submit", :class => 'big_button round unselectable'%>
</p>
<% end %>
和'student_fields'部分:
<tr class="nested-fields">
<td id="student_name" class="field form_field"><%= f.text_field :name, placeholder: "Student name" %></td>
<td id="student_gender" class="field dropdown"><%= f.select :gender, [["select a gender", ""],'Female', 'Male', 'Transgender'] %></td>
<td id="remove_link"><%= link_to_remove_association "remove student", f %></td>
</tr>
现在问题的核心是:
我有以下.js文件,可以在表单中动态添加正确数量的学生字段:
var row_i = 0;
function emptyRow() {
row_i++;
this.obj = $("<tr></tr>");
this.obj.append('<td id="student_name" class="field form_field"><input id="student_group_students_attributes___Student:0x00000103c4ead8__name" name="student_group[students_attributes][#<Student:0x00000103c4ead8>][name]" type="text" /></td>');
this.obj.append('<td id="student_gender" class="field dropdown"><select id="student_group_students_attributes___Student:0x00000103c4ead8__gender" name="student_group[students_attributes][#<Student:0x00000103c4ead8>][gender]"><option value="">select a gender</option><option value="Female">Female</option><option value="Male">Male</option><option value="Transgender">Transgender</option></select></td>');
this.obj.append(' <td id="remove_link"><input id="student_group_students_attributes___Student:0x00000103c4ead8___destroy" name="student_group[students_attributes][#<Student:0x00000103c4ead8>][_destroy]" type="hidden" /><a href="#" class="remove_fields dynamic">remove student</a></td>')
}
function refresh(new_count) {
//how many students we have got?
console.log("New count= " + new_count);
if (new_count > 0) {
$('#students_form_table').show();
}
else {
$('#students_form_table').hide();
}
var old_count = parseInt($('tbody').children().length);
console.log("Old count= " + old_count);
//calculates difference between rows needed/rows current
var rows_difference = parseInt(new_count) - old_count;
console.log("Rows diff= " + rows_difference);
//if we have rows to add
if (rows_difference > 0) {
for (var i = 0; i < rows_difference; i++)
$('tbody').append((new emptyRow()).obj);
} else if (rows_difference < 0) //we need to remove rows ..
{
var index_start = old_count + rows_difference + 1;
console.log("Index start= " + index_start);
$('tr:gt(' + index_start + ')').remove();
row_i += rows_difference;
}
}
$(document).ready(function () {
//hide table by default
$('#students_form_table').hide();
$('#nos').change(function () {
var opt=$('#nos option:selected');
refresh(opt.text());
})
});
因此,这种形式几乎可以正常运作 - 一切都正确,并且当我选择'x'学生时,'x'学生表格的数量被建立 - 但是,因为这个 -
function emptyRow() {
row_i++;
this.obj = $("<tr></tr>");
this.obj.append('<td id="student_name" class="field form_field"><input id="student_group_students_attributes___Student:0x00000103c4ead8__name" name="student_group[students_attributes][#<Student:0x00000103c4ead8>][name]" type="text" /></td>');
this.obj.append('<td id="student_gender" class="field dropdown"><select id="student_group_students_attributes___Student:0x00000103c4ead8__gender" name="student_group[students_attributes][#<Student:0x00000103c4ead8>][gender]"><option value="">select a gender</option><option value="Female">Female</option><option value="Male">Male</option><option value="Transgender">Transgender</option></select></td>');
this.obj.append(' <td id="remove_link"><input id="student_group_students_attributes___Student:0x00000103c4ead8___destroy" name="student_group[students_attributes][#<Student:0x00000103c4ead8>][_destroy]" type="hidden" /><a href="#" class="remove_fields dynamic">remove student</a></td>')
}
...字段未正确呈现 - 因为它们不会创建新学生字段的谨慎实例。我知道问题是rails生成的html的id / name部分中的哈希,但是我不知道如何替换它以便这样做。我最接近的是试图调整coffeescript from this site,但我无法让它发挥作用。
那么如何使用jquery为模型动态生成新表单?
编辑:实际上我刚刚意识到第一个和最后一个表格会正确保存 - 也就是说,如果我添加八个学生,student1和student8将被输入数据库,但其他将不会。这只会让我更加困惑:/
编辑2 :我在this问题的上下文中找到了this jquery api,名为'serialize',我认为这可能是我需要的,但是麻烦适应它。救救我!
答案 0 :(得分:1)
知道了!
尝试了很多东西,但这最终有效:
student_groups_controller.rb #create
def create
@params = params[:student_group][:students_attributes]
@student_group = @user.student_groups.build(params[:student_group])
if @student_group.save
### RE: 'defensive coding' http://stackoverflow.com/questions/14502508/undefined-method-for-nilnilclass-when-pushing-values-to-an-array
if @params.present?
### http://stackoverflow.com/questions/11355820/rails-3-2-iterate-through-an-array
@params.each do |student|
@student_group.students.create(name:"#{student[:name]}", gender: "#{student[:gender]}")
end
end
# new subject path
redirect_to class_path(@student_group), flash: { success: "#{@student_group.name} has been added successfully" }
else
@title = "Create a new group"
flash.now[:error] = "Something's gone wrong. Please try again!"
render 'new'
end
end
_groups_form.html.rb
<table id="students_form_table">
<tbody>
<!-- http://stackoverflow.com/questions/11445831/how-to-submit-multiple-new-items-via-rails-3-2-mass-assignment -->
<%= fields_for 'student_group[students_attributes][]', @student, index: nil do |builder| %>
<%= render "student_fields", :f => builder %>
<% end %>
</tbody>
</table>
最后,student_groups.js
的相关部分:
function emptyRow() {
row_i++;
this.obj = $("<tr></tr>");
this.obj.append('<td id="student_name" class="field form_field"><input id="student_group_students_attributes__name" name="student_group[students_attributes][][name]" placeholder="Student name" size="30" type="text" /></td>');
this.obj.append('<td id="student_gender" class="field dropdown"><select id="student_group_students_attributes__gender" name="student_group[students_attributes][][gender]"><option value="">select a gender</option><option value="Female">Female</option><option value="Male">Male</option><option value="Transgender">Transgender</option></select></td>');
this.obj.append('<td id="remove_link"><input id="student_group_students_attributes___destroy" name="student_group[students_attributes][][_destroy]" type="hidden" /><a href="#" class="remove_fields dynamic">remove student</a></td>')
}