diff --git a/lib/simple_form.rb b/lib/simple_form.rb index 588f832e..6a97ab46 100644 --- a/lib/simple_form.rb +++ b/lib/simple_form.rb @@ -16,7 +16,8 @@ module SimpleForm mattr_accessor :components @@components = [ SimpleForm::Components::Wrapper, SimpleForm::Components::Label, - SimpleForm::Components::Input, SimpleForm::Components::Hint, SimpleForm::Components::Error + SimpleForm::Components::Input, SimpleForm::Components::Hint, + SimpleForm::Components::Error ] # The terminator sent to the last component diff --git a/lib/simple_form/components/base.rb b/lib/simple_form/components/base.rb index c51b4430..6a78bc24 100644 --- a/lib/simple_form/components/base.rb +++ b/lib/simple_form/components/base.rb @@ -1,7 +1,14 @@ module SimpleForm module Components + # The component is the core of SimpleForm. SimpleForm can be customized simply + # with the addition of new components to the component stack. A component just + # need to be initialized with two values, the builder and the next component to + # be invoked and respond to call. + # + # The Base component is a raw component with some helpers and a default behavior + # of prepending the content available in the method content. class Base - attr_reader :builder, :attribute, :input_type, :options + delegate :template, :object, :object_name, :attribute, :input_type, :options, :to => :@builder def self.basename @basename ||= name.split("::").last.underscore.to_sym @@ -10,34 +17,19 @@ module SimpleForm def initialize(builder, component) @builder = builder @component = component - @attribute = @builder.attribute - @input_type = @builder.input_type - @options = @builder.options end def call - generate + @component.call - end - - def generate - return "" unless valid? - component_tag(content).to_s + return @component.call unless valid? + content + @component.call end def valid? true end - def template - @builder.template - end - - def object - @builder.object - end - def hidden_input? - @input_type == :hidden + input_type == :hidden end def basename @@ -49,7 +41,7 @@ module SimpleForm end def translate(default='') - lookups = [ :"#{@builder.object_name}.#{@attribute}", :"#{@attribute}", default ] + lookups = [ :"#{object_name}.#{attribute}", :"#{attribute}", default ] I18n.t(lookups.shift, :scope => :"simple_form.#{basename.to_s.pluralize}", :default => lookups) end end diff --git a/lib/simple_form/components/error.rb b/lib/simple_form/components/error.rb index 88aa397a..d15e3066 100644 --- a/lib/simple_form/components/error.rb +++ b/lib/simple_form/components/error.rb @@ -6,11 +6,11 @@ module SimpleForm end def errors - @errors ||= object.errors[@attribute] + @errors ||= object.errors[attribute] end def content - Array(errors).to_sentence + component_tag Array(errors).to_sentence end end end diff --git a/lib/simple_form/components/hint.rb b/lib/simple_form/components/hint.rb index 74ba4b72..8332c00d 100644 --- a/lib/simple_form/components/hint.rb +++ b/lib/simple_form/components/hint.rb @@ -2,11 +2,15 @@ module SimpleForm module Components class Hint < Base def valid? - !hidden_input? && !content.blank? + !hidden_input? && !hint.blank? + end + + def hint + @hint ||= options[:hint] || translate end def content - @content ||= @options[:hint] || translate + component_tag hint end end end diff --git a/lib/simple_form/components/input.rb b/lib/simple_form/components/input.rb index d859e5b1..f97fa799 100644 --- a/lib/simple_form/components/input.rb +++ b/lib/simple_form/components/input.rb @@ -26,15 +26,15 @@ module SimpleForm end end - def generate - html_options = @options[:html] || {} + def content + html_options = options[:html] || {} html_options[:class] = default_css_classes(html_options[:class]) - @options[:options] ||= {} + options[:options] ||= {} - mapping = self.class.mappings[@input_type] - raise "Invalid input type #{@input_type.inspect}" unless mapping + mapping = self.class.mappings[input_type] + raise "Invalid input type #{input_type.inspect}" unless mapping - args = [ @attribute ] + args = [ attribute ] apply_collection_behavior(args) if mapping.collection apply_options_behavior(args) if mapping.options args << html_options @@ -45,15 +45,15 @@ module SimpleForm protected def apply_collection_behavior(args) - collection = (@options[:collection] || self.class.boolean_collection).to_a - detect_collection_methods(collection, @options) + collection = (options[:collection] || self.class.boolean_collection).to_a + detect_collection_methods(collection, options) - @options[:options][:include_blank] = true unless @options[:options].key?(:include_blank) - args.push(collection, @options[:value_method], @options[:label_method]) + options[:options][:include_blank] = true unless options[:options].key?(:include_blank) + args.push(collection, options[:value_method], options[:label_method]) end def apply_options_behavior(args) - args << @options[:options] + args << options[:options] end def detect_collection_methods(collection, options) diff --git a/lib/simple_form/components/label.rb b/lib/simple_form/components/label.rb index 1f6accf4..9a44bff6 100644 --- a/lib/simple_form/components/label.rb +++ b/lib/simple_form/components/label.rb @@ -28,15 +28,14 @@ module SimpleForm !hidden_input? end - def generate - return '' unless valid? + def content html_options = { :class => default_css_classes } - html_options[:for] = @options[:html][:id] if @options.key?(:html) - @builder.label(@attribute, label_text, html_options) + html_options[:for] = options[:html][:id] if options.key?(:html) + @builder.label(attribute, label_text, html_options) end def label_text - required_text << (@options[:label] || translate_label) + required_text << (options[:label] || translate_label) end def required_text @@ -44,7 +43,7 @@ module SimpleForm end def translate_label - default = object.try(:human_attribute_name, @attribute.to_s) || @attribute.to_s.humanize + default = object.try(:human_attribute_name, attribute.to_s) || attribute.to_s.humanize translate(default) end end diff --git a/lib/simple_form/form_builder.rb b/lib/simple_form/form_builder.rb index 05d65788..f5989851 100644 --- a/lib/simple_form/form_builder.rb +++ b/lib/simple_form/form_builder.rb @@ -1,6 +1,5 @@ module SimpleForm class FormBuilder < ActionView::Helpers::FormBuilder - # Make the template accessible for components attr_reader :template, :object_name, :object, :attribute, :input_type, :options def input(attribute, options={}) @@ -23,7 +22,7 @@ module SimpleForm return :select if @options[:collection] input_type = if @object.respond_to?(:column_for_attribute) - column = @object.column_for_attribute(attribute) + column = @object.column_for_attribute(@attribute) column.type if column end @@ -31,7 +30,7 @@ module SimpleForm when :timestamp :datetime when :string, nil - attribute.to_s =~ /password/ ? :password : :string + @attribute.to_s =~ /password/ ? :password : :string else input_type end diff --git a/lib/simple_form/required_helpers.rb b/lib/simple_form/required_helpers.rb index 01e5c23c..720b0fad 100644 --- a/lib/simple_form/required_helpers.rb +++ b/lib/simple_form/required_helpers.rb @@ -1,7 +1,7 @@ module SimpleForm module RequiredHelpers def attribute_required? - @options[:required] != false + options[:required] != false end def required_class @@ -9,11 +9,11 @@ module SimpleForm end def attribute_required? - @options[:required] != false + options[:required] != false end def default_css_classes(merge_class=nil) - "#{@input_type} #{required_class} #{merge_class}".strip + "#{input_type} #{required_class} #{merge_class}".strip end end end \ No newline at end of file diff --git a/test/components/error_test.rb b/test/components/error_test.rb index 2c96807b..b2a04573 100644 --- a/test/components/error_test.rb +++ b/test/components/error_test.rb @@ -9,26 +9,26 @@ class ErrorTest < ActionView::TestCase f.options = options error = SimpleForm::Components::Error.new(f, SimpleForm.terminator) - concat(error.generate) + concat(error.call) yield error if block_given? end end test 'error should not generate content for hidden fields' do with_error_for @user, :name, :hidden do |error| - assert error.generate.blank? + assert error.call.blank? end end test 'error should not generate content for attribute without errors' do with_error_for @user, :active, :boolean do |error| - assert error.generate.blank? + assert error.call.blank? end end test 'error should not generate messages when object is not present' do with_error_for :project, :name, :string do |error| - assert error.generate.blank? + assert error.call.blank? end end diff --git a/test/components/hint_test.rb b/test/components/hint_test.rb index 42f188d1..97b8dc18 100644 --- a/test/components/hint_test.rb +++ b/test/components/hint_test.rb @@ -9,20 +9,20 @@ class ErrorTest < ActionView::TestCase f.options = options hint = SimpleForm::Components::Hint.new(f, SimpleForm.terminator) - concat(hint.generate) + concat(hint.call) yield hint if block_given? end end test 'hint should not be generated by default' do with_hint_for @user, :name, :string do |hint| - assert hint.generate.blank? + assert hint.call.blank? end end test 'hint should not be generated for hidden fields' do with_hint_for @user, :name, :hidden, :hint => 'Use with care...' do |hint| - assert hint.generate.blank? + assert hint.call.blank? end end diff --git a/test/components/input_test.rb b/test/components/input_test.rb index 8235973f..0c8638c2 100644 --- a/test/components/input_test.rb +++ b/test/components/input_test.rb @@ -13,7 +13,7 @@ class InputTest < ActionView::TestCase f.options = options input = SimpleForm::Components::Input.new(f, SimpleForm.terminator) - concat(input.generate) + concat(input.call) yield input if block_given? end end diff --git a/test/components/label_test.rb b/test/components/label_test.rb index 0012f298..64b98b3a 100644 --- a/test/components/label_test.rb +++ b/test/components/label_test.rb @@ -15,14 +15,14 @@ class LabelTest < ActionView::TestCase f.options = options label = SimpleForm::Components::Label.new(f, SimpleForm.terminator) - concat(label.generate) + concat(label.call) yield label if block_given? end end test 'label should not be generated for hidden inputs' do - with_label_for @user, :name, :hidden do |label| - assert label.generate.blank? + with_label_for @user, :name, :hidden do |label| + assert label.call.blank? end end