<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -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=&quot;selected&quot;' if option_value_selected?(value, selected)
-          options &lt;&lt; %(&lt;option value=&quot;#{html_escape(value.to_s)}&quot;#{selected_attribute}&gt;#{html_escape(text.to_s)}&lt;/option&gt;)
+          disabled_attribute = ' disabled=&quot;disabled&quot;' if disabled &amp;&amp; option_value_selected?(value, disabled)
+          options &lt;&lt; %(&lt;option value=&quot;#{html_escape(value.to_s)}&quot;#{selected_attribute}#{disabled_attribute}&gt;#{html_escape(text.to_s)}&lt;/option&gt;)
         end
 
         options_for_select.join(&quot;\n&quot;)
@@ -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 &lt;tt&gt;&lt;option&gt;&lt;/tt&gt; tags, like &lt;tt&gt;options_from_collection_for_select&lt;/tt&gt;, 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(&quot;select&quot;, add_options(options_for_select(choices, selected_value), options, selected_value), html_options)
+        disabled_value = options.has_key?(:disabled) ? options[:disabled] : nil
+        content_tag(&quot;select&quot;, add_options(options_for_select(choices, :selected =&gt; selected_value, :disabled =&gt; 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(
-          &quot;select&quot;, add_options(options_from_collection_for_select(collection, value_method, text_method, selected_value), options, value), html_options
+          &quot;select&quot;, add_options(options_from_collection_for_select(collection, value_method, text_method, :selected =&gt; selected_value, :disabled =&gt; disabled_value), options, value), html_options
         )
       end
 </diff>
      <filename>actionpack/lib/action_view/helpers/form_options_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -45,6 +45,41 @@ class FormOptionsHelperTest &lt; ActionView::TestCase
       )
   end
 
+  def test_collection_options_with_proc_for_selected
+    assert_dom_equal(
+      &quot;&lt;option value=\&quot;&amp;lt;Abe&amp;gt;\&quot;&gt;&amp;lt;Abe&amp;gt; went home&lt;/option&gt;\n&lt;option value=\&quot;Babe\&quot; selected=\&quot;selected\&quot;&gt;Babe went home&lt;/option&gt;\n&lt;option value=\&quot;Cabe\&quot;&gt;Cabe went home&lt;/option&gt;&quot;,
+      options_from_collection_for_select(dummy_posts, &quot;author_name&quot;, &quot;title&quot;, lambda{|p| p.author_name == 'Babe' })
+    )
+  end
+
+  def test_collection_options_with_disabled_value
+    assert_dom_equal(
+      &quot;&lt;option value=\&quot;&amp;lt;Abe&amp;gt;\&quot;&gt;&amp;lt;Abe&amp;gt; went home&lt;/option&gt;\n&lt;option value=\&quot;Babe\&quot; disabled=\&quot;disabled\&quot;&gt;Babe went home&lt;/option&gt;\n&lt;option value=\&quot;Cabe\&quot;&gt;Cabe went home&lt;/option&gt;&quot;,
+      options_from_collection_for_select(dummy_posts, &quot;author_name&quot;, &quot;title&quot;, :disabled =&gt; &quot;Babe&quot;)
+    )
+  end
+
+  def test_collection_options_with_disabled_array
+    assert_dom_equal(
+      &quot;&lt;option value=\&quot;&amp;lt;Abe&amp;gt;\&quot;&gt;&amp;lt;Abe&amp;gt; went home&lt;/option&gt;\n&lt;option value=\&quot;Babe\&quot; disabled=\&quot;disabled\&quot;&gt;Babe went home&lt;/option&gt;\n&lt;option value=\&quot;Cabe\&quot; disabled=\&quot;disabled\&quot;&gt;Cabe went home&lt;/option&gt;&quot;,
+      options_from_collection_for_select(dummy_posts, &quot;author_name&quot;, &quot;title&quot;, :disabled =&gt; [ &quot;Babe&quot;, &quot;Cabe&quot; ])
+    )
+  end
+
+  def test_collection_options_with_preselected_and_disabled_value
+    assert_dom_equal(
+      &quot;&lt;option value=\&quot;&amp;lt;Abe&amp;gt;\&quot;&gt;&amp;lt;Abe&amp;gt; went home&lt;/option&gt;\n&lt;option value=\&quot;Babe\&quot; disabled=\&quot;disabled\&quot;&gt;Babe went home&lt;/option&gt;\n&lt;option value=\&quot;Cabe\&quot; selected=\&quot;selected\&quot;&gt;Cabe went home&lt;/option&gt;&quot;,
+      options_from_collection_for_select(dummy_posts, &quot;author_name&quot;, &quot;title&quot;, :selected =&gt; &quot;Cabe&quot;, :disabled =&gt; &quot;Babe&quot;)
+    )
+  end
+
+  def test_collection_options_with_proc_for_disabled
+    assert_dom_equal(
+      &quot;&lt;option value=\&quot;&amp;lt;Abe&amp;gt;\&quot;&gt;&amp;lt;Abe&amp;gt; went home&lt;/option&gt;\n&lt;option value=\&quot;Babe\&quot; disabled=\&quot;disabled\&quot;&gt;Babe went home&lt;/option&gt;\n&lt;option value=\&quot;Cabe\&quot; disabled=\&quot;disabled\&quot;&gt;Cabe went home&lt;/option&gt;&quot;,
+      options_from_collection_for_select(dummy_posts, &quot;author_name&quot;, &quot;title&quot;, :disabled =&gt; lambda{|p| %w(Babe Cabe).include? p.author_name })
+    )
+  end
+
   def test_array_options_for_select
     assert_dom_equal(
       &quot;&lt;option value=\&quot;&amp;lt;Denmark&amp;gt;\&quot;&gt;&amp;lt;Denmark&amp;gt;&lt;/option&gt;\n&lt;option value=\&quot;USA\&quot;&gt;USA&lt;/option&gt;\n&lt;option value=\&quot;Sweden\&quot;&gt;Sweden&lt;/option&gt;&quot;,
@@ -66,6 +101,27 @@ class FormOptionsHelperTest &lt; ActionView::TestCase
       )
   end
 
+  def test_array_options_for_select_with_disabled_value
+    assert_dom_equal(
+      &quot;&lt;option value=\&quot;Denmark\&quot;&gt;Denmark&lt;/option&gt;\n&lt;option value=\&quot;&amp;lt;USA&amp;gt;\&quot; disabled=\&quot;disabled\&quot;&gt;&amp;lt;USA&amp;gt;&lt;/option&gt;\n&lt;option value=\&quot;Sweden\&quot;&gt;Sweden&lt;/option&gt;&quot;,
+      options_for_select([ &quot;Denmark&quot;, &quot;&lt;USA&gt;&quot;, &quot;Sweden&quot; ], :disabled =&gt; &quot;&lt;USA&gt;&quot;)
+    )
+  end
+
+  def test_array_options_for_select_with_disabled_array
+    assert_dom_equal(
+      &quot;&lt;option value=\&quot;Denmark\&quot;&gt;Denmark&lt;/option&gt;\n&lt;option value=\&quot;&amp;lt;USA&amp;gt;\&quot; disabled=\&quot;disabled\&quot;&gt;&amp;lt;USA&amp;gt;&lt;/option&gt;\n&lt;option value=\&quot;Sweden\&quot; disabled=\&quot;disabled\&quot;&gt;Sweden&lt;/option&gt;&quot;,
+      options_for_select([ &quot;Denmark&quot;, &quot;&lt;USA&gt;&quot;, &quot;Sweden&quot; ], :disabled =&gt; [&quot;&lt;USA&gt;&quot;, &quot;Sweden&quot;])
+    )
+  end
+
+  def test_array_options_for_select_with_selection_and_disabled_value
+    assert_dom_equal(
+      &quot;&lt;option value=\&quot;Denmark\&quot; selected=\&quot;selected\&quot;&gt;Denmark&lt;/option&gt;\n&lt;option value=\&quot;&amp;lt;USA&amp;gt;\&quot; disabled=\&quot;disabled\&quot;&gt;&amp;lt;USA&amp;gt;&lt;/option&gt;\n&lt;option value=\&quot;Sweden\&quot;&gt;Sweden&lt;/option&gt;&quot;,
+      options_for_select([ &quot;Denmark&quot;, &quot;&lt;USA&gt;&quot;, &quot;Sweden&quot; ], :selected =&gt; &quot;Denmark&quot;, :disabled =&gt; &quot;&lt;USA&gt;&quot;)
+    )
+  end
+
   def test_array_options_for_string_include_in_other_string_bug_fix
       assert_dom_equal(
         &quot;&lt;option value=\&quot;ruby\&quot;&gt;ruby&lt;/option&gt;\n&lt;option value=\&quot;rubyonrails\&quot; selected=\&quot;selected\&quot;&gt;rubyonrails&lt;/option&gt;&quot;,
@@ -352,6 +408,24 @@ class FormOptionsHelperTest &lt; ActionView::TestCase
     )
   end
 
+  def test_select_with_disabled_value
+    @post = Post.new
+    @post.category = &quot;&lt;mus&gt;&quot;
+    assert_dom_equal(
+      &quot;&lt;select id=\&quot;post_category\&quot; name=\&quot;post[category]\&quot;&gt;&lt;option value=\&quot;abe\&quot;&gt;abe&lt;/option&gt;\n&lt;option value=\&quot;&amp;lt;mus&amp;gt;\&quot; selected=\&quot;selected\&quot;&gt;&amp;lt;mus&amp;gt;&lt;/option&gt;\n&lt;option value=\&quot;hest\&quot; disabled=\&quot;disabled\&quot;&gt;hest&lt;/option&gt;&lt;/select&gt;&quot;,
+      select(&quot;post&quot;, &quot;category&quot;, %w( abe &lt;mus&gt; hest ), :disabled =&gt; 'hest')
+    )
+  end
+
+  def test_select_with_disabled_array
+    @post = Post.new
+    @post.category = &quot;&lt;mus&gt;&quot;
+    assert_dom_equal(
+      &quot;&lt;select id=\&quot;post_category\&quot; name=\&quot;post[category]\&quot;&gt;&lt;option value=\&quot;abe\&quot; disabled=\&quot;disabled\&quot;&gt;abe&lt;/option&gt;\n&lt;option value=\&quot;&amp;lt;mus&amp;gt;\&quot; selected=\&quot;selected\&quot;&gt;&amp;lt;mus&amp;gt;&lt;/option&gt;\n&lt;option value=\&quot;hest\&quot; disabled=\&quot;disabled\&quot;&gt;hest&lt;/option&gt;&lt;/select&gt;&quot;,
+      select(&quot;post&quot;, &quot;category&quot;, %w( abe &lt;mus&gt; hest ), :disabled =&gt; ['hest', 'abe'])
+    )
+  end
+
   def test_collection_select
     @post = Post.new
     @post.author_name = &quot;Babe&quot;
@@ -448,6 +522,16 @@ class FormOptionsHelperTest &lt; ActionView::TestCase
     )
   end
 
+  def test_collection_select_with_disabled
+    @post = Post.new
+    @post.author_name = &quot;Babe&quot;
+
+    assert_dom_equal(
+      &quot;&lt;select id=\&quot;post_author_name\&quot; name=\&quot;post[author_name]\&quot;&gt;&lt;option value=\&quot;&amp;lt;Abe&amp;gt;\&quot;&gt;&amp;lt;Abe&amp;gt;&lt;/option&gt;\n&lt;option value=\&quot;Babe\&quot; selected=\&quot;selected\&quot;&gt;Babe&lt;/option&gt;\n&lt;option value=\&quot;Cabe\&quot; disabled=\&quot;disabled\&quot;&gt;Cabe&lt;/option&gt;&lt;/select&gt;&quot;,
+      collection_select(&quot;post&quot;, &quot;author_name&quot;, dummy_posts, &quot;author_name&quot;, &quot;author_name&quot;, :disabled =&gt; 'Cabe')
+       )
+  end
+
   def test_time_zone_select
     @firm = Firm.new(&quot;D&quot;)
     html = time_zone_select( &quot;firm&quot;, &quot;time_zone&quot; )</diff>
      <filename>actionpack/test/template/form_options_helper_test.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>d206b80a36d400a554f61ddb8a6ad33d6973fb13</id>
    </parent>
  </parents>
  <author>
    <name>Tekin Suleyman</name>
    <login>tekin</login>
    <email>tekin@tekin.co.uk</email>
  </author>
  <url>http://github.com/rails/rails/commit/1525f3816e9b51d93d2e1356d1b90ba49213d325</url>
  <id>1525f3816e9b51d93d2e1356d1b90ba49213d325</id>
  <committed-date>2009-02-13T17:51:35-08:00</committed-date>
  <authored-date>2009-02-13T16:37:24-08:00</authored-date>
  <message>Enhanced form option helpers to add support for disabled option tags and use of anonymous functions for specifying selected and disabled values from collections.

Signed-off-by: Michael Koziarski &lt;michael@koziarski.com&gt;</message>
  <tree>5c934272d2c99abd229ec3f4cd9a472d7520a107</tree>
  <committer>
    <name>Michael Koziarski</name>
    <login>NZKoz</login>
    <email>michael@koziarski.com</email>
  </committer>
</commit>
