我在使用 Twitter 引导程序的 rails 应用程序中的初始值设定项中有以下内容,以便它删除 rails 在字段验证失败时应用的div.field_with_errors
,但初始化程序也会在错误的输入字段后添加帮助/验证文本:
require 'nokogiri'
ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
html = %(<div class="field_with_errors">#{html_tag}</div>).html_safe
form_fields = [
'textarea',
'input',
'select'
]
elements = Nokogiri::HTML::DocumentFragment.parse(html_tag).css("label, " + form_fields.join(', '))
elements.each do |e|
if e.node_name.eql? 'label'
html = %(#{e}).html_safe
elsif form_fields.include? e.node_name
if instance.error_message.kind_of?(Array)
html = %(#{e}<span class="help-inline"> #{instance.error_message.join(',')}</span>).html_safe
else
html = %(#{e}<span class="help-inline"> #{instance.error_message}</span>).html_safe
end
end
end
html
end
这工作正常,但我还需要为每个错误将 .error
类应用于周围的div.control-group
。
我的初始值设定项当前给出以下输出:
<div class="control-group">
<label class="control-label" for="post_message">Message</label>
<div class="controls">
<input id="post_message" name="post[message]" required="required" size="30" type="text" value="" /><span class="help-inline"> can't be blank</span>
</div>
</div>
但是我需要向我的初始值设定项添加一些东西,以便它将.error
类添加到div.control-group
中,如下所示:
<div class="control-group error">
<label class="control-label" for="post_message">Message</label>
<div class="controls">
<input id="post_message" name="post[message]" required="required" size="30" type="text" value="" /><span class="help-inline"> can't be blank</span>
</div>
</div>
该解决方案可能需要考虑到这样一个事实,即每个验证错误可能有多个标签和输入,这些标签和输入都在同一div.control-group
内(例如单选按钮/复选框/并排 2 个文本字段)。
我认为它需要某种e.at_xpath()
才能找到div.control-group
父级并向其中添加.error
类,但我不确定如何做到这一点。
谁能帮忙?
PS 这可能都可以使用 formtastic 或 simple_form gems,但如果可能的话,我宁愿只使用我自己的 html。
编辑
如果我e['class'] = 'foo'
放在if e.node_name.eql? 'label'
部分,那么它将类应用于标签,所以我想我只需要找到e
的父标签,然后对其应用一个.error
类,但我无法弄清楚从标签到其div.control-group
父级的 xpath 是什么; 没有点的组合, 斜杠或任何似乎有效的方法,但 xPath 不是我的强项。
不是最好的解决方案,但是一个有效的解决方法,因为我比rail更像HTML/js 家伙
-> 使用 jQuery 选择器 & addClasshttp://api.jquery.com/contains-selector/http://api.jquery.com/addClass/
$("div.control-group:contains('can\'t be blank')").addClass("error");
我现在已经做到了。
根据这个SO答案,这是不可能的:Rails - ActionView::Base.field_error_proc向上移动DOM树?
所以,这就是我所做的:
- 从标签和输入中删除默认的导轨错误处理
- 用span.field_with_errors包装每个错误的标签和表单字段
- 然后.field_with_errors使用 SASS 扩展 .control-group.error css
config/initializers/bootstrap.rb
require 'nokogiri'
ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
html = %(<div class="field_with_errors">#{html_tag}</div>).html_safe
form_fields = [
'textarea',
'input',
'select'
]
elements = Nokogiri::HTML::DocumentFragment.parse(html_tag).css("label, " + form_fields.join(', '))
elements.each do |e|
if e.node_name.eql? 'label'
# wrap erroneous label
html = %(<span class='field_with_errors'>#{e}</span>).html_safe
elsif form_fields.include? e.node_name
# wrap erroneous field
if instance.error_message.kind_of?(Array)
html = %(<span class='field_with_errors'>#{e}<span class="help-inline"> #{instance.error_message.join(',')}</span></span>).html_safe
else
html = %(<span class='field_with_errors'>#{e}<span class="help-inline"> #{instance.error_message}</span></span>).html_safe
end
end
end
html
end
assets/stylesheets/application.css.scss
.field_with_errors {
@extend .control-group.error;
}
希望对别人有帮助。
如果您不需要在错误字段旁边显示错误消息,那么您只需将以下内容添加到assets/stylesheets/application.css.scss
:
.field_with_errors {
@extend .control-group.error;
display: inline;
}