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_formgemを使用して可能かもしれませんが、可能であれば自分のhtmlを使用したいと思います。


編集

セクションに入れるe['class'] = 'foo'と、クラスがラベルに適用されるので、の親タグを見つけてクラスを適用するif e.node_name.eql? 'label'だけでよいと思いますが、ラベルからへのxpathの取得方法がわかりません。その親; ドットやスラッシュなどの組み合わせは機能しないようですが、xpathは私の強みではありません。e.errordiv.control-group

4

3 に答える 3

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がDOMツリーを上に移動しますか?

だから、これが私がしたことです:

  1. ラベルと入力からデフォルトのRailsエラー処理を削除します
  2. エラーのある各ラベルとフォームフィールドをspan.field_with_errorsでラップします
  3. 次に、.field_with_errorsは、SASSを使用して.control-group.errorcssを拡張します。

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 に答える
0

エラーのあるフィールドの横にエラーメッセージを表示する必要がない場合は、以下を追加するだけですassets/stylesheets/application.css.scss

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