Rails“field-with-errors”获取父节点

时间:2015-07-27 23:48:22

标签: ruby-on-rails ruby nokogiri

我有一些这样的haml

= form_for [:admin, @school] do |f|
  [...]
  = f.fields_for :address do |a|
    [...]
    .col-md-3
      .form-group.form-md-line-input.form-md-floating-label
        = a.text_field :postal_code, id: 'form_3', class: 'form-control'
        %label{:for => "form_3"} Postleitzahl

渲染到

<div class="col-md-3">
  <div class="form-group form-md-line-input form-md-floating-label">
    <input id="form_3" class="form-control" type="text" value="" name="school[address_attributes][postal_code]">
    <label for="form_3">Postleitzahl</label>
  </div>
</div>

当出现错误时,代码应该像

[...]
<div class="form-group form-md-line-input form-md-floating-label has-error">
[...]

解决这个问题: 有没有办法在config / initializers / field_error_proc.rb中选择父节点?

ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|

- &GT; Nokogiri :: HTML :: DocumentFragment.parse(html_tag).parent返回nil。

2 个答案:

答案 0 :(得分:0)

好的,所以,我现在正在记忆,但这应该会有所帮助。

ActionView::Base.field_error_proc太可怕了。不要使用它。我这样说是因为对于那些不了解它应该做什么的人来说这是非常不可预测的(例如,如果你不知道它是什么,你就不会理解为什么这些div突然出现在你的田地周围,并弄乱你的造型)。另外,它不是你需要的。

所以,这就是你要做的。由于您使用的是HAML / Slim,因此无法有条件地添加单个类。因此,您必须将整个事件封装在if语句中,这很好。您可以使用#errors检查错误:

.col-md-3
  - if @school.errors[:postal_code].any?
    .form-group.form-md-line-input.form-md-floating-label.has-error
      - # ...
   - else
    .form-group.form-md-line-input.form-md-floating-label
       - # ...

@school.errors[:postal_code].any?检查是否存在与:postal_code字段相关的任何验证错误。如果有,则返回true,因此我们在响应中创建一个具有适当类的div。

希望有所帮助!

答案 1 :(得分:0)

如果您想要

的父节点
<div class="form-group form-md-line-input form-md-floating-label has-error">

尝试:

require 'nokogiri'

doc = Nokogiri::HTML::DocumentFragment.parse(<<EOT)
<div class="col-md-3">
  <div class="form-group form-md-line-input form-md-floating-label">
    <input id="form_3" class="form-control" type="text" value="" name="school[address_attributes][postal_code]">
    <label for="form_3">Postleitzahl</label>
  </div>
</div>
EOT

div = doc.at('[class="form-group form-md-line-input form-md-floating-label"]') 
# => #<Nokogiri::XML::Element:0x3ff0e0c14d80 name="div" attributes=[#<Nokogiri::XML::Attr:0x3ff0e0c14ac4 name="class" value="form-group form-md-line-input form-md-floating-label">] children=[#<Nokogiri::XML::Text:0x3ff0e0c141dc "\n    ">, #<Nokogiri::XML::Element:0x3ff0e0c14060 name="input" attributes=[#<Nokogiri::XML::Attr:0x3ff0e0c1422c name="id" value="form_3">, #<Nokogiri::XML::Attr:0x3ff0e0c14560 name="class" value="form-control">, #<Nokogiri::XML::Attr:0x3ff0e0c14740 name="type" value="text">, #<Nokogiri::XML::Attr:0x3ff0e0c147b8 name="value">, #<Nokogiri::XML::Attr:0x3ff0e0c148d0 name="name" value="school[address_attributes][postal_code]">]>, #<Nokogiri::XML::Text:0x3ff0e0c054e8 "\n    ">, #<Nokogiri::XML::Element:0x3ff0e0c053d0 name="label" attributes=[#<Nokogiri::XML::Attr:0x3ff0e0c052f4 name="for" value="form_3">] children=[#<Nokogiri::XML::Text:0x3ff0e0c04b74 "Postleitzahl">]>, #<Nokogiri::XML::Text:0x3ff0e0c0487c "\n  ">]>

div.parent.to_html 
# => "<div class=\"col-md-3\">\n  <div class=\"form-group form-md-line-input form-md-floating-label\">\n    <input id=\"form_3\" class=\"form-control\" type=\"text\" value=\"\" name=\"school[address_attributes][postal_code]\">\n    <label for=\"form_3\">Postleitzahl</label>\n  </div>\n</div>"

通常,如果我们知道我们想要一个特定的类,我们可以用速记来定位使用它的节点:

doc.at('.form-group') 
# => #(Element:0x3fec6acbc8d4 {
#      name = "div",
#      attributes = [
#        #(Attr:0x3fec6acbc0dc {
#          name = "class",
#          value = "form-group form-md-line-input form-md-floating-label"
#          })],
#      children = [
#        #(Text "\n    "),
#        #(Element:0x3fec6aca83ac {
#          name = "input",
#          attributes = [
#            #(Attr:0x3fec6accdea4 { name = "id", value = "form_3" }),
#            #(Attr:0x3fec6accde90 { name = "class", value = "form-control" }),
#            #(Attr:0x3fec6accde7c { name = "type", value = "text" }),
#            #(Attr:0x3fec6accde54 { name = "value", value = "" }),
#            #(Attr:0x3fec6accde2c {
#              name = "name",
#              value = "school[address_attributes][postal_code]"
#              })]
#          }),
#        #(Text "\n    "),
#        #(Element:0x3fec6acdce04 {
#          name = "label",
#          attributes = [
#            #(Attr:0x3fec6acdc9cc { name = "for", value = "form_3" })],
#          children = [ #(Text "Postleitzahl")]
#          }),
#        #(Text "\n  ")]
#      })

当我们想要使用多个类时会崩溃:

doc.at('.form-group form-md-line-input') 
# => nil

但我上面使用[class="..."]使用的表单可以使用。