Ruby on rails Rails-ActionView::Base.field\u error\u proc是否向上移动DOM树?
是否仍然可以从传入的html_标记元素进入DOM树Ruby on rails Rails-ActionView::Base.field\u error\u proc是否向上移动DOM树?,ruby-on-rails,ruby,parsing,dom,actionview,Ruby On Rails,Ruby,Parsing,Dom,Actionview,是否仍然可以从传入的html_标记元素进入DOM树 ActionView::Base.field_error_proc = Proc.new do |html_tag, instance| # implementation end 我是否可以实现这个方法来向上移动DOM树并在父div上放置一个类 例如: <div class="email"> <label for="user_email">Email Address</label> <in
ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
# implementation
end
我是否可以实现这个方法来向上移动DOM树并在父div上放置一个类
例如:
<div class="email">
<label for="user_email">Email Address</label>
<input id="user_email" name="user[email]" size="30" type="text" value="">
</div>
仅供参考:我的问题的简短回答是,无法通过field\u error\u proc方法访问DOM的其他部分。这是因为这些方法实际上不是在构建DOM,而是将一组字符串压缩在一起。有关一些可能的解决方法的信息,请阅读下面的解决方案。您有两个选项,我可以从脑海中想到: 重写ActionView::Base.field\u error\u proc 在一种情况下,我重写了ActionView::Base.field\u error\u proc(上面有一个rails强制转换)。使用一点nokogiri,我改变了程序,将错误消息添加到input/textarea元素的data error属性,而不是将它们包装在error div中。然后a编写了一点javascript,使用jquery将所有输入及其标签包装到document ready上。如果存在与input/textarea关联的错误信息,则会将其传输到包装器div 我知道这个解决方案依赖于javascript,可能有,也可能没有一个优雅的回退,但在我的情况下,它工作得很好,因为它是一个web应用程序,而不是一个公开访问的网站。在那种情况下,我觉得需要javascript没问题
# place me inside your base controller class
ActionView::Base.field_error_proc = Proc.new do |html_tag, object|
html = Nokogiri::HTML::DocumentFragment.parse(html_tag)
html = html.at_css("input") || html.at_css("textarea")
unless html.nil?
css_class = html['class'] || ""
html['class'] = css_class.split.push("error").join(' ')
html['data-error'] = object.error_message.join(". ")
html_tag = html.to_s.html_safe
end
html_tag
end
编写自己的ActionView::Helpers::FormBuilder
通过重写text_field方法,使其始终返回包装的输入,也可以获得或多或少相同的效果。然后,使用object变量访问errors散列,并将任何需要的错误信息添加到包装器中。这个方法不需要javascript,而且工作得很好,但最后我还是喜欢第一种方法,因为我发现它更灵活。然而,如果我在一个可公开访问的站点上工作,我会使用这种方法
另外,仅供参考,我发现覆盖复选框和单选按钮方法非常方便,因此它们总是返回带有相关标签的输入。使用自定义FormBuilder可以做很多有趣的事情
# place me inside your projects lib folder
class PrettyFormBuilder < ActionView::Helpers::FormBuilder
def check_box(field, label_text, options = {})
checkbox = super(field, options)
checkbox += label(field, label_text)
@template.content_tag(:div, checkbox, :class => "wrapper")
end
end
要使用form builder,请在form_for method call中指定它,或在应用程序助手中放置以下内容:
# application helper
module ApplicationHelper
ActionView::Base.default_form_builder = PrettyFormBuilder
end
通常情况下,我的解决方案最终会使用每个解决方案的某些组合来实现所需的结果。您是否考虑过构建一个帮助器来构建整个
(包括内容)?我认为您没有所需的DOM访问权限,但我不了解HAML。谢谢。我想这就是我必须走的路线。要回答您关于HAML的问题,不,当涉及到Rails表单生成器时,您没有任何额外的DOM访问方式。谢谢Brettish。我认为你的建议几乎是最好的选择。我同意定制的表单生成器非常强大。
ActionView::Base.field_error_proc = Proc.new do |html_tag, object|
html_tag # return the html tag unmodified and unwrapped
end
# application helper
module ApplicationHelper
ActionView::Base.default_form_builder = PrettyFormBuilder
end