改变形式多个部分

时间:2014-09-29 17:24:46

标签: javascript jquery ruby-on-rails ruby

我在嵌套表单上关注this railscast以创建类似的应用程序。

在Ryan的应用程序中,他的结构如下:

  1. 调查---> 2.问题---> 3.答案
  2. 因此,用户可以创建调查并添加/删除问题,以及可以添加/删除的相应答案。

    我试图以不同的方式做到这一点。我有:

    1. 调查---> 2.问题---> 3.答案或评论
    2. 对于我的应用程序,在用户创建问题后,用户可以创建答案(就像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
      

      基本上,我需要一种方法来改变,选择答案/评论的部分内容。

4 个答案:

答案 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获取数据对象并呈现它。请考虑以下内容(这是未经测试但应该是一个很好的指南):

  1. 最简单的方法是分开&#39;添加答案&#39;和&#39;添加评论&#39;链接与单独的帮助方法,或
  2. 允许用户在单击要添加的链接之前选择“应答”或“注释”,并将每个不同的部分作为不同的数据属性。 e.g。
  3. _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()