From ba46d2a7ff40b426d2d5965ab5ae47125158ca52 Mon Sep 17 00:00:00 2001 From: Justin French Date: Wed, 26 Oct 2011 17:59:32 +1100 Subject: [PATCH 01/15] whitespace --- spec/inputs/boolean_input_spec.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/spec/inputs/boolean_input_spec.rb b/spec/inputs/boolean_input_spec.rb index 340fef1c9..43ebe8bdb 100644 --- a/spec/inputs/boolean_input_spec.rb +++ b/spec/inputs/boolean_input_spec.rb @@ -21,8 +21,6 @@ it 'should generate a label containing the input' do output_buffer.should_not have_tag('label.label') - - output_buffer.should have_tag('form li label', :count => 1) output_buffer.should have_tag('form li label[@for="post_allow_comments"]') output_buffer.should have_tag('form li label', /Allow comments/) From e05bbb6c7f6a303cdc3fb673b5ead5f3273b83b4 Mon Sep 17 00:00:00 2001 From: Justin French Date: Wed, 26 Oct 2011 18:18:51 +1100 Subject: [PATCH 02/15] fix boolean input to respect :index from fields_for in input[name] attribute, ref #711 --- lib/formtastic/inputs/boolean_input.rb | 10 ++++++++- spec/inputs/boolean_input_spec.rb | 31 ++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/lib/formtastic/inputs/boolean_input.rb b/lib/formtastic/inputs/boolean_input.rb index 980f9db8d..9d8233fef 100644 --- a/lib/formtastic/inputs/boolean_input.rb +++ b/lib/formtastic/inputs/boolean_input.rb @@ -84,7 +84,15 @@ def responds_to_global_required? end def input_html_options - {:name => "#{object_name}[#{method}]"}.merge(super) + {:name => input_html_options_name}.merge(super) + end + + def input_html_options_name + if builder.options.key?(:index) + "#{object_name}[#{builder.options[:index]}][#{method}]" + else + "#{object_name}[#{method}]" + end end def checked? diff --git a/spec/inputs/boolean_input_spec.rb b/spec/inputs/boolean_input_spec.rb index 43ebe8bdb..a343b4bcb 100644 --- a/spec/inputs/boolean_input_spec.rb +++ b/spec/inputs/boolean_input_spec.rb @@ -184,5 +184,36 @@ it_should_have_an_inline_label_for("context2_post_allow_comments") end + + describe "when index is provided" do + + before do + @output_buffer = '' + mock_everything + + concat(semantic_form_for(@new_post) do |builder| + concat(builder.fields_for :author, :index => 3 do |author| + concat(author.input(:name, :as => :boolean)) + end) + end) + end + + it 'should index the id of the wrapper' do + output_buffer.should have_tag("li#post_author_attributes_3_name_input") + end + + it 'should index the id of the input tag' do + output_buffer.should have_tag("input#post_author_attributes_3_name") + end + + it 'should index the name of the hidden input' do + output_buffer.should have_tag("input[@type='hidden'][@name='post[author_attributes][3][name]']") + end + + it 'should index the name of the checkbox input' do + output_buffer.should have_tag("input[@type='checkbox'][@name='post[author_attributes][3][name]']") + end + + end end From 1d63ebe9d0b41469c63f2a42bc9cf58fc9018f44 Mon Sep 17 00:00:00 2001 From: Justin French Date: Thu, 27 Oct 2011 07:25:17 +1100 Subject: [PATCH 03/15] fix select input to respect :index from fields_for in select[name] attribute, ref #711 --- lib/formtastic/inputs/select_input.rb | 14 +++++++++++++- spec/inputs/select_input_spec.rb | 27 +++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/lib/formtastic/inputs/select_input.rb b/lib/formtastic/inputs/select_input.rb index b8da74be1..f8f9fe5a3 100644 --- a/lib/formtastic/inputs/select_input.rb +++ b/lib/formtastic/inputs/select_input.rb @@ -186,9 +186,21 @@ def input_html_options def extra_input_html_options { :multiple => multiple?, - :name => "#{object_name}[#{association_primary_key}]#{'[]' if multiple?}" + :name => multiple? ? input_html_options_name_multiple : input_html_options_name } end + + def input_html_options_name + if builder.options.key?(:index) + "#{object_name}[#{builder.options[:index]}][#{association_primary_key}]" + else + "#{object_name}[#{association_primary_key}]" + end + end + + def input_html_options_name_multiple + input_html_options_name + "[]" + end def multiple_by_association? reflection && [ :has_many, :has_and_belongs_to_many ].include?(reflection.macro) diff --git a/spec/inputs/select_input_spec.rb b/spec/inputs/select_input_spec.rb index 543699e50..e91b4e088 100644 --- a/spec/inputs/select_input_spec.rb +++ b/spec/inputs/select_input_spec.rb @@ -560,6 +560,33 @@ it_should_have_select_with_id("context2_post_author_ids") it_should_have_label_for("context2_post_author_ids") end + + describe "when index is provided" do + + before do + @output_buffer = '' + mock_everything + + concat(semantic_form_for(@new_post) do |builder| + concat(builder.fields_for :author, :index => 3 do |author| + concat(author.input(:name, :as => :select)) + end) + end) + end + + it 'should index the id of the wrapper' do + output_buffer.should have_tag("li#post_author_attributes_3_name_input") + end + + it 'should index the id of the select tag' do + output_buffer.should have_tag("select#post_author_attributes_3_name") + end + + it 'should index the name of the select' do + output_buffer.should have_tag("select[@name='post[author_attributes][3][name]']") + end + + end context "when required" do it "should add the required attribute to the select's html options" do From 56bf9174aca04ac87057821d71883ec985ac5468 Mon Sep 17 00:00:00 2001 From: Justin French Date: Thu, 27 Oct 2011 07:41:23 +1100 Subject: [PATCH 04/15] fix checkboxes input to respect :index from fields_for in input[name] and [id] attributes, ref #711 --- lib/formtastic/inputs/base/choices.rb | 1 + lib/formtastic/inputs/check_boxes_input.rb | 6 ++++- spec/inputs/check_boxes_input_spec.rb | 28 ++++++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/lib/formtastic/inputs/base/choices.rb b/lib/formtastic/inputs/base/choices.rb index 908ac7636..8845c9ff4 100644 --- a/lib/formtastic/inputs/base/choices.rb +++ b/lib/formtastic/inputs/base/choices.rb @@ -71,6 +71,7 @@ def choice_input_dom_id(choice) [ builder.custom_namespace, sanitized_object_name, + builder.options[:index], association_primary_key || method, choice_html_safe_value(choice) ].compact.reject { |i| i.blank? }.join("_") diff --git a/lib/formtastic/inputs/check_boxes_input.rb b/lib/formtastic/inputs/check_boxes_input.rb index 7e28c9baa..1d005d41d 100644 --- a/lib/formtastic/inputs/check_boxes_input.rb +++ b/lib/formtastic/inputs/check_boxes_input.rb @@ -166,7 +166,11 @@ def unchecked_value end def input_name - "#{object_name}[#{association_primary_key || method}][]" + if builder.options.key?(:index) + "#{object_name}[#{builder.options[:index]}][#{association_primary_key || method}][]" + else + "#{object_name}[#{association_primary_key || method}][]" + end end protected diff --git a/spec/inputs/check_boxes_input_spec.rb b/spec/inputs/check_boxes_input_spec.rb index 559ae4fbe..86aed8146 100644 --- a/spec/inputs/check_boxes_input_spec.rb +++ b/spec/inputs/check_boxes_input_spec.rb @@ -392,6 +392,34 @@ it_should_have_input_with_id('context2_author_post_ids_19') it_should_have_input_wrapper_with_id("context2_author_posts_input") end + + describe "when index is provided" do + + before do + @output_buffer = '' + mock_everything + + concat(semantic_form_for(@fred) do |builder| + concat(builder.fields_for @fred.posts.first, :index => 3 do |author| + concat(author.input(:authors, :as => :check_boxes)) + end) + end) + end + + it 'should index the id of the wrapper' do + output_buffer.should have_tag("li#author_post_3_authors_input") + end + + it 'should index the id of the input tag' do + output_buffer.should have_tag("input#author_post_3_author_ids_42") + end + + it 'should index the name of the checkbox input' do + output_buffer.should have_tag("input[@type='checkbox'][@name='author[post][3][author_ids][]']") + end + + end + describe "when collection is an array" do before do From ec288280c370d8c9f2bcbb30f000a54941e4a7ef Mon Sep 17 00:00:00 2001 From: Justin French Date: Thu, 27 Oct 2011 08:58:16 +1100 Subject: [PATCH 05/15] fix date, datetime and time inputs to respect :index from fields_for, ref #711 --- lib/formtastic/inputs/base/timeish.rb | 10 +++++++- lib/formtastic/inputs/time_input.rb | 10 +++++++- spec/inputs/date_input_spec.rb | 32 ++++++++++++++++++++++++ spec/inputs/datetime_input_spec.rb | 36 +++++++++++++++++++++++++++ spec/inputs/time_input_spec.rb | 35 ++++++++++++++++++++++++++ 5 files changed, 121 insertions(+), 2 deletions(-) diff --git a/lib/formtastic/inputs/base/timeish.rb b/lib/formtastic/inputs/base/timeish.rb index 75051b9b3..064806075 100644 --- a/lib/formtastic/inputs/base/timeish.rb +++ b/lib/formtastic/inputs/base/timeish.rb @@ -156,10 +156,18 @@ def value end def fragment_input_html(fragment) - opts = input_options.merge(:prefix => object_name, :field_name => fragment_name(fragment), :default => value, :include_blank => include_blank?) + opts = input_options.merge(:prefix => fragment_prefix, :field_name => fragment_name(fragment), :default => value, :include_blank => include_blank?) template.send(:"select_#{fragment}", value, opts, input_html_options.merge(:id => fragment_id(fragment))) end + def fragment_prefix + if builder.options.key?(:index) + object_name + "[#{builder.options[:index]}]" + else + object_name + end + end + # TODO extract to BlankOptions or similar -- Select uses similar code def include_blank? options.key?(:include_blank) ? options[:include_blank] : builder.include_blank_for_select_by_default diff --git a/lib/formtastic/inputs/time_input.rb b/lib/formtastic/inputs/time_input.rb index c07f7fc3c..65e6165f9 100644 --- a/lib/formtastic/inputs/time_input.rb +++ b/lib/formtastic/inputs/time_input.rb @@ -26,13 +26,21 @@ def fragment_value(fragment) def hidden_fragments if !options[:ignore_date] date_fragments.map do |fragment| - template.hidden_field_tag("#{object_name}[#{fragment_name(fragment)}]", fragment_value(fragment), :id => fragment_id(fragment), :disabled => input_html_options[:disabled] ) + template.hidden_field_tag(hidden_field_name(fragment), fragment_value(fragment), :id => fragment_id(fragment), :disabled => input_html_options[:disabled] ) end.join.html_safe else super end end + def hidden_field_name(fragment) + if builder.options.key?(:index) + "#{object_name}[#{builder.options[:index]}][#{fragment_name(fragment)}]" + else + "#{object_name}[#{fragment_name(fragment)}]" + end + end + end end end \ No newline at end of file diff --git a/spec/inputs/date_input_spec.rb b/spec/inputs/date_input_spec.rb index a06380814..1b42c1cf6 100644 --- a/spec/inputs/date_input_spec.rb +++ b/spec/inputs/date_input_spec.rb @@ -70,6 +70,38 @@ it_should_have_select_with_id("context2_post_publish_at_3i") end + + describe "when index is provided" do + + before do + @output_buffer = '' + mock_everything + + concat(semantic_form_for(@new_post) do |builder| + concat(builder.fields_for :author, :index => 3 do |author| + concat(author.input(:created_at, :as => :date)) + end) + end) + end + + it 'should index the id of the wrapper' do + output_buffer.should have_tag("li#post_author_attributes_3_created_at_input") + end + + it 'should index the id of the select tag' do + output_buffer.should have_tag("select#post_author_attributes_3_created_at_1i") + output_buffer.should have_tag("select#post_author_attributes_3_created_at_2i") + output_buffer.should have_tag("select#post_author_attributes_3_created_at_3i") + end + + it 'should index the name of the select tag' do + output_buffer.should have_tag("select[@name='post[author_attributes][3][created_at(1i)]']") + output_buffer.should have_tag("select[@name='post[author_attributes][3][created_at(2i)]']") + output_buffer.should have_tag("select[@name='post[author_attributes][3][created_at(3i)]']") + end + + end + describe ':labels option' do fields = [:year, :month, :day] diff --git a/spec/inputs/datetime_input_spec.rb b/spec/inputs/datetime_input_spec.rb index 8481daa82..ab39e0d50 100644 --- a/spec/inputs/datetime_input_spec.rb +++ b/spec/inputs/datetime_input_spec.rb @@ -76,6 +76,42 @@ end + describe "when index is provided" do + + before do + @output_buffer = '' + mock_everything + + concat(semantic_form_for(@new_post) do |builder| + concat(builder.fields_for :author, :index => 3 do |author| + concat(author.input(:created_at, :as => :datetime)) + end) + end) + end + + it 'should index the id of the wrapper' do + output_buffer.should have_tag("li#post_author_attributes_3_created_at_input") + end + + it 'should index the id of the select tag' do + output_buffer.should have_tag("select#post_author_attributes_3_created_at_1i") + output_buffer.should have_tag("select#post_author_attributes_3_created_at_2i") + output_buffer.should have_tag("select#post_author_attributes_3_created_at_3i") + output_buffer.should have_tag("select#post_author_attributes_3_created_at_4i") + output_buffer.should have_tag("select#post_author_attributes_3_created_at_5i") + end + + it 'should index the name of the select tag' do + output_buffer.should have_tag("select[@name='post[author_attributes][3][created_at(1i)]']") + output_buffer.should have_tag("select[@name='post[author_attributes][3][created_at(2i)]']") + output_buffer.should have_tag("select[@name='post[author_attributes][3][created_at(3i)]']") + output_buffer.should have_tag("select[@name='post[author_attributes][3][created_at(4i)]']") + output_buffer.should have_tag("select[@name='post[author_attributes][3][created_at(5i)]']") + end + + end + + describe ':labels option' do fields = [:year, :month, :day, :hour, :minute] fields.each do |field| diff --git a/spec/inputs/time_input_spec.rb b/spec/inputs/time_input_spec.rb index b8353e63c..70c41a4f5 100644 --- a/spec/inputs/time_input_spec.rb +++ b/spec/inputs/time_input_spec.rb @@ -198,4 +198,39 @@ end end + describe "when index is provided" do + + before do + concat(semantic_form_for(@new_post) do |builder| + concat(builder.fields_for :author, :index => 3 do |author| + concat(author.input(:created_at, :as => :time)) + end) + end) + end + + it 'should index the id of the wrapper' do + output_buffer.should have_tag("li#post_author_attributes_3_created_at_input") + end + + it 'should index the id of the select tag' do + output_buffer.should have_tag("input#post_author_attributes_3_created_at_1i") + output_buffer.should have_tag("input#post_author_attributes_3_created_at_2i") + output_buffer.should have_tag("input#post_author_attributes_3_created_at_3i") + output_buffer.should have_tag("select#post_author_attributes_3_created_at_4i") + output_buffer.should have_tag("select#post_author_attributes_3_created_at_5i") + end + + it 'should index the name of the select tag' do + output_buffer.should have_tag("input[@name='post[author_attributes][3][created_at(1i)]']") + output_buffer.should have_tag("input[@name='post[author_attributes][3][created_at(2i)]']") + output_buffer.should have_tag("input[@name='post[author_attributes][3][created_at(3i)]']") + output_buffer.should have_tag("select[@name='post[author_attributes][3][created_at(4i)]']") + output_buffer.should have_tag("select[@name='post[author_attributes][3][created_at(5i)]']") + end + + end + end + + + From 253dc6d559b610f04fab1bc43209d6caa0603d30 Mon Sep 17 00:00:00 2001 From: Justin French Date: Thu, 27 Oct 2011 17:43:25 +1100 Subject: [PATCH 06/15] coverage to assert that fields for with :index works on various inputs, ref #711 --- spec/inputs/date_input_spec.rb | 1 - spec/inputs/email_input_spec.rb | 28 ++++++++++++++++++++++++++++ spec/inputs/file_input_spec.rb | 28 ++++++++++++++++++++++++++++ spec/inputs/hidden_input_spec.rb | 28 ++++++++++++++++++++++++++++ spec/inputs/number_input_spec.rb | 28 ++++++++++++++++++++++++++++ spec/inputs/password_input_spec.rb | 28 ++++++++++++++++++++++++++++ spec/inputs/phone_input_spec.rb | 28 ++++++++++++++++++++++++++++ spec/inputs/radio_input_spec.rb | 29 +++++++++++++++++++++++++++++ spec/inputs/range_input_spec.rb | 28 ++++++++++++++++++++++++++++ spec/inputs/search_input_spec.rb | 27 +++++++++++++++++++++++++++ spec/inputs/string_input_spec.rb | 28 ++++++++++++++++++++++++++++ spec/inputs/text_input_spec.rb | 27 +++++++++++++++++++++++++++ spec/inputs/time_zone_input_spec.rb | 28 ++++++++++++++++++++++++++++ spec/inputs/url_input_spec.rb | 28 ++++++++++++++++++++++++++++ 14 files changed, 363 insertions(+), 1 deletion(-) diff --git a/spec/inputs/date_input_spec.rb b/spec/inputs/date_input_spec.rb index 1b42c1cf6..19f4218ab 100644 --- a/spec/inputs/date_input_spec.rb +++ b/spec/inputs/date_input_spec.rb @@ -101,7 +101,6 @@ end end - describe ':labels option' do fields = [:year, :month, :day] diff --git a/spec/inputs/email_input_spec.rb b/spec/inputs/email_input_spec.rb index a682104dc..e5a2bc098 100644 --- a/spec/inputs/email_input_spec.rb +++ b/spec/inputs/email_input_spec.rb @@ -42,6 +42,34 @@ end + describe "when index is provided" do + + before do + @output_buffer = '' + mock_everything + + concat(semantic_form_for(@new_post) do |builder| + concat(builder.fields_for :author, :index => 3 do |author| + concat(author.input(:name, :as => :email)) + end) + end) + end + + it 'should index the id of the wrapper' do + output_buffer.should have_tag("li#post_author_attributes_3_name_input") + end + + it 'should index the id of the select tag' do + output_buffer.should have_tag("input#post_author_attributes_3_name") + end + + it 'should index the name of the select tag' do + output_buffer.should have_tag("input[@name='post[author_attributes][3][name]']") + end + + end + + describe "when required" do it "should add the required attribute to the input's html options" do with_config :use_required_attribute, true do diff --git a/spec/inputs/file_input_spec.rb b/spec/inputs/file_input_spec.rb index 19d68e2d5..6dfc003a9 100644 --- a/spec/inputs/file_input_spec.rb +++ b/spec/inputs/file_input_spec.rb @@ -46,6 +46,34 @@ end + describe "when index is provided" do + + before do + @output_buffer = '' + mock_everything + + concat(semantic_form_for(@new_post) do |builder| + concat(builder.fields_for :author, :index => 3 do |author| + concat(author.input(:name, :as => :file)) + end) + end) + end + + it 'should index the id of the wrapper' do + output_buffer.should have_tag("li#post_author_attributes_3_name_input") + end + + it 'should index the id of the select tag' do + output_buffer.should have_tag("input#post_author_attributes_3_name") + end + + it 'should index the name of the select tag' do + output_buffer.should have_tag("input[@name='post[author_attributes][3][name]']") + end + + end + + context "when required" do it "should add the required attribute to the input's html options" do with_config :use_required_attribute, true do diff --git a/spec/inputs/hidden_input_spec.rb b/spec/inputs/hidden_input_spec.rb index 2fee3503b..0ffc7c1cb 100644 --- a/spec/inputs/hidden_input_spec.rb +++ b/spec/inputs/hidden_input_spec.rb @@ -98,6 +98,34 @@ end + describe "when index is provided" do + + before do + @output_buffer = '' + mock_everything + + concat(semantic_form_for(@new_post) do |builder| + concat(builder.fields_for :author, :index => 3 do |author| + concat(author.input(:name, :as => :hidden)) + end) + end) + end + + it 'should index the id of the wrapper' do + output_buffer.should have_tag("li#post_author_attributes_3_name_input") + end + + it 'should index the id of the select tag' do + output_buffer.should have_tag("input#post_author_attributes_3_name") + end + + it 'should index the name of the select tag' do + output_buffer.should have_tag("input[@name='post[author_attributes][3][name]']") + end + + end + + context "when required" do it "should not add the required attribute to the input's html options" do concat(semantic_form_for(@new_post) do |builder| diff --git a/spec/inputs/number_input_spec.rb b/spec/inputs/number_input_spec.rb index 903ec4274..b8d5ab9d1 100644 --- a/spec/inputs/number_input_spec.rb +++ b/spec/inputs/number_input_spec.rb @@ -66,6 +66,34 @@ it_should_have_label_and_input_with_id("context2_post_title") end + describe "when index is provided" do + + before do + @output_buffer = '' + mock_everything + + concat(semantic_form_for(@new_post) do |builder| + concat(builder.fields_for :author, :index => 3 do |author| + concat(author.input(:name, :as => :number)) + end) + end) + end + + it 'should index the id of the wrapper' do + output_buffer.should have_tag("li#post_author_attributes_3_name_input") + end + + it 'should index the id of the select tag' do + output_buffer.should have_tag("input#post_author_attributes_3_name") + end + + it 'should index the name of the select tag' do + output_buffer.should have_tag("input[@name='post[author_attributes][3][name]']") + end + + end + + describe "when required" do it "should add the required attribute to the input's html options" do with_config :use_required_attribute, true do diff --git a/spec/inputs/password_input_spec.rb b/spec/inputs/password_input_spec.rb index 9e60e0ff7..f21c8ac3d 100644 --- a/spec/inputs/password_input_spec.rb +++ b/spec/inputs/password_input_spec.rb @@ -57,6 +57,34 @@ end + describe "when index is provided" do + + before do + @output_buffer = '' + mock_everything + + concat(semantic_form_for(@new_post) do |builder| + concat(builder.fields_for :author, :index => 3 do |author| + concat(author.input(:name, :as => :password)) + end) + end) + end + + it 'should index the id of the wrapper' do + output_buffer.should have_tag("li#post_author_attributes_3_name_input") + end + + it 'should index the id of the select tag' do + output_buffer.should have_tag("input#post_author_attributes_3_name") + end + + it 'should index the name of the select tag' do + output_buffer.should have_tag("input[@name='post[author_attributes][3][name]']") + end + + end + + describe "when required" do it "should add the required attribute to the input's html options" do with_config :use_required_attribute, true do diff --git a/spec/inputs/phone_input_spec.rb b/spec/inputs/phone_input_spec.rb index c4729e239..8c4d21cc0 100644 --- a/spec/inputs/phone_input_spec.rb +++ b/spec/inputs/phone_input_spec.rb @@ -42,6 +42,34 @@ end + describe "when index is provided" do + + before do + @output_buffer = '' + mock_everything + + concat(semantic_form_for(@new_post) do |builder| + concat(builder.fields_for :author, :index => 3 do |author| + concat(author.input(:name, :as => :phone)) + end) + end) + end + + it 'should index the id of the wrapper' do + output_buffer.should have_tag("li#post_author_attributes_3_name_input") + end + + it 'should index the id of the select tag' do + output_buffer.should have_tag("input#post_author_attributes_3_name") + end + + it 'should index the name of the select tag' do + output_buffer.should have_tag("input[@name='post[author_attributes][3][name]']") + end + + end + + describe "when required" do it "should add the required attribute to the input's html options" do with_config :use_required_attribute, true do diff --git a/spec/inputs/radio_input_spec.rb b/spec/inputs/radio_input_spec.rb index 808f5a26d..c69c31dcc 100644 --- a/spec/inputs/radio_input_spec.rb +++ b/spec/inputs/radio_input_spec.rb @@ -233,5 +233,34 @@ end it_should_have_input_wrapper_with_id("custom_prefix_post_authors_input") end + + describe "when index is provided" do + + before do + @output_buffer = '' + mock_everything + + concat(semantic_form_for(@new_post) do |builder| + concat(builder.fields_for :author, :index => 3 do |author| + concat(author.input(:name, :as => :radio)) + end) + end) + end + + it 'should index the id of the wrapper' do + output_buffer.should have_tag("li#post_author_attributes_3_name_input") + end + + it 'should index the id of the select tag' do + output_buffer.should have_tag("input#post_author_attributes_3_name_true") + output_buffer.should have_tag("input#post_author_attributes_3_name_false") + end + + it 'should index the name of the select tag' do + output_buffer.should have_tag("input[@name='post[author_attributes][3][name]']") + end + + end + end diff --git a/spec/inputs/range_input_spec.rb b/spec/inputs/range_input_spec.rb index 7b9c3b694..5a484f126 100644 --- a/spec/inputs/range_input_spec.rb +++ b/spec/inputs/range_input_spec.rb @@ -41,6 +41,34 @@ it_should_have_label_and_input_with_id("context2_author_age") end + + describe "when index is provided" do + + before do + @output_buffer = '' + mock_everything + + concat(semantic_form_for(@new_post) do |builder| + concat(builder.fields_for :author, :index => 3 do |author| + concat(author.input(:name, :as => :range)) + end) + end) + end + + it 'should index the id of the wrapper' do + output_buffer.should have_tag("li#post_author_attributes_3_name_input") + end + + it 'should index the id of the select tag' do + output_buffer.should have_tag("input#post_author_attributes_3_name") + end + + it 'should index the name of the select tag' do + output_buffer.should have_tag("input[@name='post[author_attributes][3][name]']") + end + + end + describe "when validations require a minimum value (:greater_than)" do before do diff --git a/spec/inputs/search_input_spec.rb b/spec/inputs/search_input_spec.rb index 50e9bafc4..8db394b42 100644 --- a/spec/inputs/search_input_spec.rb +++ b/spec/inputs/search_input_spec.rb @@ -42,6 +42,33 @@ end + describe "when index is provided" do + + before do + @output_buffer = '' + mock_everything + + concat(semantic_form_for(@new_post) do |builder| + concat(builder.fields_for :author, :index => 3 do |author| + concat(author.input(:name, :as => :search)) + end) + end) + end + + it 'should index the id of the wrapper' do + output_buffer.should have_tag("li#post_author_attributes_3_name_input") + end + + it 'should index the id of the select tag' do + output_buffer.should have_tag("input#post_author_attributes_3_name") + end + + it 'should index the name of the select tag' do + output_buffer.should have_tag("input[@name='post[author_attributes][3][name]']") + end + + end + describe "when required" do it "should add the required attribute to the input's html options" do with_config :use_required_attribute, true do diff --git a/spec/inputs/string_input_spec.rb b/spec/inputs/string_input_spec.rb index 5507fff12..c9ea0a645 100644 --- a/spec/inputs/string_input_spec.rb +++ b/spec/inputs/string_input_spec.rb @@ -124,6 +124,34 @@ def should_have_maxlength(maxlength, options) end + describe "when index is provided" do + + before do + @output_buffer = '' + mock_everything + + concat(semantic_form_for(@new_post) do |builder| + concat(builder.fields_for :author, :index => 3 do |author| + concat(author.input(:name, :as => :string)) + end) + end) + end + + it 'should index the id of the wrapper' do + output_buffer.should have_tag("li#post_author_attributes_3_name_input") + end + + it 'should index the id of the select tag' do + output_buffer.should have_tag("input#post_author_attributes_3_name") + end + + it 'should index the name of the select tag' do + output_buffer.should have_tag("input[@name='post[author_attributes][3][name]']") + end + + end + + describe "when no object is provided" do before do concat(semantic_form_for(:project, :url => 'http://test.host/') do |builder| diff --git a/spec/inputs/text_input_spec.rb b/spec/inputs/text_input_spec.rb index a3da09235..2e369560d 100644 --- a/spec/inputs/text_input_spec.rb +++ b/spec/inputs/text_input_spec.rb @@ -81,6 +81,33 @@ end + describe "when index is provided" do + + before do + @output_buffer = '' + mock_everything + + concat(semantic_form_for(@new_post) do |builder| + concat(builder.fields_for :author, :index => 3 do |author| + concat(author.input(:name, :as => :text)) + end) + end) + end + + it 'should index the id of the wrapper' do + output_buffer.should have_tag("li#post_author_attributes_3_name_input") + end + + it 'should index the id of the select tag' do + output_buffer.should have_tag("textarea#post_author_attributes_3_name") + end + + it 'should index the name of the select tag' do + output_buffer.should have_tag("textarea[@name='post[author_attributes][3][name]']") + end + + end + context "when required" do it "should add the required attribute to the input's html options" do with_config :use_required_attribute, true do diff --git a/spec/inputs/time_zone_input_spec.rb b/spec/inputs/time_zone_input_spec.rb index 57bf9b8ce..c644757e9 100644 --- a/spec/inputs/time_zone_input_spec.rb +++ b/spec/inputs/time_zone_input_spec.rb @@ -54,6 +54,34 @@ it_should_have_label_for("context2_post_time_zone") end + + describe "when index is provided" do + + before do + @output_buffer = '' + mock_everything + + concat(semantic_form_for(@new_post) do |builder| + concat(builder.fields_for :author, :index => 3 do |author| + concat(author.input(:name, :as => :time_zone)) + end) + end) + end + + it 'should index the id of the wrapper' do + output_buffer.should have_tag("li#post_author_attributes_3_name_input") + end + + it 'should index the id of the select tag' do + output_buffer.should have_tag("select#post_author_attributes_3_name") + end + + it 'should index the name of the select tag' do + output_buffer.should have_tag("select[@name='post[author_attributes][3][name]']") + end + + end + describe 'when no object is given' do before(:each) do diff --git a/spec/inputs/url_input_spec.rb b/spec/inputs/url_input_spec.rb index ef7f7f087..82cceb8f0 100644 --- a/spec/inputs/url_input_spec.rb +++ b/spec/inputs/url_input_spec.rb @@ -42,6 +42,34 @@ end + describe "when index is provided" do + + before do + @output_buffer = '' + mock_everything + + concat(semantic_form_for(@new_post) do |builder| + concat(builder.fields_for :author, :index => 3 do |author| + concat(author.input(:name, :as => :url)) + end) + end) + end + + it 'should index the id of the wrapper' do + output_buffer.should have_tag("li#post_author_attributes_3_name_input") + end + + it 'should index the id of the select tag' do + output_buffer.should have_tag("input#post_author_attributes_3_name") + end + + it 'should index the name of the select tag' do + output_buffer.should have_tag("input[@name='post[author_attributes][3][name]']") + end + + end + + describe "when required" do it "should add the required attribute to the input's html options" do with_config :use_required_attribute, true do From 0566774dba3419edcea97a54f022d8e62f65e351 Mon Sep 17 00:00:00 2001 From: Joe Slag Date: Thu, 27 Oct 2011 11:34:38 -0500 Subject: [PATCH 07/15] address syntax errors with 1.9.2-p290 The syntax introduced in 253dc6d559b610f04fab1bc43209d6caa0603d30, eg. concat(builder.fields_for :author, :index => 3 do |author| was producing these errors: syntax error, unexpected keyword_do_block, expecting ')' (SyntaxError) --- spec/inputs/boolean_input_spec.rb | 2 +- spec/inputs/check_boxes_input_spec.rb | 2 +- spec/inputs/date_input_spec.rb | 2 +- spec/inputs/datetime_input_spec.rb | 2 +- spec/inputs/email_input_spec.rb | 2 +- spec/inputs/file_input_spec.rb | 2 +- spec/inputs/hidden_input_spec.rb | 2 +- spec/inputs/number_input_spec.rb | 2 +- spec/inputs/password_input_spec.rb | 2 +- spec/inputs/phone_input_spec.rb | 2 +- spec/inputs/radio_input_spec.rb | 2 +- spec/inputs/range_input_spec.rb | 2 +- spec/inputs/search_input_spec.rb | 2 +- spec/inputs/select_input_spec.rb | 2 +- spec/inputs/string_input_spec.rb | 2 +- spec/inputs/text_input_spec.rb | 2 +- spec/inputs/time_input_spec.rb | 2 +- spec/inputs/time_zone_input_spec.rb | 2 +- spec/inputs/url_input_spec.rb | 2 +- 19 files changed, 19 insertions(+), 19 deletions(-) diff --git a/spec/inputs/boolean_input_spec.rb b/spec/inputs/boolean_input_spec.rb index a343b4bcb..c0e62bb8d 100644 --- a/spec/inputs/boolean_input_spec.rb +++ b/spec/inputs/boolean_input_spec.rb @@ -192,7 +192,7 @@ mock_everything concat(semantic_form_for(@new_post) do |builder| - concat(builder.fields_for :author, :index => 3 do |author| + concat(builder.fields_for(:author, :index => 3) do |author| concat(author.input(:name, :as => :boolean)) end) end) diff --git a/spec/inputs/check_boxes_input_spec.rb b/spec/inputs/check_boxes_input_spec.rb index 86aed8146..04530268f 100644 --- a/spec/inputs/check_boxes_input_spec.rb +++ b/spec/inputs/check_boxes_input_spec.rb @@ -400,7 +400,7 @@ mock_everything concat(semantic_form_for(@fred) do |builder| - concat(builder.fields_for @fred.posts.first, :index => 3 do |author| + concat(builder.fields_for(@fred.posts.first, :index => 3) do |author| concat(author.input(:authors, :as => :check_boxes)) end) end) diff --git a/spec/inputs/date_input_spec.rb b/spec/inputs/date_input_spec.rb index 19f4218ab..a7323a3ce 100644 --- a/spec/inputs/date_input_spec.rb +++ b/spec/inputs/date_input_spec.rb @@ -78,7 +78,7 @@ mock_everything concat(semantic_form_for(@new_post) do |builder| - concat(builder.fields_for :author, :index => 3 do |author| + concat(builder.fields_for(:author, :index => 3) do |author| concat(author.input(:created_at, :as => :date)) end) end) diff --git a/spec/inputs/datetime_input_spec.rb b/spec/inputs/datetime_input_spec.rb index ab39e0d50..105525257 100644 --- a/spec/inputs/datetime_input_spec.rb +++ b/spec/inputs/datetime_input_spec.rb @@ -83,7 +83,7 @@ mock_everything concat(semantic_form_for(@new_post) do |builder| - concat(builder.fields_for :author, :index => 3 do |author| + concat(builder.fields_for(:author, :index => 3) do |author| concat(author.input(:created_at, :as => :datetime)) end) end) diff --git a/spec/inputs/email_input_spec.rb b/spec/inputs/email_input_spec.rb index e5a2bc098..03f1eb3ed 100644 --- a/spec/inputs/email_input_spec.rb +++ b/spec/inputs/email_input_spec.rb @@ -49,7 +49,7 @@ mock_everything concat(semantic_form_for(@new_post) do |builder| - concat(builder.fields_for :author, :index => 3 do |author| + concat(builder.fields_for(:author, :index => 3) do |author| concat(author.input(:name, :as => :email)) end) end) diff --git a/spec/inputs/file_input_spec.rb b/spec/inputs/file_input_spec.rb index 6dfc003a9..2eb2db67a 100644 --- a/spec/inputs/file_input_spec.rb +++ b/spec/inputs/file_input_spec.rb @@ -53,7 +53,7 @@ mock_everything concat(semantic_form_for(@new_post) do |builder| - concat(builder.fields_for :author, :index => 3 do |author| + concat(builder.fields_for(:author, :index => 3) do |author| concat(author.input(:name, :as => :file)) end) end) diff --git a/spec/inputs/hidden_input_spec.rb b/spec/inputs/hidden_input_spec.rb index 0ffc7c1cb..24d796cc4 100644 --- a/spec/inputs/hidden_input_spec.rb +++ b/spec/inputs/hidden_input_spec.rb @@ -105,7 +105,7 @@ mock_everything concat(semantic_form_for(@new_post) do |builder| - concat(builder.fields_for :author, :index => 3 do |author| + concat(builder.fields_for(:author, :index => 3) do |author| concat(author.input(:name, :as => :hidden)) end) end) diff --git a/spec/inputs/number_input_spec.rb b/spec/inputs/number_input_spec.rb index b8d5ab9d1..6332d030d 100644 --- a/spec/inputs/number_input_spec.rb +++ b/spec/inputs/number_input_spec.rb @@ -73,7 +73,7 @@ mock_everything concat(semantic_form_for(@new_post) do |builder| - concat(builder.fields_for :author, :index => 3 do |author| + concat(builder.fields_for(:author, :index => 3) do |author| concat(author.input(:name, :as => :number)) end) end) diff --git a/spec/inputs/password_input_spec.rb b/spec/inputs/password_input_spec.rb index f21c8ac3d..1c82a6b69 100644 --- a/spec/inputs/password_input_spec.rb +++ b/spec/inputs/password_input_spec.rb @@ -64,7 +64,7 @@ mock_everything concat(semantic_form_for(@new_post) do |builder| - concat(builder.fields_for :author, :index => 3 do |author| + concat(builder.fields_for(:author, :index => 3) do |author| concat(author.input(:name, :as => :password)) end) end) diff --git a/spec/inputs/phone_input_spec.rb b/spec/inputs/phone_input_spec.rb index 8c4d21cc0..450f86f10 100644 --- a/spec/inputs/phone_input_spec.rb +++ b/spec/inputs/phone_input_spec.rb @@ -49,7 +49,7 @@ mock_everything concat(semantic_form_for(@new_post) do |builder| - concat(builder.fields_for :author, :index => 3 do |author| + concat(builder.fields_for(:author, :index => 3) do |author| concat(author.input(:name, :as => :phone)) end) end) diff --git a/spec/inputs/radio_input_spec.rb b/spec/inputs/radio_input_spec.rb index c69c31dcc..c479ac6f6 100644 --- a/spec/inputs/radio_input_spec.rb +++ b/spec/inputs/radio_input_spec.rb @@ -241,7 +241,7 @@ mock_everything concat(semantic_form_for(@new_post) do |builder| - concat(builder.fields_for :author, :index => 3 do |author| + concat(builder.fields_for(:author, :index => 3) do |author| concat(author.input(:name, :as => :radio)) end) end) diff --git a/spec/inputs/range_input_spec.rb b/spec/inputs/range_input_spec.rb index 5a484f126..35b1d4b52 100644 --- a/spec/inputs/range_input_spec.rb +++ b/spec/inputs/range_input_spec.rb @@ -49,7 +49,7 @@ mock_everything concat(semantic_form_for(@new_post) do |builder| - concat(builder.fields_for :author, :index => 3 do |author| + concat(builder.fields_for(:author, :index => 3) do |author| concat(author.input(:name, :as => :range)) end) end) diff --git a/spec/inputs/search_input_spec.rb b/spec/inputs/search_input_spec.rb index 8db394b42..eeb86596c 100644 --- a/spec/inputs/search_input_spec.rb +++ b/spec/inputs/search_input_spec.rb @@ -49,7 +49,7 @@ mock_everything concat(semantic_form_for(@new_post) do |builder| - concat(builder.fields_for :author, :index => 3 do |author| + concat(builder.fields_for(:author, :index => 3) do |author| concat(author.input(:name, :as => :search)) end) end) diff --git a/spec/inputs/select_input_spec.rb b/spec/inputs/select_input_spec.rb index e91b4e088..a68d87286 100644 --- a/spec/inputs/select_input_spec.rb +++ b/spec/inputs/select_input_spec.rb @@ -568,7 +568,7 @@ mock_everything concat(semantic_form_for(@new_post) do |builder| - concat(builder.fields_for :author, :index => 3 do |author| + concat(builder.fields_for(:author, :index => 3) do |author| concat(author.input(:name, :as => :select)) end) end) diff --git a/spec/inputs/string_input_spec.rb b/spec/inputs/string_input_spec.rb index c9ea0a645..633188c61 100644 --- a/spec/inputs/string_input_spec.rb +++ b/spec/inputs/string_input_spec.rb @@ -131,7 +131,7 @@ def should_have_maxlength(maxlength, options) mock_everything concat(semantic_form_for(@new_post) do |builder| - concat(builder.fields_for :author, :index => 3 do |author| + concat(builder.fields_for(:author, :index => 3) do |author| concat(author.input(:name, :as => :string)) end) end) diff --git a/spec/inputs/text_input_spec.rb b/spec/inputs/text_input_spec.rb index 2e369560d..b15823099 100644 --- a/spec/inputs/text_input_spec.rb +++ b/spec/inputs/text_input_spec.rb @@ -88,7 +88,7 @@ mock_everything concat(semantic_form_for(@new_post) do |builder| - concat(builder.fields_for :author, :index => 3 do |author| + concat(builder.fields_for(:author, :index => 3) do |author| concat(author.input(:name, :as => :text)) end) end) diff --git a/spec/inputs/time_input_spec.rb b/spec/inputs/time_input_spec.rb index 70c41a4f5..752c13b16 100644 --- a/spec/inputs/time_input_spec.rb +++ b/spec/inputs/time_input_spec.rb @@ -202,7 +202,7 @@ before do concat(semantic_form_for(@new_post) do |builder| - concat(builder.fields_for :author, :index => 3 do |author| + concat(builder.fields_for(:author, :index => 3) do |author| concat(author.input(:created_at, :as => :time)) end) end) diff --git a/spec/inputs/time_zone_input_spec.rb b/spec/inputs/time_zone_input_spec.rb index c644757e9..1b93c49ca 100644 --- a/spec/inputs/time_zone_input_spec.rb +++ b/spec/inputs/time_zone_input_spec.rb @@ -62,7 +62,7 @@ mock_everything concat(semantic_form_for(@new_post) do |builder| - concat(builder.fields_for :author, :index => 3 do |author| + concat(builder.fields_for(:author, :index => 3) do |author| concat(author.input(:name, :as => :time_zone)) end) end) diff --git a/spec/inputs/url_input_spec.rb b/spec/inputs/url_input_spec.rb index 82cceb8f0..bc4931217 100644 --- a/spec/inputs/url_input_spec.rb +++ b/spec/inputs/url_input_spec.rb @@ -49,7 +49,7 @@ mock_everything concat(semantic_form_for(@new_post) do |builder| - concat(builder.fields_for :author, :index => 3 do |author| + concat(builder.fields_for(:author, :index => 3) do |author| concat(author.input(:name, :as => :url)) end) end) From 617ef956b68b8c3292c44a5782c2365e3513a207 Mon Sep 17 00:00:00 2001 From: Joe Slag Date: Thu, 27 Oct 2011 13:57:49 -0500 Subject: [PATCH 08/15] Support empty Time inputs Before this change, it wasn't possible to create an input of type 'time' that didn't default to the current date. This made it impossible to differentiate between a form submission wherein the user hadn't picked a date, and one in which they'd picked midnight UTC. --- lib/formtastic/inputs/time_input.rb | 8 ++------ spec/inputs/time_input_spec.rb | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/lib/formtastic/inputs/time_input.rb b/lib/formtastic/inputs/time_input.rb index 65e6165f9..ddf595f49 100644 --- a/lib/formtastic/inputs/time_input.rb +++ b/lib/formtastic/inputs/time_input.rb @@ -15,12 +15,8 @@ def fragments time_fragments end - def value_or_default_value - value ? value : Time.current - end - def fragment_value(fragment) - value_or_default_value.send(fragment) + value ? value.send(fragment) : "" end def hidden_fragments @@ -43,4 +39,4 @@ def hidden_field_name(fragment) end end -end \ No newline at end of file +end diff --git a/spec/inputs/time_input_spec.rb b/spec/inputs/time_input_spec.rb index 752c13b16..c82a7c3cb 100644 --- a/spec/inputs/time_input_spec.rb +++ b/spec/inputs/time_input_spec.rb @@ -60,6 +60,33 @@ end + describe "with :ignore_date => false and no initial Time" do + before do + @new_post.stub(:publish_at) + concat(semantic_form_for(@new_post) do |builder| + concat(builder.input(:publish_at, :as => :time, :ignore_date => false)) + end) + end + + it 'should have a hidden input for day, month and year' do + output_buffer.should have_tag('input#post_publish_at_1i') + output_buffer.should have_tag('input#post_publish_at_2i') + output_buffer.should have_tag('input#post_publish_at_3i') + end + + it 'should not have values in hidden inputs for day, month and year' do + output_buffer.should have_tag('input#post_publish_at_1i[@value=""]') + output_buffer.should have_tag('input#post_publish_at_2i[@value=""]') + output_buffer.should have_tag('input#post_publish_at_3i[@value=""]') + end + + it 'should have an select for hour and minute' do + output_buffer.should have_tag('select#post_publish_at_4i') + output_buffer.should have_tag('select#post_publish_at_5i') + end + + end + describe "without seconds" do before do concat(semantic_form_for(@new_post) do |builder| From 9ead0e99406b8faf3a7624fadd803e1997f7a337 Mon Sep 17 00:00:00 2001 From: Joel Nimety Date: Wed, 2 Nov 2011 16:52:27 -0400 Subject: [PATCH 09/15] calculate length of integer columns as bytes Signed-off-by: Joel Nimety --- lib/formtastic/inputs/base/validations.rb | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/formtastic/inputs/base/validations.rb b/lib/formtastic/inputs/base/validations.rb index ddc3abeb6..014be7de7 100644 --- a/lib/formtastic/inputs/base/validations.rb +++ b/lib/formtastic/inputs/base/validations.rb @@ -183,7 +183,14 @@ def autofocus? end def column_limit - column.limit if column? && column.respond_to?(:limit) + if column? && column.respond_to?(:limit) + case column.type + when :integer + (2 ** (column.limit * 8)).to_s.length + 1 + else + column.limit + end + end end def limit From 1bc9fabe3daac87dad16d277eeb4fbbc003fc76f Mon Sep 17 00:00:00 2001 From: Justin French Date: Thu, 3 Nov 2011 20:22:34 +1100 Subject: [PATCH 10/15] passing spec related to #714 --- spec/builder/semantic_fields_for_spec.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/spec/builder/semantic_fields_for_spec.rb b/spec/builder/semantic_fields_for_spec.rb index d78d657f0..3bae0489a 100644 --- a/spec/builder/semantic_fields_for_spec.rb +++ b/spec/builder/semantic_fields_for_spec.rb @@ -98,6 +98,20 @@ end) output_buffer.should have_tag('form fieldset.inputs #context2_post_author_1_login_input') end + + it 'should render errors on the nested inputs' do + @errors = mock('errors') + @errors.stub!(:[]).with(:login).and_return(['oh noes']) + @bob.stub!(:errors).and_return(@errors) + + concat(semantic_form_for(@new_post, :namespace => 'context2') do |builder| + concat(builder.semantic_fields_for(@bob) do |nested_builder| + concat(nested_builder.inputs(:login)) + end) + end) + output_buffer.should =~ /oh noes/ + end + end context "when I rendered my own hidden id input" do From 4df91fc12f1b4799eb5f7c64f6afd7e56c723ef9 Mon Sep 17 00:00:00 2001 From: Kacper Bielecki Date: Mon, 7 Nov 2011 12:37:39 +0100 Subject: [PATCH 11/15] Documentation update: :include_blank option should be passed outside of :input_html option in order to take effect while using f.input :as => :select. --- lib/formtastic/inputs/select_input.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/formtastic/inputs/select_input.rb b/lib/formtastic/inputs/select_input.rb index f8f9fe5a3..41c81e997 100644 --- a/lib/formtastic/inputs/select_input.rb +++ b/lib/formtastic/inputs/select_input.rb @@ -122,8 +122,8 @@ module Inputs # <%= f.input :authors, :as => :select, :wrapper_html => { :class => "special" } %> # # @example Exclude or include the blank option at the top of the select, or change the prompt - # <%= f.input :author, :as => :select, :input_html => { :include_blank => false } %> - # <%= f.input :author, :as => :select, :input_html => { :include_blank => true } %> + # <%= f.input :author, :as => :select, :include_blank => false %> + # <%= f.input :author, :as => :select, :include_blank => true %> # <%= f.input :author, :as => :select, :input_html => { :prompt => "Please select an Author..." } %> # # @example Group options an `` with the `:group_by` and `:group_label` options (`belongs_to` associations only) From 7804a9fe14dd7cfe52418fe6b255a6529097c98e Mon Sep 17 00:00:00 2001 From: Bradley Priest Date: Tue, 8 Nov 2011 21:43:47 +1300 Subject: [PATCH 12/15] Fixed up the documentation for text_input --- lib/formtastic/inputs/text_input.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/formtastic/inputs/text_input.rb b/lib/formtastic/inputs/text_input.rb index e81db24d7..11491694d 100644 --- a/lib/formtastic/inputs/text_input.rb +++ b/lib/formtastic/inputs/text_input.rb @@ -9,16 +9,16 @@ module Inputs # # <%= semantic_form_for(@user) do |f| %> # <%= f.inputs do %> - # <%= f.input :first_name, :as => :string %> + # <%= f.input :first_name, :as => :text %> # <% end %> # <% end %> # # #
#
    - #
  1. + #
  2. # - # + # #
  3. #
#
From 9632dbedb25d6470b8b1aba61469770e4d461715 Mon Sep 17 00:00:00 2001 From: Matt Burke Date: Wed, 9 Nov 2011 12:08:39 -0500 Subject: [PATCH 13/15] Demonstrate a problem when using with_options. A failing test. --- spec/inputs/with_options_spec.rb | 43 ++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 spec/inputs/with_options_spec.rb diff --git a/spec/inputs/with_options_spec.rb b/spec/inputs/with_options_spec.rb new file mode 100644 index 000000000..0a34dd837 --- /dev/null +++ b/spec/inputs/with_options_spec.rb @@ -0,0 +1,43 @@ +# encoding: utf-8 +require 'spec_helper' + +describe 'string input' do + + include FormtasticSpecHelper + + before do + @output_buffer = '' + mock_everything + end + + describe "with_options and :wrapper_html" do + before do + concat(semantic_form_for(@new_post) do |builder| + builder.with_options :wrapper_html => { :class => ['extra'] } do |opt_builder| + concat(opt_builder.input(:title, :as => :string)) + concat(opt_builder.input(:author, :as => :radio)) + end + end) + end + + it "should have extra class on title" do + output_buffer.should have_tag("form li#post_title_input.extra") + end + it "should have title as string" do + output_buffer.should have_tag("form li#post_title_input.string") + end + it "should not have title as radio" do + output_buffer.should_not have_tag("form li#post_title_input.radio") + end + + it "should have extra class on author" do + output_buffer.should have_tag("form li#post_author_input.extra") + end + it "should not have author as string" do + output_buffer.should_not have_tag("form li#post_author_input.string") + end + it "should have author as radio" do + output_buffer.should have_tag("form li#post_author_input.radio") + end + end +end From f34c6c4ff5b4551aaa7eb61a62ad14e2b288a7eb Mon Sep 17 00:00:00 2001 From: Matt Burke Date: Wed, 9 Nov 2011 12:13:17 -0500 Subject: [PATCH 14/15] Clone wrapper_html options before modifying it. A passing test. --- lib/formtastic/inputs/base/wrapping.rb | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/formtastic/inputs/base/wrapping.rb b/lib/formtastic/inputs/base/wrapping.rb index fcfff13db..be897162e 100644 --- a/lib/formtastic/inputs/base/wrapping.rb +++ b/lib/formtastic/inputs/base/wrapping.rb @@ -14,9 +14,16 @@ def input_wrapping(&block) end def wrapper_html_options - opts = options[:wrapper_html] || {} - opts[:class] ||= [] - opts[:class] = [opts[:class].to_s] unless opts[:class].is_a?(Array) + opts = (options[:wrapper_html] || {}).dup + opts[:class] = + case opts[:class] + when Array + opts[:class].dup + when nil + [] + else + [opts[:class].to_s] + end opts[:class] << as opts[:class] << "input" opts[:class] << "error" if errors? From a09a6db9b3f1fab5185a4a0ee8c67ebafdb00b9b Mon Sep 17 00:00:00 2001 From: Russell Garner Date: Fri, 11 Nov 2011 12:32:16 +0000 Subject: [PATCH 15/15] Fix for #740 - Mongoid belongs_to select raises NoMethodError and always returns empty results --- lib/formtastic/inputs/base/collections.rb | 13 +++++++++---- spec/spec_helper.rb | 16 +++++++++++++++- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/lib/formtastic/inputs/base/collections.rb b/lib/formtastic/inputs/base/collections.rb index 7317324c7..884127521 100644 --- a/lib/formtastic/inputs/base/collections.rb +++ b/lib/formtastic/inputs/base/collections.rb @@ -54,18 +54,23 @@ def collection_from_options def collection_from_association if reflection - raise PolymorphicInputWithoutCollectionError.new("A collection must be supplied for #{method} input. Collections cannot be guessed for polymorphic associations.") if reflection.options && reflection.options[:polymorphic] == true + if reflection.respond_to?(:options) + raise PolymorphicInputWithoutCollectionError.new( + "A collection must be supplied for #{method} input. Collections cannot be guessed for polymorphic associations." + ) if reflection.options[:polymorphic] == true + end find_options_from_options = options[:find_options] || {} conditions_from_options = find_options_from_options[:conditions] || {} - conditions_from_reflection = reflection.options && reflection.options[:conditions] || {} + conditions_from_reflection = (reflection.respond_to?(:options) && reflection.options[:conditions]) || {} conditions_from_reflection = conditions_from_reflection.call if conditions_from_reflection.is_a?(Proc) + scope_conditions = conditions_from_reflection.empty? ? nil : {:conditions => conditions_from_reflection} if conditions_from_options.any? - reflection.klass.scoped(:conditions => conditions_from_reflection).where(conditions_from_options) + reflection.klass.scoped(scope_conditions).where(conditions_from_options) else find_options_from_options.merge!(:include => group_by) if self.respond_to?(:group_by) && group_by - reflection.klass.scoped(:conditions => conditions_from_reflection).where(find_options_from_options) + reflection.klass.scoped(scope_conditions).where(find_options_from_options) end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 3e5b9c971..c2625f759 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -137,6 +137,18 @@ class ::PostModel include ActiveModel::Conversion if defined?(ActiveModel::Conversion) end + ## + # We can't mock :respond_to?, so we need a concrete class override + class ::MongoidReflectionMock < RSpec::Mocks::Mock + def initialize(name=nil, stubs_and_options={}) + super name, stubs_and_options + end + + def respond_to?(sym) + sym == :options ? false : super + end + end + def _routes url_helpers = mock('url_helpers') url_helpers.stub!(:hash_for_posts_path).and_return({}) @@ -282,7 +294,9 @@ def new_author_path(*args); "/authors/new"; end when :main_post mock('reflection', :options => {}, :klass => ::Post, :macro => :belongs_to) when :mongoid_reviewer - mock('reflection', :options => nil, :klass => ::Author, :macro => :referenced_in, :foreign_key => "reviewer_id") # custom id + ::MongoidReflectionMock.new('reflection', + :options => Proc.new { raise NoMethodError, "Mongoid has no reflection.options" }, + :klass => ::Author, :macro => :referenced_in, :foreign_key => "reviewer_id") # custom id end end ::Post.stub!(:find).and_return([@freds_post])