diff --git a/CHANGELOG.md b/CHANGELOG.md index e4444b62..3abf7ea9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## master ### enhancements + * Add the `full_error` component. [@laurocaetano](https://github.com/laurocaetano) * Add support to `scope` to be used on associations. [@laurocaetano](https://github.com/laurocaetano) * Execute the association `condition` in the object context. [@laurocaetano](https://github.com/laurocaetano) * Check if the given association responds to `order` before calling it. [@laurocaetano](https://github.com/laurocaetano) diff --git a/lib/generators/simple_form/templates/config/initializers/simple_form.rb b/lib/generators/simple_form/templates/config/initializers/simple_form.rb index 89a3b374..0a6656e0 100644 --- a/lib/generators/simple_form/templates/config/initializers/simple_form.rb +++ b/lib/generators/simple_form/templates/config/initializers/simple_form.rb @@ -43,6 +43,12 @@ SimpleForm.setup do |config| b.use :label_input b.use :hint, wrap_with: { tag: :span, class: :hint } b.use :error, wrap_with: { tag: :span, class: :error } + + ## full_messages_for + # If you want to display the full error message for the attribute, you can + # use the component :full_error, like: + # + # b.use :full_error, wrap_with: { tag: :span, class: :error } end # The default wrapper to be used by the FormBuilder. diff --git a/lib/simple_form/components/errors.rb b/lib/simple_form/components/errors.rb index b4bacf85..70c44c15 100644 --- a/lib/simple_form/components/errors.rb +++ b/lib/simple_form/components/errors.rb @@ -5,6 +5,10 @@ module SimpleForm error_text if has_errors? end + def full_error(wrapper_options = nil) + full_error_text if has_errors? + end + def has_errors? object && object.respond_to?(:errors) && errors.present? end @@ -15,6 +19,10 @@ module SimpleForm "#{html_escape(options[:error_prefix])} #{errors.send(error_method)}".lstrip.html_safe end + def full_error_text + "#{html_escape(options[:error_prefix])} #{full_errors.send(error_method)}".lstrip.html_safe + end + def error_method options[:error_method] || SimpleForm.error_method end @@ -23,13 +31,25 @@ module SimpleForm @errors ||= (errors_on_attribute + errors_on_association).compact end + def full_errors + @full_errors ||= (full_errors_on_attribute + full_errors_on_association).compact + end + def errors_on_attribute object.errors[attribute_name] end + def full_errors_on_attribute + object.errors.full_messages_for(attribute_name) + end + def errors_on_association reflection ? object.errors[reflection.name] : [] end + + def full_errors_on_association + reflection ? object.full_messages_for(reflection.name) : [] + end end end end diff --git a/test/form_builder/error_test.rb b/test/form_builder/error_test.rb index 06a024a7..bcdf99f8 100644 --- a/test/form_builder/error_test.rb +++ b/test/form_builder/error_test.rb @@ -123,4 +123,13 @@ class ErrorTest < ActionView::TestCase assert_select 'span.omg_error', "can't be blank" end end + + # FULL_ERROR_WRAPPER + + test 'full error should find errors on association' do + swap_wrapper :default, self.custom_wrapper_with_full_error do + with_form_for @user, :company_id, as: :select + assert_select 'span.error', 'Company must be valid' + end + end end diff --git a/test/form_builder/wrapper_test.rb b/test/form_builder/wrapper_test.rb index 8c011db4..3cf36f57 100644 --- a/test/form_builder/wrapper_test.rb +++ b/test/form_builder/wrapper_test.rb @@ -136,6 +136,13 @@ class WrapperTest < ActionView::TestCase end end + test 'custom wrappers can have full error message on attributes' do + swap_wrapper :default, self.custom_wrapper_with_full_error do + with_form_for @user, :name + assert_select 'span.error', "Name can't be blank" + end + end + test 'custom wrappers on a form basis' do swap_wrapper :another do with_concat_form_for(@user) do |f| diff --git a/test/support/misc_helpers.rb b/test/support/misc_helpers.rb index 7a663628..1826bc93 100644 --- a/test/support/misc_helpers.rb +++ b/test/support/misc_helpers.rb @@ -144,6 +144,12 @@ module MiscHelpers end end + def custom_wrapper_with_full_error + SimpleForm.build tag: :div, class: 'custom_wrapper' do |b| + b.use :full_error, wrap_with: { tag: :span, class: :error } + end + end + def custom_wrapper_with_label_text SimpleForm.build :label_text => proc { |label, required| "**#{label}**" } do |b| b.use :label_input