Rails “field-with-errors” 获取父节点
Rails “field-with-errors” get parent node
我有这样的火腿
= 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">
[...]
要解决这个问题:
有没有办法 select config/initializers/field_error_proc.rb 中的父节点?
ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
--> Nokogiri::HTML::DocumentFragment.parse(html_tag).parent returns nil.
好的,所以,我现在要忘记记忆了,但这应该会有所帮助。
ActionView::Base.field_error_proc
太糟糕了。不要使用它。我这样说是因为对于不明白它应该做什么的人来说,这是极其不可预测的(例如,如果你不知道它是什么,你就不会明白为什么这些 div
突然出现在你的领域周围,并弄乱你的造型)。另外,这不是你需要的。
所以,这就是你要做的。由于您使用的是 HAML/Slim,因此您无法有条件地添加单个 class。因此,您必须将整个内容封装在一个 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
字段关联的任何验证错误。如果有,它 returns 为真,因此我们创建一个 div 并使用适当的 class 作为响应。
希望对您有所帮助!
如果要
的父节点
<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>"
通常,如果我们知道我们想要一个特定的 class,我们可以使用 shorthand 来定位使用它的节点:
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 ")]
# })
当我们想要使用多个 classes 时,这会崩溃:
doc.at('.form-group form-md-line-input')
# => nil
但是我上面使用 [class="..."]
的形式可以工作。
我有这样的火腿
= 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">
[...]
要解决这个问题: 有没有办法 select config/initializers/field_error_proc.rb 中的父节点?
ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
--> Nokogiri::HTML::DocumentFragment.parse(html_tag).parent returns nil.
好的,所以,我现在要忘记记忆了,但这应该会有所帮助。
ActionView::Base.field_error_proc
太糟糕了。不要使用它。我这样说是因为对于不明白它应该做什么的人来说,这是极其不可预测的(例如,如果你不知道它是什么,你就不会明白为什么这些 div
突然出现在你的领域周围,并弄乱你的造型)。另外,这不是你需要的。
所以,这就是你要做的。由于您使用的是 HAML/Slim,因此您无法有条件地添加单个 class。因此,您必须将整个内容封装在一个 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
字段关联的任何验证错误。如果有,它 returns 为真,因此我们创建一个 div 并使用适当的 class 作为响应。
希望对您有所帮助!
如果要
的父节点<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>"
通常,如果我们知道我们想要一个特定的 class,我们可以使用 shorthand 来定位使用它的节点:
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 ")]
# })
当我们想要使用多个 classes 时,这会崩溃:
doc.at('.form-group form-md-line-input')
# => nil
但是我上面使用 [class="..."]
的形式可以工作。