From 67a045c289d62d433cea45a7cab2bde9ad996556 Mon Sep 17 00:00:00 2001 From: Tekin Suleyman Date: Sat, 14 Feb 2009 00:14:48 +0000 Subject: [PATCH] DRY up form option helper tests --- .../test/template/form_options_helper_test.rb | 97 ++++---------------- 1 files changed, 19 insertions(+), 78 deletions(-) diff --git a/actionpack/test/template/form_options_helper_test.rb b/actionpack/test/template/form_options_helper_test.rb index 83c27ac..8e60412 100644 --- a/actionpack/test/template/form_options_helper_test.rb +++ b/actionpack/test/template/form_options_helper_test.rb @@ -24,42 +24,24 @@ class FormOptionsHelperTest < ActionView::TestCase end def test_collection_options - @posts = [ - Post.new(" went home", "", "To a little house", "shh!"), - Post.new("Babe went home", "Babe", "To a little house", "shh!"), - Post.new("Cabe went home", "Cabe", "To a little house", "shh!") - ] - assert_dom_equal( "\n\n", - options_from_collection_for_select(@posts, "author_name", "title") + options_from_collection_for_select(dummy_posts, "author_name", "title") ) end def test_collection_options_with_preselected_value - @posts = [ - Post.new(" went home", "", "To a little house", "shh!"), - Post.new("Babe went home", "Babe", "To a little house", "shh!"), - Post.new("Cabe went home", "Cabe", "To a little house", "shh!") - ] - assert_dom_equal( "\n\n", - options_from_collection_for_select(@posts, "author_name", "title", "Babe") + options_from_collection_for_select(dummy_posts, "author_name", "title", "Babe") ) end def test_collection_options_with_preselected_value_array - @posts = [ - Post.new(" went home", "", "To a little house", "shh!"), - Post.new("Babe went home", "Babe", "To a little house", "shh!"), - Post.new("Cabe went home", "Cabe", "To a little house", "shh!") - ] - assert_dom_equal( "\n\n", - options_from_collection_for_select(@posts, "author_name", "title", [ "Babe", "Cabe" ]) + options_from_collection_for_select(dummy_posts, "author_name", "title", [ "Babe", "Cabe" ]) ) end @@ -371,33 +353,21 @@ class FormOptionsHelperTest < ActionView::TestCase end def test_collection_select - @posts = [ - Post.new(" went home", "", "To a little house", "shh!"), - Post.new("Babe went home", "Babe", "To a little house", "shh!"), - Post.new("Cabe went home", "Cabe", "To a little house", "shh!") - ] - @post = Post.new @post.author_name = "Babe" assert_dom_equal( "", - collection_select("post", "author_name", @posts, "author_name", "author_name") + collection_select("post", "author_name", dummy_posts, "author_name", "author_name") ) end def test_collection_select_under_fields_for - @posts = [ - Post.new(" went home", "", "To a little house", "shh!"), - Post.new("Babe went home", "Babe", "To a little house", "shh!"), - Post.new("Cabe went home", "Cabe", "To a little house", "shh!") - ] - @post = Post.new @post.author_name = "Babe" fields_for :post, @post do |f| - concat f.collection_select(:author_name, @posts, :author_name, :author_name) + concat f.collection_select(:author_name, dummy_posts, :author_name, :author_name) end assert_dom_equal( @@ -407,17 +377,11 @@ class FormOptionsHelperTest < ActionView::TestCase end def test_collection_select_under_fields_for_with_index - @posts = [ - Post.new(" went home", "", "To a little house", "shh!"), - Post.new("Babe went home", "Babe", "To a little house", "shh!"), - Post.new("Cabe went home", "Cabe", "To a little house", "shh!") - ] - @post = Post.new @post.author_name = "Babe" fields_for :post, @post, :index => 815 do |f| - concat f.collection_select(:author_name, @posts, :author_name, :author_name) + concat f.collection_select(:author_name, dummy_posts, :author_name, :author_name) end assert_dom_equal( @@ -427,18 +391,12 @@ class FormOptionsHelperTest < ActionView::TestCase end def test_collection_select_under_fields_for_with_auto_index - @posts = [ - Post.new(" went home", "", "To a little house", "shh!"), - Post.new("Babe went home", "Babe", "To a little house", "shh!"), - Post.new("Cabe went home", "Cabe", "To a little house", "shh!") - ] - @post = Post.new @post.author_name = "Babe" def @post.to_param; 815; end fields_for "post[]", @post do |f| - concat f.collection_select(:author_name, @posts, :author_name, :author_name) + concat f.collection_select(:author_name, dummy_posts, :author_name, :author_name) end assert_dom_equal( @@ -448,69 +406,45 @@ class FormOptionsHelperTest < ActionView::TestCase end def test_collection_select_with_blank_and_style - @posts = [ - Post.new(" went home", "", "To a little house", "shh!"), - Post.new("Babe went home", "Babe", "To a little house", "shh!"), - Post.new("Cabe went home", "Cabe", "To a little house", "shh!") - ] - @post = Post.new @post.author_name = "Babe" assert_dom_equal( "", - collection_select("post", "author_name", @posts, "author_name", "author_name", { :include_blank => true }, "style" => "width: 200px") + collection_select("post", "author_name", dummy_posts, "author_name", "author_name", { :include_blank => true }, "style" => "width: 200px") ) end def test_collection_select_with_blank_as_string_and_style - @posts = [ - Post.new(" went home", "", "To a little house", "shh!"), - Post.new("Babe went home", "Babe", "To a little house", "shh!"), - Post.new("Cabe went home", "Cabe", "To a little house", "shh!") - ] - @post = Post.new @post.author_name = "Babe" assert_dom_equal( "", - collection_select("post", "author_name", @posts, "author_name", "author_name", { :include_blank => 'No Selection' }, "style" => "width: 200px") + collection_select("post", "author_name", dummy_posts, "author_name", "author_name", { :include_blank => 'No Selection' }, "style" => "width: 200px") ) end def test_collection_select_with_multiple_option_appends_array_brackets - @posts = [ - Post.new(" went home", "", "To a little house", "shh!"), - Post.new("Babe went home", "Babe", "To a little house", "shh!"), - Post.new("Cabe went home", "Cabe", "To a little house", "shh!") - ] - @post = Post.new @post.author_name = "Babe" expected = "" # Should suffix default name with []. - assert_dom_equal expected, collection_select("post", "author_name", @posts, "author_name", "author_name", { :include_blank => true }, :multiple => true) + assert_dom_equal expected, collection_select("post", "author_name", dummy_posts, "author_name", "author_name", { :include_blank => true }, :multiple => true) # Shouldn't suffix custom name with []. - assert_dom_equal expected, collection_select("post", "author_name", @posts, "author_name", "author_name", { :include_blank => true, :name => 'post[author_name][]' }, :multiple => true) + assert_dom_equal expected, collection_select("post", "author_name", dummy_posts, "author_name", "author_name", { :include_blank => true, :name => 'post[author_name][]' }, :multiple => true) end def test_collection_select_with_blank_and_selected - @posts = [ - Post.new(" went home", "", "To a little house", "shh!"), - Post.new("Babe went home", "Babe", "To a little house", "shh!"), - Post.new("Cabe went home", "Cabe", "To a little house", "shh!") - ] - @post = Post.new @post.author_name = "Babe" assert_dom_equal( %{}, - collection_select("post", "author_name", @posts, "author_name", "author_name", {:include_blank => true, :selected => ""}) + collection_select("post", "author_name", dummy_posts, "author_name", "author_name", {:include_blank => true, :selected => ""}) ) end @@ -723,4 +657,11 @@ class FormOptionsHelperTest < ActionView::TestCase html end + private + + def dummy_posts + [ Post.new(" went home", "", "To a little house", "shh!"), + Post.new("Babe went home", "Babe", "To a little house", "shh!"), + Post.new("Cabe went home", "Cabe", "To a little house", "shh!") ] + end end -- 1.5.5.4 From d713cec798084a455accd2684c6f668235ff2e4a Mon Sep 17 00:00:00 2001 From: Tekin Suleyman Date: Sat, 14 Feb 2009 00:37:24 +0000 Subject: [PATCH] Enhanced form option helpers to add support for disabled option tags and use of anonymous functions for specifying selected and disabled values from collections. --- .../lib/action_view/helpers/form_options_helper.rb | 37 ++++++++- .../test/template/form_options_helper_test.rb | 84 ++++++++++++++++++++ 2 files changed, 116 insertions(+), 5 deletions(-) diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb index 54c82cb..4f4625d 100644 --- a/actionpack/lib/action_view/helpers/form_options_helper.rb +++ b/actionpack/lib/action_view/helpers/form_options_helper.rb @@ -189,11 +189,13 @@ module ActionView # NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag. def options_for_select(container, selected = nil) container = container.to_a if Hash === container - + selected, disabled = extract_selected_and_disabled(selected) + options_for_select = container.inject([]) do |options, element| text, value = option_text_and_value(element) selected_attribute = ' selected="selected"' if option_value_selected?(value, selected) - options << %() + disabled_attribute = ' disabled="disabled"' if disabled && option_value_selected?(value, disabled) + options << %() end options_for_select.join("\n") @@ -220,7 +222,12 @@ module ActionView options = collection.map do |element| [element.send(text_method), element.send(value_method)] end - options_for_select(options, selected) + selected, disabled = extract_selected_and_disabled(selected) + select_deselect = {} + select_deselect[:selected] = extract_values_from_collection(collection, value_method, selected) + select_deselect[:disabled] = extract_values_from_collection(collection, value_method, disabled) + + options_for_select(options, select_deselect) end # Returns a string of tags, like options_from_collection_for_select, but @@ -388,6 +395,24 @@ module ActionView value == selected end end + + def extract_selected_and_disabled(selected) + if selected.is_a?(Hash) + [selected[:selected], selected[:disabled]] + else + [selected, nil] + end + end + + def extract_values_from_collection(collection, value_method, selected) + if selected.is_a?(Proc) + collection.map do |element| + element.send(value_method) if selected.call(element) + end.compact + else + selected + end + end end class InstanceTag #:nodoc: @@ -398,16 +423,18 @@ module ActionView add_default_name_and_id(html_options) value = value(object) selected_value = options.has_key?(:selected) ? options[:selected] : value - content_tag("select", add_options(options_for_select(choices, selected_value), options, selected_value), html_options) + disabled_value = options.has_key?(:disabled) ? options[:disabled] : nil + content_tag("select", add_options(options_for_select(choices, :selected => selected_value, :disabled => disabled_value), options, selected_value), html_options) end def to_collection_select_tag(collection, value_method, text_method, options, html_options) html_options = html_options.stringify_keys add_default_name_and_id(html_options) value = value(object) + disabled_value = options.has_key?(:disabled) ? options[:disabled] : nil selected_value = options.has_key?(:selected) ? options[:selected] : value content_tag( - "select", add_options(options_from_collection_for_select(collection, value_method, text_method, selected_value), options, value), html_options + "select", add_options(options_from_collection_for_select(collection, value_method, text_method, :selected => selected_value, :disabled => disabled_value), options, value), html_options ) end diff --git a/actionpack/test/template/form_options_helper_test.rb b/actionpack/test/template/form_options_helper_test.rb index 8e60412..37ed61e 100644 --- a/actionpack/test/template/form_options_helper_test.rb +++ b/actionpack/test/template/form_options_helper_test.rb @@ -45,6 +45,41 @@ class FormOptionsHelperTest < ActionView::TestCase ) end + def test_collection_options_with_proc_for_selected + assert_dom_equal( + "\n\n", + options_from_collection_for_select(dummy_posts, "author_name", "title", lambda{|p| p.author_name == 'Babe' }) + ) + end + + def test_collection_options_with_disabled_value + assert_dom_equal( + "\n\n", + options_from_collection_for_select(dummy_posts, "author_name", "title", :disabled => "Babe") + ) + end + + def test_collection_options_with_disabled_array + assert_dom_equal( + "\n\n", + options_from_collection_for_select(dummy_posts, "author_name", "title", :disabled => [ "Babe", "Cabe" ]) + ) + end + + def test_collection_options_with_preselected_and_disabled_value + assert_dom_equal( + "\n\n", + options_from_collection_for_select(dummy_posts, "author_name", "title", :selected => "Cabe", :disabled => "Babe") + ) + end + + def test_collection_options_with_proc_for_disabled + assert_dom_equal( + "\n\n", + options_from_collection_for_select(dummy_posts, "author_name", "title", :disabled => lambda{|p| %w(Babe Cabe).include? p.author_name }) + ) + end + def test_array_options_for_select assert_dom_equal( "\n\n", @@ -66,6 +101,27 @@ class FormOptionsHelperTest < ActionView::TestCase ) end + def test_array_options_for_select_with_disabled_value + assert_dom_equal( + "\n\n", + options_for_select([ "Denmark", "", "Sweden" ], :disabled => "") + ) + end + + def test_array_options_for_select_with_disabled_array + assert_dom_equal( + "\n\n", + options_for_select([ "Denmark", "", "Sweden" ], :disabled => ["", "Sweden"]) + ) + end + + def test_array_options_for_select_with_selection_and_disabled_value + assert_dom_equal( + "\n\n", + options_for_select([ "Denmark", "", "Sweden" ], :selected => "Denmark", :disabled => "") + ) + end + def test_array_options_for_string_include_in_other_string_bug_fix assert_dom_equal( "\n", @@ -352,6 +408,24 @@ class FormOptionsHelperTest < ActionView::TestCase ) end + def test_select_with_disabled_value + @post = Post.new + @post.category = "" + assert_dom_equal( + "", + select("post", "category", %w( abe hest ), :disabled => 'hest') + ) + end + + def test_select_with_disabled_array + @post = Post.new + @post.category = "" + assert_dom_equal( + "", + select("post", "category", %w( abe hest ), :disabled => ['hest', 'abe']) + ) + end + def test_collection_select @post = Post.new @post.author_name = "Babe" @@ -448,6 +522,16 @@ class FormOptionsHelperTest < ActionView::TestCase ) end + def test_collection_select_with_disabled + @post = Post.new + @post.author_name = "Babe" + + assert_dom_equal( + "", + collection_select("post", "author_name", dummy_posts, "author_name", "author_name", :disabled => 'Cabe') + ) + end + def test_time_zone_select @firm = Firm.new("D") html = time_zone_select( "firm", "time_zone" ) -- 1.5.5.4 From f6af7e342371e4debf5b8257eb1b3359b508c546 Mon Sep 17 00:00:00 2001 From: Tekin Suleyman Date: Sat, 14 Feb 2009 00:47:22 +0000 Subject: [PATCH] Updated rdoc to reflect changes to form option helpers --- .../lib/action_view/helpers/form_options_helper.rb | 72 +++++++++++++++++--- 1 files changed, 61 insertions(+), 11 deletions(-) diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb index 4f4625d..a462e25 100644 --- a/actionpack/lib/action_view/helpers/form_options_helper.rb +++ b/actionpack/lib/action_view/helpers/form_options_helper.rb @@ -6,9 +6,7 @@ module ActionView module Helpers # Provides a number of methods for turning different kinds of containers into a set of option tags. # == Options - # The collection_select, country_select, select, - # and time_zone_select methods take an options parameter, - # a hash. + # The collection_select, select and time_zone_select methods take an options parameter, a hash: # # * :include_blank - set to true or a prompt string if the first option element of the select element is a blank. Useful if there is not a default value required for the select element. # @@ -28,7 +26,7 @@ module ActionView # # Example with @post.person_id => 2: # - # select("post", "person_id", Person.find(:all).collect {|p| [ p.name, p.id ] }, {:include_blank => 'None'}) + # select("post", "person_id", Person.all.collect {|p| [ p.name, p.id ] }, {:include_blank => 'None'}) # # could become: # @@ -43,7 +41,7 @@ module ActionView # # Example: # - # select("post", "person_id", Person.find(:all).collect {|p| [ p.name, p.id ] }, {:prompt => 'Select Person'}) + # select("post", "person_id", Person.all.collect {|p| [ p.name, p.id ] }, {:prompt => 'Select Person'}) # # could become: # @@ -68,6 +66,36 @@ module ActionView # # # + # + # * :disabled - can be a single value or an array of values that will be disabled options in the final output. + # + # Example: + # + # select("post", "category", Post::CATEGORIES, {:disabled => 'restricted'}) + # + # could become: + # + # + # + # When used with the collection_select helper, :disabled can also be a Proc that identifies those options that should be disabled. + # + # Example: + # + # collection_select(:post, :category_id, Category.all, :id, :name, {:disabled => lambda{|category| category.archived? }}) + # + # If the categories "2008 stuff" and "Christmas" return true when the method archived? is called, this would return: + # + # module FormOptionsHelper include ERB::Util @@ -76,7 +104,7 @@ module ActionView # See options_for_select for the required format of the choices parameter. # # Example with @post.person_id => 1: - # select("post", "person_id", Person.find(:all).collect {|p| [ p.name, p.id ] }, { :include_blank => true }) + # select("post", "person_id", Person.all.collect {|p| [ p.name, p.id ] }, { :include_blank => true }) # # could become: # @@ -94,7 +122,8 @@ module ActionView # In addition, this allows a single partial to be used to generate form inputs for both edit and create forms. # # By default, post.person_id is the selected option. Specify :selected => value to use a different selection - # or :selected => nil to leave all options unselected. + # or :selected => nil to leave all options unselected. Similarly, you can specify values to be disabled in the option + # tags by specifying the :disabled option. This can either be a single value or an array of values to be disabled. def select(object, method, choices, options = {}, html_options = {}) InstanceTag.new(object, method, self, options.delete(:object)).to_select_tag(choices, options, html_options) end @@ -120,7 +149,7 @@ module ActionView # end # # Sample usage (selecting the associated Author for an instance of Post, @post): - # collection_select(:post, :author_id, Author.find(:all), :id, :name_with_initial, {:prompt => true}) + # collection_select(:post, :author_id, Author.all, :id, :name_with_initial, {:prompt => true}) # # If @post.author_id is already 1, this would return: #