Thomas Baustert
2005-Oct-26 21:49 UTC
How to display error messages sorted and with index?
Hi,
by default the errors messages displayed by Rails (through helper method
error_messages_for for example) are displayed in arbitrarily order.
One of our customers wanted the error messages displayed in the order
the form
elements occured one the page. The messages and form elements must
also be
indexed. Example:
1) Name can''t be empty
2) Age can''t be empty
...
Name : [...] 1)
Street: [...]
Age : [...] 2)
...
We use the following solution and I''m interested to get feedback,
what you
think about that and if someone had a better solution.
Idea:
1) Modify the error display of the form elements by adding a comment
tag which contains the form element name (e.g. name, age).
ActionView::Base.field_error_proc = Proc.new do |html, obj|
"<div class=\"fieldWithErrors\">#{html}" +
<!-- @method_name --></div>"
end
The variable @method_name holds the actual form element name (e.g.
name, age).
Inside the view you got something like:
...
<div class="fieldWithErrors"><input type="text"
name="name"...>
<!-- name --></div>"
<div class="fieldWithErrors"><input type="text"
name="age"...>
<!-- age --></div>"
...
This code may go to config/environment.rb or a better place!? :)
2) Capture the output of the view into a string @page_content. In
case of
errors the helper method show_with_errors returns a view containing
an error
message header and the original view. Otherwise the method returns
just the
original page. We also need to provide the model, because it contains
the
error messages.
<% @page_content = capture %>
...
original code
...
<% end %>
<%= show_with_errors(@address.errors,@page_content) %>
3) In case of errros we modify @page_content (the view) inside
show_with_errors by looking up each comment tag (e.g. <!-- age -->)
inside
@page_content, inserting each found form element name of a tag
("age") into an
array A and replacing the comment tag with html code containing a
counter (1,
2, 3,...) (array index).
A = [ "name", "age", ... ]
from:
<div class="fieldWithErrors"><input type="text"
name="name" ...>
<!-- name --></div>"
<div class="fieldWithErrors"><input type="text"
name="age" ...>
<!-- age --></div>"
to:
<div class="fieldWithErrors"><input type="text"
name="name" ...>
<span class="errorIndex">1)</span></div>"
<div class="fieldWithErrors"><input type="text"
name="age" ...>
<span class="errorIndex">2)</span></div>"
4) Iterate over the array A (which contains the error in the order
the form
element occured on page) and create html code that displays the
message. Use
the message from the model
A.each do |name|
<div>...<%= name %>: <%= model.errors.on(name)
%></div>
end
5) show_with_errors returns the full page containing the error
messages and
the captured and modified page. Or in case of no error just the
orignal page.
Note, this is just a possible pragmatic solution. We use it, it works
in our case.
Any other (simpler) solutions? Any comments? :)
Thanks in advance
bye
---
Thomas Baustert
rails-bHvOKaA9pPkvyvRFVCEN17NAH6kLmebB@public.gmane.org