我在嵌套表单上关注this railscast以创建类似的应用程序。
在Ryan的应用程序中,他的结构如下:
因此,用户可以创建调查并添加/删除问题,以及可以添加/删除的相应答案。
我试图以不同的方式做到这一点。我有:
对于我的应用程序,在用户创建问题后,用户可以创建答案(就像Ryan的应用程序一样)。但每个答案旁边都有一个选择框,默认为“答案”,另一个为“评论”。我试图获得与Ryan应用程序基本相同的功能,但有两个表:评论表和答案表。
我的代码模仿了railscast,除了我的answer_fields部分看起来像:
<fieldset>
<%= f.label :content, "Answer" %>
<%= f.select :switch_answer_table options_for_select(["Answer", "Comment"]), class: "change-type" %>
<%= f.text_field :content %>
<%= f.check_box :_destroy %>
<%= f.label :_destroy, "remove" %>
</fieldset>
我有一个如下所示的comment_fields部分:
<fieldset>
<%= f.label :content, "Comment" %>
<%= f.select :switch_answer_table options_for_select(["Comment", "Answer"]), class: "change-type" %>
<%= f.text_field :comment_content %>
... (leaving out some stuff) ...
<%= f.check_box :_destroy %>
<%= f.label :_destroy, "remove" %>
</fieldset>
我的问题.rb模型如下:
class Question < ActiveRecord::Base
belongs_to :survey
has_many :answers
has_many :comments
accepts_nested_attributes_for :answers, allow_destroy: true
accepts_nested_attributes_for :comments, allow_destroy: true
end
我一直在努力,我被困住了。到目前为止,我的jQuery看起来只是这样:
jQuery ->
$('form').on 'click', '.remove_fields', (event) ->
$(this).prev('input[type=hidden]').val('1')
$(this).closest('fieldset').hide()
event.preventDefault()
$('form').on 'click', '.add_fields', (event) ->
time = new Date().getTime()
regexp = new RegExp($(this).data('id'), 'g')
$(this).before($(this).data('fields').replace(regexp, time))
event.preventDefault()
$('form').on 'change', '.change-type', (event) ->
# Confused on how to change partials
基本上,我需要一种方法来改变,选择答案/评论的部分内容。
答案 0 :(得分:3)
alejandro babio是对的。渲染两个部分。给其中一个显示样式:none,然后在你的coffescipt onchange处理程序中切换类。如果用户开始输入答案然后切换到评论,您还需要清除与新隐藏字段相关联的字段,否则在提交时您可以同时提交评论和答案。
答案 1 :(得分:2)
我没有对此进行过测试,但也许你想使用dependent-fields-rails。根据选择框的状态,您可以显示注释框或答案框。
github页面上给出的示例(使用简单表单,但您可以将其应用于form_for):
= simple_form_for(@filing) do
= f.input :registration_office, collection: ['habm', 'dpma']
.js-dependent-fields[data-select-id='filing_registration_office' data-option-value='habm']
= f.input :language, collection: ['english', 'german']
然后我猜你使用fields_for来满足你的has_many关系,例如:
f.select :switch_answer_table, collection: ['answer', 'comment']
.js-dependent-fields[data-select-id='question_switch_answer_table' data-option-value='answer']
f.fields_for :answers do |abuilder|
...
.js-dependent-fields[data-select-id='question_switch_answer_table' data-option-value='comment']
f.fields_for :comments do |cbuilder|
...
再一次,没有经过测试和最好的猜测,但它有望推动你走向正确的方向。
答案 2 :(得分:2)
首先,您必须使用表单呈现两个部分(answer_fields和comments_fields)。
在comments_partial上将<fieldset>
替换为<fieldset style="display:none">
使用coffeescript更改部分内容的可见性:
$('form').on 'change', '.change-type', (event) ->
$('.change-type').each ->
$(@).closest('fieldset').each ->
if $(@).is(':visible')
$(@).find('input').val('') # reset all filels to empty values
$(@).toggle()
我可以做到这一点。
我只清除输入字段,但必须有所有这些字段以防止保存隐藏元素(如hraynaud所说)
答案 3 :(得分:2)
部分字段由link_to_add_fields辅助方法生成为数据属性。然后js获取数据对象并呈现它。请考虑以下内容(这是未经测试但应该是一个很好的指南):
_form.html.erb
<select id="response_type_select_field">
<option value="comment">Comment</option>
<option value="answer">Answer</option>
</select>
<%= link_to_add_reply_fields "Add Reply", f, :answers, :comments %>
surveys_helper.rb
module SurveysHelper
def link_to_add_reply_fields(name, f, association_1, association_2)
object_1 = f.object.send(association_1).klass.new
object_1_id = object_1.object_id
object_1_fields = f.fields_for(association_1, object_1, child_index: object_1_id) do |builder|
render(association_1.to_s.singularize + "_fields", f: builder)
end
object_2 = f.object.send(association_2).klass.new
object_2_id = object_2.object_id
object_2_fields = f.fields_for(association_2, object_2, child_index: object_2_id) do |builder|
render(association_2.to_s.singularize + "_fields", f: builder)
end
link_to(name, '#', class: "add_reply_fields", data: {id_1: object_1_id, id_2: object_2_id, object_1_fields: object_1_fields.gsub("\n", ""), object_2_fields: object_2_fields.gsub("\n", "")})
end
end
咖啡脚本:
jQuery ->
$('form').on 'click', '.add_reply_fields', (event) ->
time = new Date().getTime()
reply_type = $("#response_type_select_field option:selected").val()
if reply_type is 'answer'
data_attribute = 'object_1_fields'
regexp = new RegExp($(this).data('id_1'), 'g')
else if reply_type is 'comment'
data_attribute = 'object_2_fields'
regexp = new RegExp($(this).data('id_2'), 'g')
$(this).before($(this).data(data_attribute).replace(regexp, time))
event.preventDefault()