Skip to content

Instantly share code, notes, and snippets.

@bogdanconstantinescu
Forked from t2/application.rb
Created May 9, 2012 15:26
Show Gist options
  • Star 14 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save bogdanconstantinescu/2645498 to your computer and use it in GitHub Desktop.
Save bogdanconstantinescu/2645498 to your computer and use it in GitHub Desktop.
Formatting Rails form elements for Twitter Bootstrap error validation
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 error">#{e}</div>).html_safe
elsif form_fields.include? e.node_name
if instance.error_message.kind_of?(Array)
html = %(<div class="control-group error">#{html_tag}<span class="help-inline">&nbsp;#{instance.error_message.join(',')}</span></div>).html_safe
else
html = %(<div class="control-group error">#{html_tag}<span class="help-inline">&nbsp;#{instance.error_message}</span></div>).html_safe
end
end
end
html
end
// Place all the styles related to the YourController controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
form .clearfix:before, form .clearfix:after {
display: inline;
}
@t2
Copy link

t2 commented May 9, 2012

Nice!

@amnesia7
Copy link

I don't think this code is quite right. It seems to wrap the label and input elements in div.control-group tags but the the label+input are already within a div.control-group tag so it breaks styling on the page.

I think the control-group part needs removing and the .error class should be applied by going up the DOM from the label (because that has div.control-group as its parent) and use add_class to add the .error class to that div.

Something like the following but it doesn't work. I need someone with some knowledge of nokogiri to correct it (I only started using it an hour ago):

  elements.each do |e|
    if e.node_name.eql? 'label'
      html = %(#{e.parent.add_class('error')}).html_safe
    elsif form_fields.include? e.node_name
      if instance.error_message.kind_of?(Array)
        html = %(#{html_tag}<span class="help-inline">&nbsp;#{instance.error_message.join(',')}</span>).html_safe
      else
        html = %(#{html_tag}<span class="help-inline">&nbsp;#{instance.error_message}</span>).html_safe
      end
    end
  end
  html

@tomwang1013
Copy link

This solution is not perfect:

  1. the left label is not in error color
  2. after adding a "control-group", the whole form gets larger

The best solution is jquery, justing add "error" class to the grandfather div, but it is not easy.

@krthi
Copy link

krthi commented Jul 19, 2020

Any solution for adding a class in grandfather div?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment