开发者

Rails 3: "field-with-errors" wrapper changes the page appearance. How to avoid this?

Email field:

<label for="job_client_email">Email: </label> 
<input type="email" name="job[client_email]" id="job_client_email">

looks like this开发者_JAVA百科:

Rails 3: "field-with-errors" wrapper changes the page appearance. How to avoid this?

But, if the email validation fails, it becomes:

<div class="field_with_errors">
  <label for="job_client_email">Email: </label>
</div> 
<div class="field_with_errors">
  <input type="email" value="wrong email" name="job[client_email]" id="job_client_email">
</div>

which looks like this:

Rails 3: "field-with-errors" wrapper changes the page appearance. How to avoid this?

How could I avoid this appearance change ?


You should override ActionView::Base.field_error_proc. It's currently defined as this within ActionView::Base:

 @@field_error_proc = Proc.new{ |html_tag, instance| 
   "<div class=\"field_with_errors\">#{html_tag}</div>".html_safe
 }

You can override it by putting this in your application's class inside config/application.rb:

config.action_view.field_error_proc = Proc.new { |html_tag, instance| 
  html_tag
}

Restart rails server for this change to take effect.


The visual difference you are seeing is happening because the div element is a block element. Add this style to your CSS file to make it behave like an inline element:

.field_with_errors { display: inline; }


I currently use this solution, placed in an initializer:

ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
  class_attr_index = html_tag.index 'class="'

  if class_attr_index
    html_tag.insert class_attr_index+7, 'error '
  else
    html_tag.insert html_tag.index('>'), ' class="error"'
  end
end

This allows me to merely add a class name to the appropriate tag, without creating additional elements.


The extra code is being added by ActionView::Base.field_error_proc. If you're not using field_with_errors to style your form, you can override it in application.rb:

config.action_view.field_error_proc = Proc.new { |html_tag, instance| html_tag.html_safe }

Alternatively, you can change it to something that suits your UI:

config.action_view.field_error_proc = Proc.new { |html_tag, instance| "<span class='field_with_errors'>#{html_tag}</span>".html_safe }


I am working with Rails 5 and Materialize-Sass and I am getting some issues with the default behavior from Rails to treat failed field validations as in the image below and it was because of the extra div added to the input fields where validation failed.

Rails 3: "field-with-errors" wrapper changes the page appearance. How to avoid this?

Working with @Phobetron answer and modifying Hugo Demiglio's answer too. I made some adjustments to those blocks of code and I get something working well in the following cases:

  • If both input and label has their own class attribute anywhere
    • <input type="my-field" class="control">
    • <label class="active" for="...">My field</label>
  • If the input or label tags does not have a class attribute
    • <input type="my-field">
    • <label for="...">My field</label>
  • if the label tag has another tag inside with the class attribute
    • <label for="..."><i class="icon-name"></i>My field</label>

In all those cases the error class will be added to the existing classes in the class attribute if exist or it will be created if it is not present in the label or input tags.

ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
    class_attr_index = html_tag.index('class="')
    first_tag_end_index = html_tag.index('>')

    # Just to inspect variables in the console
    puts '
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜