I'm using sorcery for authentication along with twitter bootstrap.
I'd like to style my error messages on my signup form in the style of twitter's bootstrap by changing the default rails <div class="field_with_errors"> that gets added to the DOM.
What's the rails convention for doing something like this?
I suppose you could add some javascript that manipulates the DOM to rename <div class="field_with_errors">, but that seems like a hack. It seems like there should be a way to override this in rails, but I can't figure out where to do that.
This is how bootstrap requires you to mark up your error to use its built in form error styles:
<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>
                From the link above, if you put the following inside class Application < Rails::Application of 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
}
Your input tags will have a red marker around them whenever validation fails
Using Rails 6 with Bootstrap 4 you'll need to add the is-invalid class. Without getting too fancy I just did:
ActionView::Base.field_error_proc = proc do |html_tag, instance|
  html_tag.gsub("form-control", "form-control is-invalid").html_safe
end
                        For Bootstrap 3.2 you could use sth. like this (add nokogiri gem to your 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"> #{instance.error_message.uniq.join(', ')}</span></div>).html_safe
      else
        html = %(<div class="control-group has-error">#{html_tag}<span class="help-block"> #{instance.error_message}</span></div>).html_safe
      end
    end
  end
  html
end
Place this code inside config/initializers/field_error_proc.rb file (create one if not exists)
This is slightly modified code from: Overriding ActionView::Base.field_error_proc in Rails
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With