Customizing field_with_errors

Customizing field_with_errors

Is there a way to tell Rails to not create div.field_with_errors around both label and actually field, but to create div.error around them both?
E.g. snippet from my view with the form (written in HAML)
= form_for @user do |f|
%div.clearfix
= f.label :name
%div.input
= f.text_field :name

I want in the case of error the root div to be div.clearfix.error and avoid that field_with_errors. Can I do so?
As another option, can I make formtastic to create Bootstrap-styled elements, w/o formtastic’s css and html classes, but with bootstrap’s ones. Can I make something with error fields in the case of using formtastic?

Solutions/Answers:

Solution 1:

@flowdelic’s answer seems to be the simplest fix. However, the names are incorrect.
This may be due to the Rails/Bootstrap version, but this works for me.

/* Rails scaffold style compatibility */
#error_explanation {
  @extend .alert;
  @extend .alert-error;
  @extend .alert-block; /* optional */
}

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

Solution 2:

if anyone uses LESS:

Related:  X-Editable and Bootstrap 4

in bootstrap_and_overrides.css.less you can add:

#error_explanation {
  .alert();
  .alert-error();
  .alert-block();
}

.field_with_errors {
  .control-group.error();
}

which is the LESS version of the shown sass example.

Solution 3:

This is what works with Bootstrap 3, when using the https://github.com/anjlab/bootstrap-rails gem.

.field_with_errors {
  @include form-control-validation($state-danger-text, $state-danger-text, $state-danger-bg);
}

Solution 4:

Here’s what I did with bootstrap 3.0.3 and rails 4.0.2:

/* Rails scaffold style compatibility */
#error_explanation {
  @extend .alert;
  @extend .alert-danger;
  width: inherit;
}

.field_with_errors {
  @extend .has-error;
  display: inherit;
  padding: inherit;
  background-color: inherit;
}

Solution 5:

If you are using SASS with Twitter Bootstrap, you can use the @extend directive to apply the Twitter Bootstrap styles to the Rails generated CSS classes. (Search GitHub, there are several Bootstrap/SASS ports available.)

For example:

@import "bootstrap";

/* Rails scaffold style compatibility */
.errorExplanation {
  @extend .alert-message;
  @extend .block-message;
  @extend .error;
}

.fieldWithErrors {
  // pulled from div.clearfix.error
  @include formFieldState(#b94a48, #ee5f5b, lighten(#ee5f5b, 30%));
}

Note that the Twitter Bootstrap style for ‘error’ is attached to a div.clearfix selector, which prevents us from simply doing this:

.fieldWithErrors {
  @extend .error;
}

So, instead, I copied/pasted the code from Bootstrap’s definition for div.clearfix.error into my .fieldWithErrors selector.

Related:  Bootstrap columns float issue. DIVS need to be same height

Solution 6:

Create config/initializers/field_with_errors.rb with:

ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
  "<div class=\"error\">#{html_tag}</div>".html_safe
end

This will swap .field-with-errors for .error.

However, the biggest problem I’ve found with the “Rails-way” is that it wraps the element with a new div instead of simply adding the class to the element itself. I prefer this:

ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
  parts = html_tag.split('>', 2)
  parts[0] += ' class="field_with_errors">'
  (parts[0] + parts[1]).html_safe
end

References