Skip to content

Commit

Permalink
Renamed (with backwards compatibility) and deprecation notices) :labe…
Browse files Browse the repository at this point in the history
…l_method => :member_label, :value_method => :member_value and :grouped_label_method => :grouped_label. Fixes #533.
  • Loading branch information
justinfrench committed May 4, 2011
1 parent 116d645 commit 454dd44
Show file tree
Hide file tree
Showing 13 changed files with 216 additions and 62 deletions.
2 changes: 1 addition & 1 deletion README.textile
Expand Up @@ -171,7 +171,7 @@ If you want to customize the label text, or render some hint text below the fiel
<% form.inputs :name => "Advanced Options", :id => "advanced" do %>
<%= form.input :slug, :label => "URL Title", :hint => "Created automatically if left blank", :required => false %>
<%= form.input :section, :as => :radio %>
<%= form.input :user, :label => "Author", :label_method => :full_name %>
<%= form.input :user, :label => "Author", :member_label => :full_name %>
<%= form.input :categories, :required => false %>
<%= form.input :created_at, :as => :string, :label => "Publication Date", :required => false %>
<% end %>
Expand Down
15 changes: 12 additions & 3 deletions lib/formtastic/helpers/input_helper.rb
Expand Up @@ -136,12 +136,18 @@ module InputHelper
# @option options :collection [Array<ActiveModel, String, Symbol>, Hash{String => String, Boolean}, OrderedHash{String => String, Boolean}]
# Override collection of objects in the association (`:select`, `:radio` & `:check_boxes` inputs only)
#
# @option options :label_method [Symbol, Proc, Method]
# @option options :member_label [Symbol, Proc, Method]
# Override the method called on each object in the `:collection` for use as the `<label>` content (`:check_boxes` & `:radio` inputs) or `<option>` content (`:select` inputs)
#
# @option options :value_method [Symbol, Proc, Method]
# @option options :label_method [Symbol, Proc, Method]
# Deprecated, renamed to :member_label
#
# @option options :member_value [Symbol, Proc, Method]
# Override the method called on each object in the `:collection` for use as the `value` attribute in the `<input>` (`:check_boxes` & `:radio` inputs) or `<option>` (`:select` inputs)
#
# @option options :value_method [Symbol, Proc, Method]
# Deprecated, renamed to :member_value
#
# @option options :hint_class [String]
# Override the `class` attribute applied to the `<p>` tag used when a `:hint` is rendered for an input
#
Expand All @@ -158,6 +164,9 @@ module InputHelper
# TODO will probably be deprecated
#
# @option options :group_label_method [Symbol]
# Deprecated, use `:group_label`
#
# @option options :group_label [Symbol]
# TODO will probably be deprecated
#
# @option options :include_blank [Boolean]
Expand All @@ -167,7 +176,7 @@ module InputHelper
# Specify the text in the first ('blank') `:select` input `<option>` to prompt a user to make a selection (implicitly sets `:include_blank` to `true`)
#
# @todo Can we kill `:hint_class` & `:error_class`? What's the use case for input-by-input? Shift to config or burn!
# @todo Can we kill `:group_by` & `:group_label_method`? Should be done with :collection => grouped_options_for_select(...)
# @todo Can we kill `:group_by` & `:group_label`/`:group_label_method`? Should be done with :collection => grouped_options_for_select(...)
# @todo Can we kill `:find_options`? Should be done with MyModel.some_scope.where(...).order(...).whatever_scope
# @todo Can we kill `:label`, `:hint` & `:prompt`? All strings could be shifted to i18n!
#
Expand Down
11 changes: 11 additions & 0 deletions lib/formtastic/inputs/base.rb
Expand Up @@ -11,6 +11,17 @@ def initialize(builder, template, object, object_name, method, options)
@object_name = object_name
@method = method
@options = options.dup

warn_and_correct_option!(:label_method, :member_label)
warn_and_correct_option!(:value_method, :member_value)
warn_and_correct_option!(:group_label_method, :group_label)
end

def warn_and_correct_option!(old_option_name, new_option_name)
if options.key?(old_option_name)
::ActiveSupport::Deprecation.warn("The :#{old_option_name} option is deprecated in favour of :#{new_option_name} and will be removed from Formtastic after 2.0")
options[new_option_name] = options.delete(old_option_name)
end
end

extend ActiveSupport::Autoload
Expand Down
6 changes: 3 additions & 3 deletions lib/formtastic/inputs/base/collections.rb
Expand Up @@ -24,8 +24,8 @@ def label_and_value_method(_collection, grouped=false)
end

# Order of preference: user supplied method, class defaults, auto-detect
label = (grouped ? options[:grouped_label_method] : options[:label_method]) || label || builder.collection_label_methods.find { |m| sample.respond_to?(m) }
value = (grouped ? options[:grouped_value_method] : options[:value_method]) || value || builder.collection_value_methods.find { |m| sample.respond_to?(m) }
label = (grouped ? options[:grouped_label_method] : options[:member_label]) || label || builder.collection_label_methods.find { |m| sample.respond_to?(m) }
value = (grouped ? options[:grouped_value_method] : options[:member_value]) || value || builder.collection_value_methods.find { |m| sample.respond_to?(m) }

[label, value]
end
Expand All @@ -41,7 +41,7 @@ def collection
# Return if we have an Array of strings, fixnums or arrays
return raw_collection if (raw_collection.instance_of?(Array) || raw_collection.instance_of?(Range)) &&
[Array, Fixnum, String, Symbol].include?(raw_collection.first.class) &&
!(options.include?(:label_method) || options.include?(:value_method))
!(options.include?(:member_label) || options.include?(:member_value))

raw_collection.map { |o| [send_or_call(label_method, o), send_or_call(value_method, o)] }
end
Expand Down
2 changes: 1 addition & 1 deletion lib/formtastic/inputs/base/grouped_collections.rb
Expand Up @@ -16,7 +16,7 @@ def group_label_method
end

def group_label_method_from_options
options[:group_label_method]
options[:group_label]
end

def group_label_method_from_grouped_collection
Expand Down
2 changes: 1 addition & 1 deletion lib/formtastic/inputs/base/options.rb
Expand Up @@ -8,7 +8,7 @@ def input_options
end

def formtastic_options
[:priority_countries, :priority_zones, :value_method, :label_method, :collection, :required, :label, :as, :hint, :input_html, :label_html, :value_as_class, :find_options, :class]
[:priority_countries, :priority_zones, :value_method, :label_method, :member_label, :member_value, :collection, :required, :label, :as, :hint, :input_html, :label_html, :value_as_class, :find_options, :class]
end

end
Expand Down
28 changes: 14 additions & 14 deletions lib/formtastic/inputs/check_boxes_input.rb
Expand Up @@ -52,23 +52,23 @@ module Inputs
# @example `:disabled` can be used to disable any checkboxes with a value found in the given Array
# <%= f.input :categories, :as => :check_boxes, :collection => ["a", "b"], :disabled => ["a"] %>
#
# @example `:label_method` can be used to call a different method (or a Proc) on each object in the collection for rendering the label text (it'll try the methods like `to_s` in `collection_label_methods` config by default)
# <%= f.input :categories, :as => :check_boxes, :label_method => :name %>
# <%= f.input :categories, :as => :check_boxes, :label_method => :name_with_post_count
# <%= f.input :categories, :as => :check_boxes, :label_method => { |c| "#{c.name} (#{pluralize("post", c.posts.count)})" }
# @example `:member_label` can be used to call a different method (or a Proc) on each object in the collection for rendering the label text (it'll try the methods like `to_s` in `collection_label_methods` config by default)
# <%= f.input :categories, :as => :check_boxes, :member_label => :name %>
# <%= f.input :categories, :as => :check_boxes, :member_label => :name_with_post_count
# <%= f.input :categories, :as => :check_boxes, :member_label => { |c| "#{c.name} (#{pluralize("post", c.posts.count)})" }
#
# @example `:label_method` can be used with a helper method (both examples have the same result)
# <%= f.input :categories, :as => :check_boxes, :label_method => method(:fancy_label)
# <%= f.input :categories, :as => :check_boxes, :label_method => Proc.new { |category| fancy_label(category) }
# @example `:member_label` can be used with a helper method (both examples have the same result)
# <%= f.input :categories, :as => :check_boxes, :member_label => method(:fancy_label)
# <%= f.input :categories, :as => :check_boxes, :member_label => Proc.new { |category| fancy_label(category) }
#
# @example `:value_method` can be used to call a different method (or a Proc) on each object in the collection for rendering the value for each checkbox (it'll try the methods like `id` in `collection_value_methods` config by default)
# <%= f.input :categories, :as => :check_boxes, :value_method => :code %>
# <%= f.input :categories, :as => :check_boxes, :value_method => :isbn
# <%= f.input :categories, :as => :check_boxes, :value_method => Proc.new { |c| c.name.downcase.underscore }
# @example `:member_value` can be used to call a different method (or a Proc) on each object in the collection for rendering the value for each checkbox (it'll try the methods like `id` in `collection_value_methods` config by default)
# <%= f.input :categories, :as => :check_boxes, :member_value => :code %>
# <%= f.input :categories, :as => :check_boxes, :member_value => :isbn
# <%= f.input :categories, :as => :check_boxes, :member_value => Proc.new { |c| c.name.downcase.underscore }
#
# @example `:value_method` can be used with a helper method (both examples have the same result)
# <%= f.input :categories, :as => :check_boxes, :value_method => method(:some_helper)
# <%= f.input :categories, :as => :check_boxes, :value_method => Proc.new { |category| some_helper(category) }
# @example `:member_value` can be used with a helper method (both examples have the same result)
# <%= f.input :categories, :as => :check_boxes, :member_value => method(:some_helper)
# <%= f.input :categories, :as => :check_boxes, :member_value => Proc.new { |category| some_helper(category) }
#
# @example `:value_as_class` can be used to add a class to the `<li>` wrapped around each choice using the checkbox value for custom styling of each choice
# <%= f.input :categories, :as => :check_boxes, :value_as_class => true %>
Expand Down
28 changes: 14 additions & 14 deletions lib/formtastic/inputs/radio_input.rb
Expand Up @@ -32,7 +32,7 @@ module Inputs
# You can override or customise this collection through the `:collection` option (see examples).
#
# The way on which Formtastic renders the `value` attribute and label for each choice is
# customisable through the `:label_method` and `:value_method` options (see examples below).
# customisable through the `:member_label` and `:member_value` options (see examples below).
# When not provided, we fall back to a list of methods to try on each object such as
# `:to_label`, `:name` and `:to_s`, which are defined in the configurations
# `collection_label_methods` and `collection_value_methods`.
Expand Down Expand Up @@ -85,22 +85,22 @@ module Inputs
# <%= f.input :author, :as => :radio, :collection => [["Justin", 1], ["Kate", 3]] %>
# <%= f.input :author, :as => :radio, :collection => 1..5 %>
#
# @example The `:label_method` can be used to call a different method (or a Proc) on each object in the collection for rendering the label text (it'll try the methods like `to_s` in `collection_label_methods` config by default)
# <%= f.input :author, :as => :radio, :label_method => :name %>
# <%= f.input :author, :as => :radio, :label_method => :name_with_post_count
# <%= f.input :author, :as => :radio, :label_method => Proc.new { |a| "#{c.name} (#{pluralize("post", a.posts.count)})" }
# @example The `:member_label` can be used to call a different method (or a Proc) on each object in the collection for rendering the label text (it'll try the methods like `to_s` in `collection_label_methods` config by default)
# <%= f.input :author, :as => :radio, :member_label => :name %>
# <%= f.input :author, :as => :radio, :member_label => :name_with_post_count
# <%= f.input :author, :as => :radio, :member_label => Proc.new { |a| "#{c.name} (#{pluralize("post", a.posts.count)})" }
#
# @example `:label_method` can be used with a helper method (both examples have the same result)
# <%= f.input :author, :as => :radio, :label_method => method(:fancy_label)
# <%= f.input :author, :as => :radio, :label_method => Proc.new { |author| fancy_label(author) }
# @example `:member_label` can be used with a helper method (both examples have the same result)
# <%= f.input :author, :as => :radio, :member_label => method(:fancy_label)
# <%= f.input :author, :as => :radio, :member_label => Proc.new { |author| fancy_label(author) }
#
# @example The `:value_method` can be used to call a different method (or a Proc) on each object in the collection for rendering the value for each checkbox (it'll try the methods like `id` in `collection_value_methods` config by default)
# <%= f.input :author, :as => :radio, :value_method => :login %>
# <%= f.input :author, :as => :radio, :value_method => Proc.new { |c| c.full_name.downcase.underscore }
# @example The `:member_value` can be used to call a different method (or a Proc) on each object in the collection for rendering the value for each checkbox (it'll try the methods like `id` in `collection_value_methods` config by default)
# <%= f.input :author, :as => :radio, :member_value => :login %>
# <%= f.input :author, :as => :radio, :member_value => Proc.new { |c| c.full_name.downcase.underscore }
#
# @example `:value_method` can be used with a helper method (both examples have the same result)
# <%= f.input :author, :as => :radio, :value_method => method(:some_helper)
# <%= f.input :author, :as => :radio, :value_method => Proc.new { |author| some_helper(author) }
# @example `:member_value` can be used with a helper method (both examples have the same result)
# <%= f.input :author, :as => :radio, :member_value => method(:some_helper)
# <%= f.input :author, :as => :radio, :member_value => Proc.new { |author| some_helper(author) }
#
# @example Set HTML attributes on each `<input type="radio">` tag with `:input_html`
# <%= f.input :author, :as => :radio, :input_html => { :size => 20, :multiple => true, :class => "special" } %>
Expand Down
18 changes: 9 additions & 9 deletions lib/formtastic/inputs/select_input.rb
Expand Up @@ -33,7 +33,7 @@ module Inputs
# the `:collection` option (see examples).
#
# The way on which Formtastic renders the `value` attribute and content of each `<option>` tag
# is customisable through the `:label_method` and `:value_method` options. When not provided,
# is customisable through the `:member_label` and `:member_value` options. When not provided,
# we fall back to a list of methods to try on each object such as `:to_label`, `:name` and
# `:to_s`, which are defined in the configurations `collection_label_methods` and
# `collection_value_methods` (see examples below).
Expand Down Expand Up @@ -106,14 +106,14 @@ module Inputs
# <%= f.input :author, :as => :select, :collection => grouped_options_for_select(...) %>
# <%= f.input :author, :as => :select, :collection => time_zone_options_for_select(...) %>
#
# @example The `:label_method` can be used to call a different method (or a Proc) on each object in the collection for rendering the label text (it'll try the methods like `to_s` in `collection_label_methods` config by default)
# <%= f.input :author, :as => :select, :label_method => :name %>
# <%= f.input :author, :as => :select, :label_method => :name_with_post_count
# <%= f.input :author, :as => :select, :label_method => Proc.new { |a| "#{c.name} (#{pluralize("post", a.posts.count)})" }
# @example The `:member_label` can be used to call a different method (or a Proc) on each object in the collection for rendering the label text (it'll try the methods like `to_s` in `collection_label_methods` config by default)
# <%= f.input :author, :as => :select, :member_label => :name %>
# <%= f.input :author, :as => :select, :member_label => :name_with_post_count
# <%= f.input :author, :as => :select, :member_label => Proc.new { |a| "#{c.name} (#{pluralize("post", a.posts.count)})" }
#
# @example The `:value_method` can be used to call a different method (or a Proc) on each object in the collection for rendering the value for each checkbox (it'll try the methods like `id` in `collection_value_methods` config by default)
# <%= f.input :author, :as => :select, :value_method => :login %>
# <%= f.input :author, :as => :select, :value_method => Proc.new { |c| c.full_name.downcase.underscore }
# @example The `:member_value` can be used to call a different method (or a Proc) on each object in the collection for rendering the value for each checkbox (it'll try the methods like `id` in `collection_value_methods` config by default)
# <%= f.input :author, :as => :select, :member_value => :login %>
# <%= f.input :author, :as => :select, :member_value => Proc.new { |c| c.full_name.downcase.underscore }
#
# @example Set HTML attributes on the `<select>` tag with `:input_html`
# <%= f.input :authors, :as => :select, :input_html => { :size => 20, :multiple => true, :class => "special" } %>
Expand All @@ -126,7 +126,7 @@ module Inputs
# <%= f.input :author, :as => :select, :input_html => { :include_blank => true } %>
# <%= f.input :author, :as => :select, :input_html => { :prompt => "Please select an Author..." } %>
#
# @example Group options an `<optgroup>` with the `:group_by` and `:group_label_method` options (`belongs_to` associations only)
# @example Group options an `<optgroup>` with the `:group_by` and `:group_label` options (`belongs_to` associations only)
# <%= f.input :author, :as => :select, :group_by => :continent %>
#
# @see Formtastic::Helpers::InputsHelper#input InputsHelper#input for full documetation of all possible options.
Expand Down
4 changes: 2 additions & 2 deletions spec/inputs/check_boxes_input_spec.rb
Expand Up @@ -332,7 +332,7 @@
end

describe 'for an association when a :collection is provided' do
describe 'it should use the specified :value_method option' do
describe 'it should use the specified :member_value option' do
before do
@output_buffer = ''
mock_everything
Expand All @@ -345,7 +345,7 @@
item.should_receive(:custom_value).exactly(3).times
@new_post.author.should_receive(:custom_value).exactly(3).times
concat(semantic_form_for(@new_post) do |builder|
concat(builder.input(:author, :as => :check_boxes, :value_method => :custom_value, :collection => [item, item, item]))
concat(builder.input(:author, :as => :check_boxes, :member_value => :custom_value, :collection => [item, item, item]))
end)
output_buffer.should have_tag('input[@type=checkbox][@value="custom_value"]', :count => 3)
end
Expand Down
4 changes: 2 additions & 2 deletions spec/inputs/label_spec.rb
Expand Up @@ -36,14 +36,14 @@
describe 'when a collection is given' do
it 'should use a supplied label_method for simple collections' do
concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
concat(builder.input(:author_id, :as => :check_boxes, :collection => [:a, :b, :c], :value_method => :to_s, :label_method => proc {|f| ('Label_%s' % [f])}))
concat(builder.input(:author_id, :as => :check_boxes, :collection => [:a, :b, :c], :member_value => :to_s, :member_label => proc {|f| ('Label_%s' % [f])}))
end)
output_buffer.should have_tag('form li fieldset ol li label', /Label_[abc]/, :count => 3)
end

it 'should use a supplied value_method for simple collections' do
concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
concat(builder.input(:author_id, :as => :check_boxes, :collection => [:a, :b, :c], :value_method => proc {|f| ('Value_%s' % [f.to_s])}))
concat(builder.input(:author_id, :as => :check_boxes, :collection => [:a, :b, :c], :member_value => proc {|f| ('Value_%s' % [f.to_s])}))
end)
output_buffer.should have_tag('form li fieldset ol li label input[value="Value_a"]')
output_buffer.should have_tag('form li fieldset ol li label input[value="Value_b"]')
Expand Down

0 comments on commit 454dd44

Please sign in to comment.