Как изменить ошибку по умолчанию rails div "field_with_errors"

Я использую sorcery для аутентификации вместе с twitter bootstrap.

Я хотел бы создать свои сообщения об ошибках в моей форме регистрации в стиле загрузочного буфера twitter, изменив рельсы по умолчанию <div class="field_with_errors">, которые будут добавлены в DOM.

Что означает рельсы для выполнения чего-то подобного?

Я полагаю, вы могли бы добавить javascript, который манипулирует DOM, чтобы переименовать <div class="field_with_errors">, но это похоже на взломать. Кажется, должен быть способ переопределить это в рельсах, но я не могу понять, где это сделать.

Вот как загрузочный файл требует, чтобы вы пометили свою ошибку, чтобы использовать встроенные стили ошибки формы:

<div class="control-group error">
  <label class="control-label" for="inputError">Input with error</label>
  <div class="controls">
    <input type="text" id="inputError">
    <span class="help-inline">Please correct the error</span>
  </div>
</div>

Ответы

Ответ 1

Из приведенной выше ссылки, если вы поместите следующее внутри class Application < Rails::Application из config/application.rb

config.action_view.field_error_proc = Proc.new { |html_tag, instance| 
  "<div class=\"field_with_errors control-group error\">#{html_tag}</div>".html_safe
}

У ваших тегов ввода будет красный маркер вокруг них всякий раз, когда проверка не выполняется

Ответ 2

Для Bootstrap 3.2 вы можете использовать sth. (добавьте nokogiri gem к вашему Gemfile):

ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
  html = %(<div class="field_with_errors">#{html_tag}</div>).html_safe
  # add nokogiri gem to Gemfile

  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 = %(<div class="control-group has-error">#{e}</div>).html_safe
    elsif form_fields.include? e.node_name
      if instance.error_message.kind_of?(Array)
        html = %(<div class="control-group has-error">#{html_tag}<span class="help-block">&nbsp;#{instance.error_message.uniq.join(', ')}</span></div>).html_safe
      else
        html = %(<div class="control-group has-error">#{html_tag}<span class="help-block">&nbsp;#{instance.error_message}</span></div>).html_safe
      end
    end
  end
  html
end

Поместите этот код внутри файла config/initializers/field_error_proc.rb (создайте его, если он не существует)

Это немного измененный код из: Переопределение ActionView:: Base.field_error_proc в Rails

Ответ 3

Обратите внимание, что если вы используете SimpleForm, принятый ответ на использование Proc в application.rb не будет работать. Вместо этого вы должны отредактировать инициализатор simple_form. Например, используя Bootstrap 3.2:

config.wrappers :default, class: :input,
  hint_class: :field_with_hint, error_class: :'has-error' do |b|
  [...]
  b.use :hint,  wrap_with: { tag: :span, class: :'text-warning' }
  b.use :error, wrap_with: { tag: :span, class: :'text-danger' }
end

Ответ 4

Twitter Bootstrap 3.3.6 на Rails 5, это идет в инициализаторе customize_error.rb и работает для меня:

ActionView::Base.field_error_proc = proc { |html_tag, _instance| "<div class=\"has-error\">#{html_tag}</div>".html_safe }

Ответ 5

Я хотел отключить ошибки только для флажков, поэтому я сделал это:

ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
  doc = Nokogiri::HTML::Document.parse(html_tag)
  if doc.xpath("//*[@type='checkbox']").any?
    html_tag
  else
    "<div class=\"field_with_errors\">#{html_tag}</div>".html_safe
  end
end