【问题标题】:One form element not being rendered when validation fails验证失败时未呈现一个表单元素
【发布时间】:2016-08-17 20:17:15
【问题描述】:

我无法确定这是 simple_fields_for 问题、茧问题还是其他问题。如果我在 </div> 展示位置上犯了错误,我看不到它。

当表单首次显示时,它会呈现协议名称的输入字段。用户可以单击按钮来添加感兴趣的表单元素。这工作正常,看起来像这样:

这是用户单击每个“添加元素”按钮后的外观:

用户可以添加 0..many 每个元素。当他们点击“保存”时,一切都很好。

如果其中一个字段出现验证错误,则表单会重新呈现,但有一个异常。 “成像步骤”元素的验证错误根本不会重新显示。当验证失败时,其他元素会重新渲染并按预期突出显示。

这是一个图示示例。用户填写表格的一部分,忘记选择“序列”并且忘记输入“提示描述”的文本:

点击“保存”并验证失败后,表单重新呈现如下:

如您所见,“成像步骤”部分尚未重绘。

如果我在视图的上下文中查看参数,一切似乎都在那里。 @protocol.errors 对我来说也很合适。模型看起来也不错。

这是pastebin of the form code

这是pastebin of _step_item_fields.html.erb

这是pastebin of _tip_fields.html.erb

这是pastebin of my Gemfile

更新:

如果我像这样构建一个 step_item:

<div id="step_items">
    <%= f.simple_fields_for :step_items, @protocol.step_items.build do |si| %>
        <%= render 'step_item_fields', :f => si %>
    <%end%>
</div>

始终绘制成像步骤部分,但(显然)在验证失败时不会填充。这也混淆了让用户添加/删除 0..many Imaging Steps 的功能。

我也试过了:

<div id="step_items">
    <%= f.simple_fields_for :step_items, @protocol.step_items.build(protocol_params) do |si| %>
        <%= render 'step_item_fields', :f => si %>
    <%end%>
</div>

... 当 protocol_params 可用时的其他变体,但遇到了禁止的参数问题。

更新2:

我还尝试使用参数为 step_item 构建哈希。我可以在这里使用它:

<div id="step_items">
    <%= f.simple_fields_for :step_items, @protocol.step_items.build(some_ok_params) do |si| %>
        <%= render 'step_item_fields', :f => si %>
    <%end%>
</div>

... 但仅适用于单个 step_item。我不确定如何传递反映 0..many 功能的哈希值。此外,以这种方式构建 step_item 可以正确填充表单元素,但不包括错误突出显示样式。这是我开始想知道为什么更简单的解决方案不起作用的时候。

【问题讨论】:

    标签: ruby-on-rails forms cocoon-gem


    【解决方案1】:

    由于 StepItem 是 STI 类 Step 的子类型,我认为 StepItems 的错误检测被遗漏了。我在这里的 hack 修复并不漂亮,而且确实很脆弱。如果您有更好的方法,请发布。

    我在 _form.html.erb 中更改了这个:

    ...

    <%if params["protocol"] && params["protocol"]["step_items_attributes"].present?%>
        <%params["protocol"]["step_items_attributes"].each do |sia|%>
            <%v = sia[1]%>
            <div id="step_items">
                <%= f.simple_fields_for :step_items, @protocol.step_items.build(:orientation_id => v["orientation_id"], :sequence_id => v["sequence_id"], :note => v["note"], :id => v["id"], :protocol_id => v["protocol_id"], :institution_id => v["institution_id"] ) do |si| %>
                    <%= render 'step_item_fields', :f => si%>
                <% end %>
            </div><!-- end step_items-->
        <%end%>
    <%else%>
    

    ...

    我在 _step_item_fields.html.erb 中更改了这个:

    ...

    <div class="nested-fields">
        <div class= "form-inputs">
            <div class="row">
                <div class="col-sm-2 text-right">Imaging Step:</div>
                    <div class="col-sm-2 drop_col ">                
                        <%= f.collection_select :orientation_id, Orientation.where("institution_id=?",current_user.current_institution_id),:id,:name,  {:prompt => "Pick an Orientation", }, {class: "form-control #{"dropdown_error" if f.object.orientation_id.blank? && (f.object.sequence_id.present? || f.object.note.present?)}"}%>
                    </div>              
                    <div class="col-sm-2 drop_col ">
                        <%= f.collection_select :sequence_id, Sequence.where("institution_id=?",current_user.current_institution_id),:id,:name, {:prompt => "Pick a Sequence"}, {class: "form-control #{ "dropdown_error" if f.object.sequence_id.blank? && (f.object.orientation_id.present? || f.object.note.present?) }"}%>                              
                    </div>              
            </div>
    
            <div class="row">
                <div class="col-sm-2"></div>
                    <%= f.input :note, :wrapper_html =>{:class => 'col-sm-8'}, label: false, placeholder: 'You can put an optional note here.' , :input_html => {:size => 50}%>
                    <%= f.input :institution_id,:as => :hidden, :input_html => {:value=>current_user.current_institution_id}  %>
                    <%= f.input :id,:as => :hidden  %>
                <div class="col-sm-2">
                    <%= link_to_remove_association "Remove Imaging Step", f , :class=>"btn btn-danger btn-xs placemid",title: "Click here to delete this imaging step.", data: {toggle: "tooltip", placement: "auto", animation: true,  delay: {show: 700, hide: 100}}%>
                </div>
            </div>
        </div>
        <div class="col-sm-12"><hr></div>
    </div>
    

    ...

    我将它添加到正确的样式表中:

    .dropdown_error{
        color: red;
    }
    

    该表单现在可以正确显示 StepItem 错误,如下所示:

    【讨论】:

      猜你喜欢
      • 2016-07-21
      • 1970-01-01
      • 1970-01-01
      • 2019-11-22
      • 1970-01-01
      • 2015-09-07
      • 2013-07-02
      • 2017-08-15
      • 1970-01-01
      相关资源
      最近更新 更多