Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

* added semantic_errors method with specs

* added basic CSS for semantic_errors and info in README
  • Loading branch information...
commit c4ebcefdbf82d6cecfe75973d97c8a72307a1ead 1 parent e06139b
Wojciech Wnętrzak authored justinfrench committed
View
11 README.textile
@@ -406,6 +406,17 @@ For more flexible forms; Formtastic find translations using a bottom-up approach
Values for @labels@/@hints@/@actions@ are can take values: @String@ (explicit value), @Symbol@ (i18n-lookup-key relative to the current "type", e.g. actions:), @true@ (force I18n lookup), @false@ (force no I18n lookup). Titles (legends) can only take: @String@ and @Symbol@ - true/false have no meaning.
+h2. Semantic errors
+
+You can show errors on base (by default) and any other attribute just passing it name to semantic_errors method:
+
+<pre>
+ <% semantic_form_for @post do |form| %>
+ <%= form.semantic_errors :state %>
+ <% end %>
+</pre>
+
+
h2. ValidationReflection plugin
If you have the "ValidationReflection":http://github.com/redinger/validation_reflection plugin installed, you won't have to specify the @:required@ option (it checks the validations on the model instead).
View
6 generators/formtastic/templates/formtastic.css
@@ -22,6 +22,12 @@ form.formtastic input, form.formtastic textarea, form.formtastic select { font-s
form.formtastic legend { color:#000; }
+/* SEMANTIC ERRORS
+--------------------------------------------------------------------------------------------------*/
+form.formtastic ul.errors { color:#cc0000; margin:0.5em 0 1.5em 25%; list-style:square; }
+form.formtastic ul.errors li { padding:0; border:none; display:list-item; }
+
+
/* FIELDSETS & LISTS
--------------------------------------------------------------------------------------------------*/
form.formtastic fieldset { }
View
26 lib/formtastic.rb
@@ -415,6 +415,32 @@ def inline_errors_for(method, options = nil) #:nodoc:
end
alias :errors_on :inline_errors_for
+ # Generates error messages for given method names and for base.
+ # You can pass a hash with html options that will be added to ul tag
+ #
+ # == Examples
+ #
+ # f.semantic_errors # This will show only errors on base
+ # f.semantic_errors :state # This will show errors on base and state
+ # f.semantic_errors :state, :class => "awesome" # errors will be rendered in ul.awesome
+ #
+ def semantic_errors(*args)
+ html_options = args.extract_options!
+ full_errors = args.inject([]) do |array, method|
+ attribute = localized_string(method, method.to_sym, :label) || humanized_attribute_name(method)
+ errors = Array(@object.errors[method.to_sym]).to_sentence
+ errors.present? ? array << [attribute, errors].join(" ") : array ||= []
+ end
+ full_errors << @object.errors.on_base
+ full_errors.flatten!
+ full_errors.compact!
+ return nil if full_errors.blank?
+ html_options[:class] ||= "errors"
+ template.content_tag(:ul, html_options) do
+ full_errors.map { |error| template.content_tag(:li, error) }.join
+ end
+ end
+
protected
def render_inline_errors?
View
98 spec/semantic_errors_spec.rb
@@ -0,0 +1,98 @@
+# coding: utf-8
+require File.dirname(__FILE__) + '/spec_helper'
+
+describe 'SemanticFormBuilder#semantic_errors' do
+
+ include FormtasticSpecHelper
+
+ before do
+ @output_buffer = ''
+ mock_everything
+ @title_errors = ['must not be blank', 'must be awesome']
+ @base_errors = ['base error message', 'nasty error']
+ @base_error = 'one base error'
+ @errors = mock('errors')
+ @new_post.stub!(:errors).and_return(@errors)
+ end
+
+ describe 'when there is only one error on base' do
+ before do
+ @errors.stub!(:on_base).and_return(@base_error)
+ end
+
+ it 'should render an unordered list' do
+ semantic_form_for(@new_post) do |builder|
+ builder.semantic_errors.should have_tag('ul.errors li', @base_error)
+ end
+ end
+ end
+
+ describe 'when there is more than one error on base' do
+ before do
+ @errors.stub!(:on_base).and_return(@base_errors)
+ end
+
+ it 'should render an unordered list' do
+ semantic_form_for(@new_post) do |builder|
+ builder.semantic_errors.should have_tag('ul.errors')
+ @base_errors.each do |error|
+ builder.semantic_errors.should have_tag('ul.errors li', error)
+ end
+ end
+ end
+ end
+
+ describe 'when there are errors on title' do
+ before do
+ @errors.stub!(:[]).with(:title).and_return(@title_errors)
+ @errors.stub!(:on_base).and_return([])
+ end
+
+ it 'should render an unordered list' do
+ semantic_form_for(@new_post) do |builder|
+ title_name = builder.send(:localized_string, :title, :title, :label)
+ builder.semantic_errors(:title).should have_tag('ul.errors li', title_name << " " << @title_errors.to_sentence)
+ end
+ end
+ end
+
+ describe 'when there are errors on title and base' do
+ before do
+ @errors.stub!(:[]).with(:title).and_return(@title_errors)
+ @errors.stub!(:on_base).and_return(@base_error)
+ end
+
+ it 'should render an unordered list' do
+ semantic_form_for(@new_post) do |builder|
+ title_name = builder.send(:localized_string, :title, :title, :label)
+ builder.semantic_errors(:title).should have_tag('ul.errors li', title_name << " " << @title_errors.to_sentence)
+ builder.semantic_errors(:title).should have_tag('ul.errors li', @base_error)
+ end
+ end
+ end
+
+ describe 'when there are no errors' do
+ before do
+ @errors.stub!(:[]).with(:title).and_return(nil)
+ @errors.stub!(:on_base).and_return(nil)
+ end
+
+ it 'should return nil' do
+ semantic_form_for(@new_post) do |builder|
+ builder.semantic_errors(:title).should be_nil
+ end
+ end
+ end
+
+ describe 'when there is one error on base and options with class is passed' do
+ before do
+ @errors.stub!(:on_base).and_return(@base_error)
+ end
+
+ it 'should render an unordered list with given class' do
+ semantic_form_for(@new_post) do |builder|
+ builder.semantic_errors(:class => "awesome").should have_tag('ul.awesome li', @base_error)
+ end
+ end
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.