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