formtastic 3.1.0.rc1 → 3.1.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +5 -1
- data/DEPRECATIONS +2 -0
- data/README.textile +4 -1
- data/lib/formtastic/helpers/input_helper.rb +0 -6
- data/lib/formtastic/inputs/base.rb +6 -1
- data/lib/formtastic/inputs/check_boxes_input.rb +1 -18
- data/lib/formtastic/inputs/radio_input.rb +5 -21
- data/lib/formtastic/inputs/select_input.rb +2 -9
- data/lib/formtastic/version.rb +1 -1
- data/spec/inputs/check_boxes_input_spec.rb +6 -3
- data/spec/inputs/label_spec.rb +10 -6
- data/spec/spec_helper.rb +10 -1
- data/spec/support/custom_macros.rb +35 -21
- metadata +2 -2
data/CHANGELOG
CHANGED
data/DEPRECATIONS
CHANGED
data/README.textile
CHANGED
@@ -191,7 +191,7 @@ If you want to customize the label text, or render some hint text below the fiel
|
|
191
191
|
<%= f.inputs :name => "Advanced Options", :id => "advanced" do %>
|
192
192
|
<%= f.input :slug, :label => "URL Title", :hint => "Created automatically if left blank", :required => false %>
|
193
193
|
<%= f.input :section, :as => :radio %>
|
194
|
-
<%= f.input :user, :label => "Author"
|
194
|
+
<%= f.input :user, :label => "Author" %>
|
195
195
|
<%= f.input :categories, :required => false %>
|
196
196
|
<%= f.input :created_at, :as => :string, :label => "Publication Date", :required => false %>
|
197
197
|
<% end %>
|
@@ -308,6 +308,9 @@ Many inputs provide a collection of options to choose from (like @:select@, @:ra
|
|
308
308
|
f.input :authors, :as => :check_boxes, :collection => [@justin, @kate]
|
309
309
|
f.input :authors, :as => :check_boxes, :collection => ["Justin", "Kate", "Amelia", "Gus", "Meg"]
|
310
310
|
f.input :author, :as => :select, :collection => Author.all
|
311
|
+
f.input :author, :as => :select, :collection => Author.pluck(:first_name, :id)
|
312
|
+
f.input :author, :as => :select, :collection => Author.pluck(Arel.sql("CONCAT(`first_name`, ' ', `last_name`)"), :id)
|
313
|
+
f.input :author, :as => :select, :collection => Author.your_custom_scope_or_class_method
|
311
314
|
f.input :author, :as => :select, :collection => { @justin.name => @justin.id, @kate.name => @kate.id }
|
312
315
|
f.input :author, :as => :select, :collection => ["Justin", "Kate", "Amelia", "Gus", "Meg"]
|
313
316
|
f.input :author, :as => :radio, :collection => User.all
|
@@ -141,12 +141,6 @@ module Formtastic
|
|
141
141
|
# @option options :collection [Array<ActiveModel, String, Symbol>, Hash{String => String, Boolean}, OrderedHash{String => String, Boolean}]
|
142
142
|
# Override collection of objects in the association (`:select`, `:radio` & `:check_boxes` inputs only)
|
143
143
|
#
|
144
|
-
# @option options :member_label [Symbol, Proc, Method]
|
145
|
-
# 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)
|
146
|
-
#
|
147
|
-
# @option options :member_value [Symbol, Proc, Method]
|
148
|
-
# 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)
|
149
|
-
#
|
150
144
|
# @option options :multiple [Boolean]
|
151
145
|
# Specify if the `:select` input should allow multiple selections or not (defaults to `belongs_to` associations, and `true` for `has_many` and `has_and_belongs_to_many` associations)
|
152
146
|
#
|
@@ -11,6 +11,11 @@ module Formtastic
|
|
11
11
|
@object_name = object_name
|
12
12
|
@method = method
|
13
13
|
@options = options.dup
|
14
|
+
|
15
|
+
# Deprecate :member_label and :member_value, remove v4.0
|
16
|
+
member_deprecation_message = "passing an Array of label/value pairs like [['Justin', 2], ['Kate', 3]] into :collection directly (consider building the array in your model using Model.pluck)"
|
17
|
+
warn_deprecated_option!(:member_label, member_deprecation_message)
|
18
|
+
warn_deprecated_option!(:member_value, member_deprecation_message)
|
14
19
|
end
|
15
20
|
|
16
21
|
# Usefull for deprecating options.
|
@@ -24,7 +29,7 @@ module Formtastic
|
|
24
29
|
# Usefull for deprecating options.
|
25
30
|
def warn_deprecated_option!(old_option_name, instructions)
|
26
31
|
if options.key?(old_option_name)
|
27
|
-
::ActiveSupport::Deprecation.warn("The :#{old_option_name} option is deprecated in favour of `#{instructions}
|
32
|
+
::ActiveSupport::Deprecation.warn("The :#{old_option_name} option is deprecated in favour of `#{instructions}`. :#{old_option_name} will be removed in the next version", caller(6))
|
28
33
|
end
|
29
34
|
end
|
30
35
|
|
@@ -39,6 +39,7 @@ module Formtastic
|
|
39
39
|
# <%= f.input :categories, :as => :check_boxes, :collection => @categories %>
|
40
40
|
# <%= f.input :categories, :as => :check_boxes, :collection => Category.all %>
|
41
41
|
# <%= f.input :categories, :as => :check_boxes, :collection => Category.some_named_scope %>
|
42
|
+
# <%= f.input :categories, :as => :check_boxes, :collection => Category.pluck(:label, :id) %>
|
42
43
|
# <%= f.input :categories, :as => :check_boxes, :collection => [Category.find_by_name("Ruby"), Category.find_by_name("Rails")] %>
|
43
44
|
# <%= f.input :categories, :as => :check_boxes, :collection => ["Ruby", "Rails"] %>
|
44
45
|
# <%= f.input :categories, :as => :check_boxes, :collection => [["Ruby", "ruby"], ["Rails", "rails"]] %>
|
@@ -56,24 +57,6 @@ module Formtastic
|
|
56
57
|
# @example `:disabled` can be used to disable any checkboxes with a value found in the given Array
|
57
58
|
# <%= f.input :categories, :as => :check_boxes, :collection => ["a", "b"], :disabled => ["a"] %>
|
58
59
|
#
|
59
|
-
# @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)
|
60
|
-
# <%= f.input :categories, :as => :check_boxes, :member_label => :name %>
|
61
|
-
# <%= f.input :categories, :as => :check_boxes, :member_label => :name_with_post_count
|
62
|
-
# <%= f.input :categories, :as => :check_boxes, :member_label => { |c| "#{c.name} (#{pluralize("post", c.posts.count)})" }
|
63
|
-
#
|
64
|
-
# @example `:member_label` can be used with a helper method (both examples have the same result)
|
65
|
-
# <%= f.input :categories, :as => :check_boxes, :member_label => method(:fancy_label)
|
66
|
-
# <%= f.input :categories, :as => :check_boxes, :member_label => Proc.new { |category| fancy_label(category) }
|
67
|
-
#
|
68
|
-
# @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)
|
69
|
-
# <%= f.input :categories, :as => :check_boxes, :member_value => :code %>
|
70
|
-
# <%= f.input :categories, :as => :check_boxes, :member_value => :isbn
|
71
|
-
# <%= f.input :categories, :as => :check_boxes, :member_value => Proc.new { |c| c.name.downcase.underscore }
|
72
|
-
#
|
73
|
-
# @example `:member_value` can be used with a helper method (both examples have the same result)
|
74
|
-
# <%= f.input :categories, :as => :check_boxes, :member_value => method(:some_helper)
|
75
|
-
# <%= f.input :categories, :as => :check_boxes, :member_value => Proc.new { |category| some_helper(category) }
|
76
|
-
#
|
77
60
|
# @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
|
78
61
|
# <%= f.input :categories, :as => :check_boxes, :value_as_class => true %>
|
79
62
|
#
|
@@ -31,10 +31,9 @@ module Formtastic
|
|
31
31
|
# `Section.all` for a `Post` form with an input for a `belongs_to :section` association.
|
32
32
|
# You can override or customise this collection through the `:collection` option (see examples).
|
33
33
|
#
|
34
|
-
# The way on which Formtastic renders the `value` attribute and label for each choice is
|
35
|
-
# customisable
|
36
|
-
#
|
37
|
-
# `:to_label`, `:name` and `:to_s`, which are defined in the configurations
|
34
|
+
# The way on which Formtastic renders the `value` attribute and label for each choice in the `:collection` is
|
35
|
+
# customisable (see examples below). When not provided, we fall back to a list of methods to try on each
|
36
|
+
# object such as `:to_label`, `:name` and `:to_s`, which are defined in the configurations
|
38
37
|
# `collection_label_methods` and `collection_value_methods`.
|
39
38
|
#
|
40
39
|
# @example Basic `belongs_to` example with full form context
|
@@ -78,6 +77,8 @@ module Formtastic
|
|
78
77
|
# <%= f.input :author, :as => :radio, :collection => @authors %>
|
79
78
|
# <%= f.input :author, :as => :radio, :collection => Author.all %>
|
80
79
|
# <%= f.input :author, :as => :radio, :collection => Author.some_named_scope %>
|
80
|
+
# <%= f.input :author, :as => :radio, :collection => Author.pluck(:full_name, :id) %>
|
81
|
+
# <%= f.input :author, :as => :radio, :collection => Author.pluck(Arel.sql("CONCAT(`first_name`, ' ', `last_name`)"), :id)) %>
|
81
82
|
# <%= f.input :author, :as => :radio, :collection => [Author.find_by_login("justin"), Category.find_by_name("kate")] %>
|
82
83
|
# <%= f.input :author, :as => :radio, :collection => ["Justin", "Kate"] %>
|
83
84
|
# <%= f.input :author, :as => :radio, :collection => [["Justin", "justin"], ["Kate", "kate"]] %>
|
@@ -87,23 +88,6 @@ module Formtastic
|
|
87
88
|
# <%= f.input :author, :as => :radio, :collection => [:justin, :kate] %>
|
88
89
|
# <%= f.input :author, :as => :radio, :collection => 1..5 %>
|
89
90
|
#
|
90
|
-
# @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)
|
91
|
-
# <%= f.input :author, :as => :radio, :member_label => :name %>
|
92
|
-
# <%= f.input :author, :as => :radio, :member_label => :name_with_post_count
|
93
|
-
# <%= f.input :author, :as => :radio, :member_label => Proc.new { |a| "#{c.name} (#{pluralize("post", a.posts.count)})" }
|
94
|
-
#
|
95
|
-
# @example `:member_label` can be used with a helper method (both examples have the same result)
|
96
|
-
# <%= f.input :author, :as => :radio, :member_label => method(:fancy_label)
|
97
|
-
# <%= f.input :author, :as => :radio, :member_label => Proc.new { |author| fancy_label(author) }
|
98
|
-
#
|
99
|
-
# @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)
|
100
|
-
# <%= f.input :author, :as => :radio, :member_value => :login %>
|
101
|
-
# <%= f.input :author, :as => :radio, :member_value => Proc.new { |c| c.full_name.downcase.underscore }
|
102
|
-
#
|
103
|
-
# @example `:member_value` can be used with a helper method (both examples have the same result)
|
104
|
-
# <%= f.input :author, :as => :radio, :member_value => method(:some_helper)
|
105
|
-
# <%= f.input :author, :as => :radio, :member_value => Proc.new { |author| some_helper(author) }
|
106
|
-
#
|
107
91
|
# @example Set HTML attributes on each `<input type="radio">` tag with `:input_html`
|
108
92
|
# <%= f.input :author, :as => :radio, :input_html => { :size => 20, :multiple => true, :class => "special" } %>
|
109
93
|
#
|
@@ -94,6 +94,8 @@ module Formtastic
|
|
94
94
|
# <%= f.input :author, :as => :select, :collection => @authors %>
|
95
95
|
# <%= f.input :author, :as => :select, :collection => Author.all %>
|
96
96
|
# <%= f.input :author, :as => :select, :collection => Author.some_named_scope %>
|
97
|
+
# <%= f.input :author, :as => :select, :collection => Author.pluck(:full_name, :id) %>
|
98
|
+
# <%= f.input :author, :as => :select, :collection => Author.pluck(Arel.sql("CONCAT(`first_name`, ' ', `last_name`)"), :id)) %>
|
97
99
|
# <%= f.input :author, :as => :select, :collection => [Author.find_by_login("justin"), Category.find_by_name("kate")] %>
|
98
100
|
# <%= f.input :author, :as => :select, :collection => ["Justin", "Kate"] %>
|
99
101
|
# <%= f.input :author, :as => :select, :collection => [["Justin", "justin"], ["Kate", "kate"]] %>
|
@@ -106,15 +108,6 @@ module Formtastic
|
|
106
108
|
# <%= f.input :author, :as => :select, :collection => grouped_options_for_select(...) %>
|
107
109
|
# <%= f.input :author, :as => :select, :collection => time_zone_options_for_select(...) %>
|
108
110
|
#
|
109
|
-
# @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)
|
110
|
-
# <%= f.input :author, :as => :select, :member_label => :name %>
|
111
|
-
# <%= f.input :author, :as => :select, :member_label => :name_with_post_count %>
|
112
|
-
# <%= f.input :author, :as => :select, :member_label => Proc.new { |a| "#{c.name} (#{pluralize("post", a.posts.count)})" } %>
|
113
|
-
#
|
114
|
-
# @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)
|
115
|
-
# <%= f.input :author, :as => :select, :member_value => :login %>
|
116
|
-
# <%= f.input :author, :as => :select, :member_value => Proc.new { |c| c.full_name.downcase.underscore } %>
|
117
|
-
#
|
118
111
|
# @example Set HTML attributes on the `<select>` tag with `:input_html`
|
119
112
|
# <%= f.input :authors, :as => :select, :input_html => { :size => 20, :multiple => true, :class => "special" } %>
|
120
113
|
#
|
data/lib/formtastic/version.rb
CHANGED
@@ -350,9 +350,12 @@ describe 'check_boxes input' do
|
|
350
350
|
item.stub(:custom_value).and_return('custom_value')
|
351
351
|
item.should_receive(:custom_value).exactly(3).times
|
352
352
|
@new_post.author.should_receive(:custom_value).exactly(1).times
|
353
|
-
|
354
|
-
|
355
|
-
|
353
|
+
|
354
|
+
with_deprecation_silenced do
|
355
|
+
concat(semantic_form_for(@new_post) do |builder|
|
356
|
+
concat(builder.input(:author, :as => :check_boxes, :member_value => :custom_value, :collection => [item, item, item]))
|
357
|
+
end)
|
358
|
+
end
|
356
359
|
output_buffer.should have_tag('input[@type=checkbox][@value="custom_value"]', :count => 3)
|
357
360
|
end
|
358
361
|
end
|
data/spec/inputs/label_spec.rb
CHANGED
@@ -68,16 +68,20 @@ describe 'Formtastic::FormBuilder#label' do
|
|
68
68
|
|
69
69
|
describe 'when a collection is given' do
|
70
70
|
it 'should use a supplied label_method for simple collections' do
|
71
|
-
|
72
|
-
concat(
|
73
|
-
|
71
|
+
with_deprecation_silenced do
|
72
|
+
concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
|
73
|
+
concat(builder.input(:author_id, :as => :check_boxes, :collection => [:a, :b, :c], :member_value => :to_s, :member_label => proc {|f| ('Label_%s' % [f])}))
|
74
|
+
end)
|
75
|
+
end
|
74
76
|
output_buffer.should have_tag('form li fieldset ol li label', /Label_[abc]/, :count => 3)
|
75
77
|
end
|
76
78
|
|
77
79
|
it 'should use a supplied value_method for simple collections' do
|
78
|
-
|
79
|
-
concat(
|
80
|
-
|
80
|
+
with_deprecation_silenced do
|
81
|
+
concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
|
82
|
+
concat(builder.input(:author_id, :as => :check_boxes, :collection => [:a, :b, :c], :member_value => proc {|f| ('Value_%s' % [f.to_s])}))
|
83
|
+
end)
|
84
|
+
end
|
81
85
|
output_buffer.should have_tag('form li fieldset ol li label input[value="Value_a"]')
|
82
86
|
output_buffer.should have_tag('form li fieldset ol li label input[value="Value_b"]')
|
83
87
|
output_buffer.should have_tag('form li fieldset ol li label input[value="Value_c"]')
|
data/spec/spec_helper.rb
CHANGED
@@ -534,7 +534,16 @@ RSpec.configure do |config|
|
|
534
534
|
config.before(:each) do
|
535
535
|
Formtastic::Localizer.cache.clear!
|
536
536
|
end
|
537
|
-
|
537
|
+
|
538
|
+
config.before(:each) do
|
539
|
+
allow(Formtastic.deprecation).to receive(:deprecation_warning).and_call_original
|
540
|
+
# TODO: Remove this in Formtastic 4
|
541
|
+
[ :action_class, :standard_action_class_name, :custom_action_class_name,
|
542
|
+
:input_class, :standard_input_class_name, :custom_input_class_name ].each do |method|
|
543
|
+
allow(Formtastic.deprecation).to receive(:deprecation_warning).with(method, instance_of(String), instance_of(Array))
|
544
|
+
end
|
545
|
+
end
|
546
|
+
|
538
547
|
config.before(:all) do
|
539
548
|
DeferredGarbageCollection.start unless ENV["DEFER_GC"] == "false"
|
540
549
|
end
|
@@ -428,9 +428,11 @@ module CustomMacros
|
|
428
428
|
|
429
429
|
describe 'as a symbol' do
|
430
430
|
before do
|
431
|
-
|
432
|
-
concat(
|
433
|
-
|
431
|
+
with_deprecation_silenced do
|
432
|
+
concat(semantic_form_for(@new_post) do |builder|
|
433
|
+
concat(builder.input(:author, :as => as, :member_label => :login))
|
434
|
+
end)
|
435
|
+
end
|
434
436
|
end
|
435
437
|
|
436
438
|
it 'should have options with text content from the specified method' do
|
@@ -442,9 +444,11 @@ module CustomMacros
|
|
442
444
|
|
443
445
|
describe 'as a proc' do
|
444
446
|
before do
|
445
|
-
|
446
|
-
concat(
|
447
|
-
|
447
|
+
with_deprecation_silenced do
|
448
|
+
concat(semantic_form_for(@new_post) do |builder|
|
449
|
+
concat(builder.input(:author, :as => as, :member_label => Proc.new {|a| a.login.reverse }))
|
450
|
+
end)
|
451
|
+
end
|
448
452
|
end
|
449
453
|
|
450
454
|
it 'should have options with the proc applied to each' do
|
@@ -459,9 +463,11 @@ module CustomMacros
|
|
459
463
|
def reverse_login(a)
|
460
464
|
a.login.reverse
|
461
465
|
end
|
462
|
-
|
463
|
-
concat(
|
464
|
-
|
466
|
+
with_deprecation_silenced do
|
467
|
+
concat(semantic_form_for(@new_post) do |builder|
|
468
|
+
concat(builder.input(:author, :as => as, :member_label => method(:reverse_login)))
|
469
|
+
end)
|
470
|
+
end
|
465
471
|
end
|
466
472
|
|
467
473
|
it 'should have options with the proc applied to each' do
|
@@ -480,9 +486,11 @@ module CustomMacros
|
|
480
486
|
@fred.stub(:respond_to?) { |m| m.to_s == label_method || m.to_s == 'id' }
|
481
487
|
[@fred, @bob].each { |a| a.stub(label_method).and_return('The Label Text') }
|
482
488
|
|
483
|
-
|
484
|
-
concat(
|
485
|
-
|
489
|
+
with_deprecation_silenced do
|
490
|
+
concat(semantic_form_for(@new_post) do |builder|
|
491
|
+
concat(builder.input(:author, :as => as))
|
492
|
+
end)
|
493
|
+
end
|
486
494
|
end
|
487
495
|
|
488
496
|
it "should render the options with #{label_method} as the label" do
|
@@ -499,9 +507,11 @@ module CustomMacros
|
|
499
507
|
|
500
508
|
describe 'as a symbol' do
|
501
509
|
before do
|
502
|
-
|
503
|
-
concat(
|
504
|
-
|
510
|
+
with_deprecation_silenced do
|
511
|
+
concat(semantic_form_for(@new_post) do |builder|
|
512
|
+
concat(builder.input(:author, :as => as, :member_value => :login))
|
513
|
+
end)
|
514
|
+
end
|
505
515
|
end
|
506
516
|
|
507
517
|
it 'should have options with values from specified method' do
|
@@ -513,9 +523,11 @@ module CustomMacros
|
|
513
523
|
|
514
524
|
describe 'as a proc' do
|
515
525
|
before do
|
516
|
-
|
517
|
-
concat(
|
518
|
-
|
526
|
+
with_deprecation_silenced do
|
527
|
+
concat(semantic_form_for(@new_post) do |builder|
|
528
|
+
concat(builder.input(:author, :as => as, :member_value => Proc.new {|a| a.login.reverse }))
|
529
|
+
end)
|
530
|
+
end
|
519
531
|
end
|
520
532
|
|
521
533
|
it 'should have options with the proc applied to each value' do
|
@@ -530,9 +542,11 @@ module CustomMacros
|
|
530
542
|
def reverse_login(a)
|
531
543
|
a.login.reverse
|
532
544
|
end
|
533
|
-
|
534
|
-
concat(
|
535
|
-
|
545
|
+
with_deprecation_silenced do
|
546
|
+
concat(semantic_form_for(@new_post) do |builder|
|
547
|
+
concat(builder.input(:author, :as => as, :member_value => method(:reverse_login)))
|
548
|
+
end)
|
549
|
+
end
|
536
550
|
end
|
537
551
|
|
538
552
|
it 'should have options with the proc applied to each value' do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: formtastic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.1.0.
|
4
|
+
version: 3.1.0.rc2
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-11-
|
12
|
+
date: 2014-11-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionpack
|