1

我在使用 Twitter 引导程序的 rails 应用程序中的初始化程序中有以下内容,以便它删除div.field_with_errors当字段验证失败时应用的 rails 并且初始化程序在错误的输入字段后添加帮助/验证文本:

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">&nbsp;#{instance.error_message.join(',')}</span>).html_safe
      else
        html = %(#{e}<span class="help-inline">&nbsp;#{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">&nbsp;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">&nbsp;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类应用到它,但我无法弄清楚 xpath 从标签到它的div.control-group父母;没有点、斜线或任何似乎有效的组合,但 xpath 不是我的强项。

4

3 回答 3

0

If you don't need to display the error messages next to the erroneous field then you can simply add the following to assets/stylesheets/application.css.scss:

.field_with_errors {
  @extend .control-group.error;
  display: inline;
}
于 2012-06-03T10:37:23.767 回答
0

不是最好的解决方案,而是一个有效的解决方法,因为我比 rails 更像 html/js 人

-> 使用 jQuery 选择器和 addClass http://api.jquery.com/contains-selector/ http://api.jquery.com/addClass/

$("div.control-group:contains('can\\'t be blank')").addClass("error");
于 2012-06-01T12:54:25.373 回答
0

我现在已经做到了。

根据这个 SO 答案,这是不可能的:Rails - ActionView::Base.field_error_proc move up the DOM tree?

所以,这就是我所做的:

  1. 从标签和输入中删除默认的 rails 错误处理
  2. 用 span.field_with_errors 包裹每个错误的标签和表单字段
  3. .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">&nbsp;#{instance.error_message.join(',')}</span></span>).html_safe
      else
        html = %(<span class='field_with_errors'>#{e}<span class="help-inline">&nbsp;#{instance.error_message}</span></span>).html_safe
      end
    end
  end
  html
end

assets/stylesheets/application.css.scss

.field_with_errors {
  @extend .control-group.error;
}

希望对其他人有所帮助。

于 2012-06-02T10:03:22.793 回答