Article:
Hiển thị thông báo lỗi validation theo đúng ý mình
856
ngocdaothanh.myopenid.com 172Updated over 4 years ago |
Trong Rails, để hiển thị lỗi validation, chỉ cần dùng error_messages_for một phát là xong. Tuy thế không người dùng sành điệu nào lại muốn nhìn thấy các thông báo lỗi validation được hiển thị xấu xí và khó hiểu như ở dưới. Do đó lập trình viên chắc chắn không thể dùng nguyên xi error_messages_for mà phải override lại chút đỉnh.

CSS
Trước hết, để hiện ra được màu sắc tạm được như trên, cần dùng CSS như sau:
.fieldWithErrors {
padding: 1px;
background-color: red;
}
#errorExplanation {
border: 1px solid red;
padding: 5px;
padding-bottom: 5px;
margin-bottom: 5px;
background-color: #f0f0f0;
}
#errorExplanation h2 {
text-align: left;
font-weight: bold;
padding: 5px 5px 5px 15px;
font-size: 12px;
margin: -5px;
background-color: #c00;
color: #fff;
}
#errorExplanation p {
color: #333;
margin-bottom: 0;
padding: 0px;
}
Override error_messages_for
Từ mã nguồn của error_messsages_for, ta chế lại thành my_error_messages_for có tính năng sau:
- Không hiển thị số lỗi làm quách gì để người dùng mất công tò mò đếm xem có đúng không
- Không hiển thị "Có vấn đề với các mục sau:" cho khỏi vướng mắt, khi bị báo lỗi tâm lí chung của người dùng là bực mình, đừng để họ mất công đọc những câu vô tích sự
- Ứng với mỗi attribute, chỉ hiển thị một thông báo lỗi
- Thứ tự của lỗi (= của attribute) theo đúng ý ta, chứ không được nhảy lung tung địa

Hàm này nên để trong application_helper.rb:
# @param attributes Array of attributes to be displayed in order
def error_messages_for(object, attributes)
return '' if object.nil? or object.errors.count == 0
html = {}
[:id, :class].each do |key|
html[key] = 'errorExplanation'
end
error_messages = []
attributes = object.attribute_names if attributes.nil?
attributes.unshift(:base)
attributes.each do |a|
msgs = object.errors.on(a)
next if msgs.blank?
msg = msgs.is_a?(String) ? msgs : msgs[0]
error_messages << content_tag(:li, msg)
end
contents = ''
contents << content_tag(:h2, _('Error'))
contents << content_tag(:ul, error_messages)
content_tag(:div, contents, html)
end
1 2 
Rails
172