폼 유효성 검증 오류 메시지 각 입력부 하단에 표시하기

  • 루비 버전 : 2.5.0
  • 레일스 버전 : 5.2.0.beta2

일반적으로 유효한 데이터만 입력하기 위한 조치로 모델 클래스에 특정 필드 속성에 대한 유효성 검증을 지정한다.

class Post < ActiveRecord
  validates :title, presence: true
end

title 속성 항목에 대해서 필수항목으로 유효성 검증을 지정했다.

이후 title 데이터 입력없이 저장할 경우 아래와 같은 유효성 오류가 폼 뷰(view)에 표시된다.

validation_errors

그러나, 매우 어글리(ugly)하다. ^^ 이 부분에 대한 html 소스코드는 다음과 같다.

<div class="field">
  <div class="field_with_errors">
    <label for="post_title">Title</label>
  </div>
  <div class="field_with_errors">
    <input class="form-control" type="text" value="" name="post[title]" id="post_title">
  </div>
</div>

field_with_errors 스타일 클래스가 결정적인 역할을 한다.

.field_with_errors {
  padding: 2px;
  background-color: red;
  display: table;
}

위에서 display: table; 를 코멘트 처리하면 다음과 같이 보이게 된다.

validation_errors_modified

이제 상단부의 오류 박스 부분의 가로 폭을 코멘트 처리하고 해당 필드의 오류 표시부를 아래와 같이 이쁘게 보이도록 수정해 보자.

#error_explanation {
  //width: 450px;
  border: 2px solid red;
  padding: 7px 7px 0;
  margin-bottom: 20px;
  background-color: #f0f0f0;

  h2 {
    text-align: left;
    font-weight: bold;
    padding: 5px 5px 5px 15px;
    font-size: 12px;
    margin: -7px -7px 0;
    background-color: #c00;
    color: #fff;
  }

  ul li {
    font-size: 12px;
    list-style: square;
  }
}

.field_with_errors {
  margin: 0;
}

.field_with_errors > * {
  border: 1px solid red;
  border-radius: 0 0 5px 5px;
}

.field_with_errors > label {
  padding: 2px 7px;
  background-color: red;
  border: 1px solid red;
  display: block;
  color: white;
  border-radius: 5px 5px 0 0;
  margin-bottom: 0;
}

validation_errors_modified_1

와우~, 항목명과 입력부 쌍이 훨씬 이쁘게 보이게 되었다. 이번에는 각 유효성 검증 오류 메시지를 해당 항목 아래에 보이도록 해 보자. 이를 위해서는 액티브레코드의 오류 객체를 이용한다.

<div class="field">
  <%= form.label :title %>
  <%= form.text_field :title, class: 'form-control' %>
  <div class="validation-error">
    <%= post.errors.messages[:title].join(' ') %>
  </div>
</div>
.field {
  margin-bottom: 1em;
  .validation-error {
    color: red;
  }
}

validation_errors_modified_2

can’t be blank” 오류 메시지가 입력부 아래에 보이게 되었다. 그러나 주어가 없는 문장이 어색하게 느껴진다. 이런 경우에는 커스텀 메시지를 로케일로 작성하면 편리하다. 디폴트 로케일이 :en 이므로 config/locales/en.yml 파일을 열고 아래와 같이 작성해 준다.

en:
  activerecord:
    errors:
      models:
        post:
          attributes:
            title:
              blank: "Title can't be blank."

validation_errors_modified_3

이제 완전한 문장의 오류 메시지 문장이 입력부 하단에 보이게 되었다. 그러나 바로 위에 보이는 오류 박스 안의 오류 메시지에는 주어가 두 번 표시된다. 이 문제는 views/posts/_form.html.erb 파일 내의 오류 표시 코드에서 기인한다.

<% if post.errors.any? %>
  <div id="error_explanation">
  <h2><%= pluralize(post.errors.count, "error") %> prohibited this post from being saved:</h2>
  <ul>
    <% post.errors.full_messages.each do "message %>
      <li><%= message %></li>
    <% end %>
  </ul>
</div>
<% end %>

full_messages 헬퍼 메소드를 messages 로 변경하고 관련 코드를 아래와 같이 수정하면 제대로 표시될 것이다.

<% if post.errors.any? %>
  <div id="error_explanation">
  <h2><%= pluralize(post.errors.count, "error") %> prohibited this post from being saved:</h2>
  <ul>
    <% post.errors.messages.each do |message| %>
      <li><%= message.flatten[1] %></li>
    <% end %>
  </ul>
</div>
<% end %>

validation_errors_modified_4

그러나 상단부의 오류 박스는 결과적으로 중복되는 부분이기 때문에 삭제하는 것이 좋을 것이다.

validation_errors_modified_5

그래, 이쁘다, 아주 이쁘다.

^_^

Posted in 미분류. Bookmark the permalink.