如何在字段旁边显示错误消息

30

我有一个包含输入字段、标签等的表单。如何使错误消息显示在字段旁边,而不是聚集在顶部?

我正在使用 devise 和 rails 3。

我在表单顶部有这个:

 = form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f|
- if resource.errors.any?
  #errorExplanation
    %h2
      = pluralize(resource.errors.count, "error")
      prevented this user from being saved:
    %ul
      - resource.errors.full_messages.each do |msg|
        %li
          = msg

好问题,但我认为对于UJS表单来说答案并不优雅。 - Daniel Viglione
5个回答

41

1
太好了!看起来很棒!要获取消息,我应该说 @resource.errors[:field_name].ful_messages 吗? - newbie_86
谢谢,这会在一行中给我一个错误列表吗?我正在尝试做以下操作:对于每个字段,如果该字段存在错误,则为每个错误创建一个div并在该字段下输出它,或者创建一个div,其中包含一个下面的错误列表。 - newbie_86
1
第一行必须有属性,不能为空白。第二行必须有属性,不能少于5个字符等。 - newbie_86
1
是的,它会返回一行错误。您可以通过询问 @resource.errors[:field_name].present? 来检查错误是否存在。 - fl00r
或者 @resource.errors[:field_name].any?present? 能够工作是因为 Rails 认为空数组是 blank? - Kris
显示剩余2条评论

7

只需在初始文件夹中创建一个文件。

config/initializers/inline_errors.rb

将以下代码放入其中:

ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
  unless html_tag =~ /^<label/
    %{<div class="has-error">#{html_tag}<span class="help-block">#{instance.error_message.first}</span></div>}.html_safe
  else
    %{#{html_tag}}.html_safe
  end
end

PD: Sorry for my english.


1
没有提供真正的描述来引导读者找到答案。不过这看起来非常有用。 - HermannHH
1
我放了一些文本来提供一些信息,我的英语不好,因此我之前没有写一些文本 :/ - el_quick
谢谢@el_quick。你有没有使用这个在你的表单中的例子吗?我很难弄清楚你是如何实现的。顺便说一下,我改变了我的评分。 :-) - HermannHH
我认为 field_error_proc 不是 Rails 的公共 API 的一部分,因为它没有文档记录。如果是私有的,这将是一个危险的解决方案。 - Jared Beck

5

你想把错误消息放在文本框下方,可以这样做

如下:

.row.spacer20top
  .col-sm-6.form-group
    = f.label :first_name, "*Your First Name:"
    = f.text_field :first_name, :required => true, class: "form-control"
    = f.error_message_for(:first_name)

什么是error_message_for
--> 嗯,这是一个很棒的技巧,可以做一些很酷的事情。

# Author Shiva Bhusal
# Aug 2016
# in config/initializers/modify_rails_form_builder.rb
# This will add a new method in the `f` object available in Rails forms
class ActionView::Helpers::FormBuilder
  def error_message_for(field_name)
    if self.object.errors[field_name].present?
      model_name              = self.object.class.name.downcase
      id_of_element           = "error_#{model_name}_#{field_name}"
      target_elem_id          = "#{model_name}_#{field_name}"
      class_name              = 'signup-error alert alert-danger'
      error_declaration_class = 'has-signup-error'

      "<div id=\"#{id_of_element}\" for=\"#{target_elem_id}\" class=\"#{class_name}\">"\
      "#{self.object.errors[field_name].join(', ')}"\
      "</div>"\
      "<!-- Later JavaScript to add class to the parent element -->"\
      "<script>"\
          "document.onreadystatechange = function(){"\
            "$('##{id_of_element}').parent()"\
            ".addClass('#{error_declaration_class}');"\
          "}"\
      "</script>".html_safe
    end
  rescue
    nil
  end
end

结果 enter image description here

错误后生成的标记

<div id="error_user_first_name" for="user_first_name" class="signup-error alert alert-danger">This field is required.</div>
<script>document.onreadystatechange = function(){$('#error_user_first_name').parent().addClass('has-signup-error');}</script>

相应的SCSS

  .has-signup-error{
    .signup-error{
      background: transparent;
      color: $brand-danger;
      border: none;
    }

    input, select{
      background-color: $bg-danger;
      border-color: $brand-danger;
      color: $gray-base;
      font-weight: 500;
    }

    &.checkbox{
      label{
        &:before{
          background-color: $bg-danger;
          border-color: $brand-danger;
        }
      }
    }

注意:这里使用了Bootstrap变量,不要忘记现在以及对配置文件目录中任何修改后都要重新启动服务器。

你有没有不使用html_safe的解决方案? - undefined

0

0
如果有人正在寻找一种在Rails 6中显示特定字段错误消息的方法:
a = Post.new
a.save # => false
a.errors.full_messages_for(:title)
["Title can't be blank"]

a.errors.full_messages_for(:title).join(', ')
"Title can't be blank, Title too short"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接