2015-07-27 5 views
0

У меня есть некоторый HAML как этотRails «поле-с ошибками» получить родительский узел

= 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| 

-> Nokogiri :: HTML :: DocumentFragment.parse (html_tag) .parent возвращает ноль.

+0

Не могли бы вы поделиться с вашим взглядом немного больше контекста? –

+0

Что вам нужно? – pandi

+0

На ваш взгляд, можете ли вы показать мне немного больше о самой форме, например. form_for и т. д. –

ответ

0

Итак, я сейчас уйду от памяти, но это должно помочь.

ActionView::Base.field_error_proc ужасно. Не используйте его. Я говорю это, потому что это чрезвычайно непредсказуемо для того, кто не понимает, что он должен делать (например, если вы не знали, что это такое, вы не понимаете, почему эти div s внезапно появились вокруг ваших полей и испортили ваши моделирование). Кроме того, это не то, что вам нужно.

Итак, это то, что вы делаете. Поскольку вы используете 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 
     - # ... 

The @school.errors[:postal_code].any? проверяет, есть ли какая-либо ошибка проверки, связанная с :postal_code поля. Он возвращает true, если есть, поэтому мы создаем div с соответствующими классами в ответ.

Надеюсь, что это поможет!

0

Если вы хотите, чтобы родительский узел

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

Try:

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="..."], будет работать.

+0

Хорошо, круто! Но в моем контексте я борюсь с переменной html_tag. Я не могу найти способ выбрать родительский элемент, потому что он содержит только вход. – pandi

Смежные вопросы