formtastic 2.2.1 → 2.3.0.rc
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +17 -13
- data/Appraisals +6 -3
- data/CHANGELOG +4 -0
- data/Gemfile +1 -1
- data/README.textile +14 -23
- data/Rakefile +0 -17
- data/app/assets/stylesheets/formtastic.css +2 -1
- data/formtastic.gemspec +4 -3
- data/gemfiles/{rails-3.0.gemfile → rails_3.0.gemfile} +1 -1
- data/gemfiles/{rails-3.1.gemfile → rails_3.1.gemfile} +1 -1
- data/gemfiles/{rails-3.2.gemfile → rails_3.2.gemfile} +1 -1
- data/gemfiles/rails_4.gemfile +7 -0
- data/gemfiles/rails_edge.gemfile +7 -0
- data/lib/formtastic/form_builder.rb +7 -0
- data/lib/formtastic/helpers/fieldset_wrapper.rb +1 -1
- data/lib/formtastic/helpers/form_helper.rb +8 -10
- data/lib/formtastic/helpers/input_helper.rb +1 -0
- data/lib/formtastic/inputs/base.rb +0 -1
- data/lib/formtastic/inputs/base/collections.rb +15 -4
- data/lib/formtastic/inputs/base/labelling.rb +4 -7
- data/lib/formtastic/inputs/base/numeric.rb +1 -1
- data/lib/formtastic/inputs/base/options.rb +1 -1
- data/lib/formtastic/inputs/base/timeish.rb +12 -4
- data/lib/formtastic/inputs/boolean_input.rb +6 -6
- data/lib/formtastic/inputs/check_boxes_input.rb +7 -2
- data/lib/formtastic/inputs/datetime_picker_input.rb +3 -3
- data/lib/formtastic/inputs/select_input.rb +4 -2
- data/lib/formtastic/util.rb +4 -0
- data/lib/formtastic/version.rb +1 -1
- data/lib/generators/templates/formtastic.rb +3 -3
- data/sample/basic_inputs.html +1 -1
- data/spec/builder/semantic_fields_for_spec.rb +0 -1
- data/spec/helpers/action_helper_spec.rb +1 -1
- data/spec/helpers/form_helper_spec.rb +30 -0
- data/spec/helpers/input_helper_spec.rb +1 -1
- data/spec/helpers/inputs_helper_spec.rb +13 -15
- data/spec/inputs/boolean_input_spec.rb +7 -0
- data/spec/inputs/check_boxes_input_spec.rb +31 -1
- data/spec/inputs/date_select_input_spec.rb +8 -0
- data/spec/inputs/datetime_picker_input_spec.rb +14 -14
- data/spec/inputs/datetime_select_input_spec.rb +8 -0
- data/spec/inputs/label_spec.rb +11 -0
- data/spec/inputs/select_input_spec.rb +21 -4
- data/spec/inputs/time_select_input_spec.rb +9 -1
- data/spec/spec_helper.rb +74 -13
- data/spec/support/custom_macros.rb +3 -2
- data/spec/support/test_environment.rb +2 -0
- metadata +116 -40
- data/gemfiles/rails-4.gemfile +0 -8
- data/lib/tasks/verify_rcov.rb +0 -44
data/.travis.yml
CHANGED
@@ -1,26 +1,30 @@
|
|
1
|
-
before_install:
|
1
|
+
before_install:
|
2
|
+
- gem update --system
|
3
|
+
- gem update bundler
|
2
4
|
rvm:
|
3
5
|
- 1.8.7
|
4
6
|
- ree
|
5
7
|
- 1.9.2
|
6
8
|
- 1.9.3
|
7
9
|
gemfile:
|
8
|
-
- gemfiles/
|
9
|
-
- gemfiles/
|
10
|
-
- gemfiles/
|
11
|
-
- gemfiles/rails-4.gemfile
|
10
|
+
- gemfiles/rails_3.0.gemfile
|
11
|
+
- gemfiles/rails_3.1.gemfile
|
12
|
+
- gemfiles/rails_3.2.gemfile
|
12
13
|
env:
|
13
14
|
- DEFER_GC=false RAILS_EDGE=true
|
14
15
|
script: "rake spec"
|
15
16
|
matrix:
|
16
|
-
|
17
|
-
- rvm: 1.
|
18
|
-
gemfile: gemfiles/
|
17
|
+
include:
|
18
|
+
- rvm: 1.9.3
|
19
|
+
gemfile: gemfiles/rails_4.gemfile
|
19
20
|
env: DEFER_GC=false RAILS_EDGE=true
|
20
|
-
- rvm:
|
21
|
-
gemfile: gemfiles/
|
21
|
+
- rvm: 2.0.0
|
22
|
+
gemfile: gemfiles/rails_4.gemfile
|
22
23
|
env: DEFER_GC=false RAILS_EDGE=true
|
23
|
-
|
24
|
-
|
24
|
+
allow_failures:
|
25
|
+
- rvm: 1.9.3
|
26
|
+
gemfile: gemfiles/rails_edge.gemfile
|
27
|
+
env: DEFER_GC=false RAILS_EDGE=true
|
28
|
+
- rvm: 2.0.0
|
29
|
+
gemfile: gemfiles/rails_edge.gemfile
|
25
30
|
env: DEFER_GC=false RAILS_EDGE=true
|
26
|
-
|
data/Appraisals
CHANGED
@@ -10,9 +10,12 @@ appraise 'rails-3.2' do
|
|
10
10
|
gem 'rails', '~> 3.2.0'
|
11
11
|
end
|
12
12
|
|
13
|
+
appraise 'rails-4' do
|
14
|
+
gem 'rails', '~> 4.0.0'
|
15
|
+
end
|
16
|
+
|
13
17
|
if ENV["RAILS_EDGE"] == "true"
|
14
|
-
appraise 'rails-
|
18
|
+
appraise 'rails-edge' do
|
15
19
|
gem 'rails', :git => 'git://github.com/rails/rails.git'
|
16
|
-
gem 'active_record_deprecated_finders', :git=>'https://github.com/rails/active_record_deprecated_finders.git'
|
17
20
|
end
|
18
|
-
end
|
21
|
+
end
|
data/CHANGELOG
CHANGED
data/Gemfile
CHANGED
data/README.textile
CHANGED
@@ -5,6 +5,15 @@ Formtastic is a Rails FormBuilder DSL (with some other goodies) to make it far e
|
|
5
5
|
<a href='http://www.pledgie.com/campaigns/2178'><img alt='Click here to lend your support to: formtastic and make a donation at www.pledgie.com !' src='http://pledgie.com/campaigns/2178.png?skin_name=chrome' border='0' /></a>
|
6
6
|
|
7
7
|
|
8
|
+
h2. Documentation & Support
|
9
|
+
|
10
|
+
* "Documentation is available on rdoc.info":http://rdoc.info/projects/justinfrench/formtastic
|
11
|
+
* "We track issues & bugs on GitHub":http://github.com/justinfrench/formtastic/issues
|
12
|
+
* "We have a wiki on GitHub":http://github.com/justinfrench/formtastic/wiki
|
13
|
+
* "StackOverflow can help":http://stackoverflow.com/questions/tagged/formtastic
|
14
|
+
* "Follow @formtastic on Twitter for news & updates":http://twitter.com/formtastic
|
15
|
+
|
16
|
+
|
8
17
|
h2. Compatibility
|
9
18
|
|
10
19
|
* Formtastic 2.1.x is Rails 3.x compatible
|
@@ -75,11 +84,6 @@ h2. Opinions
|
|
75
84
|
* Make the common things we do easy, yet ensure uncommon things are still possible.
|
76
85
|
|
77
86
|
|
78
|
-
h2. Documentation
|
79
|
-
|
80
|
-
RDoc documentation _should_ be automatically generated after each commit and made available on the "rdoc.info website":http://rdoc.info/projects/justinfrench/formtastic.
|
81
|
-
|
82
|
-
|
83
87
|
h2. Installation
|
84
88
|
|
85
89
|
Simply add Formtastic to your Gemfile and bundle it up:
|
@@ -250,12 +254,7 @@ Alternatively, the current index can be accessed via the `inputs` block's argume
|
|
250
254
|
<pre>
|
251
255
|
<%= semantic_form_for @post do |f| %>
|
252
256
|
<%= f.inputs :for => :categories do |category, i| %>
|
253
|
-
|
254
|
-
<%= f.inputs :name => "Category ##{i}" %>
|
255
|
-
<% else %>
|
256
|
-
<%= f.inputs :name => "Category ##{i} (optional)" %>
|
257
|
-
<% end %>
|
258
|
-
<% end %>
|
257
|
+
...
|
259
258
|
<%= f.actions %>
|
260
259
|
<% end %>
|
261
260
|
</pre>
|
@@ -531,7 +530,7 @@ Values for @labels@/@hints@/@actions@ are can take values: @String@ (explicit va
|
|
531
530
|
|
532
531
|
h2. Semantic errors
|
533
532
|
|
534
|
-
You can show errors on base (by default) and any other attribute just passing
|
533
|
+
You can show errors on base (by default) and any other attribute just by passing its name to the semantic_errors method:
|
535
534
|
|
536
535
|
<pre>
|
537
536
|
<%= semantic_form_for @post do |f| %>
|
@@ -608,28 +607,20 @@ Formtastic::FormBuilder.escape_html_entities_in_hints_and_labels = false
|
|
608
607
|
|
609
608
|
h2. Dependencies
|
610
609
|
|
611
|
-
There are none, but...
|
610
|
+
There are none other than Rails itself, but...
|
612
611
|
|
613
612
|
* If you want to use the @:country@ input, you'll need to install the "country-select plugin":https://github.com/chrislerum/country_select (or any other country_select plugin with the same API).
|
614
|
-
*
|
613
|
+
* There are a bunch of development dependencies
|
615
614
|
|
616
615
|
|
617
616
|
h2. How to contribute
|
618
617
|
|
619
618
|
* Fork the project on Github
|
620
619
|
* Create a topic branch for your changes
|
620
|
+
* Ensure that you provide test coverage for your changes
|
621
621
|
* Ensure that all tests pass (`bundle exec rake`)
|
622
|
-
* Ensure that the changes in your branch are as atomic as possible
|
623
622
|
* Create a pull request on Github
|
624
623
|
|
625
|
-
For significant changes, you may wish to discuss your idea on the Formtastic Google group before coding to ensure that your change is likely to be accepted. Formtastic relies heavily on i18n, so if you're unsure of the impact this has on your changes, please discuss them with the group.
|
626
|
-
|
627
|
-
|
628
|
-
h2. Google Group, Twitter, etc
|
629
|
-
|
630
|
-
Please join the "Formtastic Google Group":http://groups.google.com.au/group/formtastic, especially if you'd like to talk about a new feature, or report a bug.
|
631
|
-
|
632
|
-
You can also follow "@justinfrench":http://twitter.com/formtastic or "@formtastic":http://twitter.com/formtastic on Twitter for announcements, tutorials and links.
|
633
624
|
|
634
625
|
h2. Project Info
|
635
626
|
|
data/Rakefile
CHANGED
@@ -3,7 +3,6 @@ require 'bundler/setup'
|
|
3
3
|
require 'appraisal'
|
4
4
|
require 'rdoc/task'
|
5
5
|
require 'rspec/core/rake_task'
|
6
|
-
require 'tasks/verify_rcov'
|
7
6
|
|
8
7
|
Bundler::GemHelper.install_tasks
|
9
8
|
|
@@ -38,19 +37,3 @@ desc 'Test the formtastic plugin with specdoc formatting and colors'
|
|
38
37
|
RSpec::Core::RakeTask.new('specdoc') do |t|
|
39
38
|
t.pattern = FileList['spec/**/*_spec.rb']
|
40
39
|
end
|
41
|
-
|
42
|
-
desc 'Run all examples with RCov'
|
43
|
-
RSpec::Core::RakeTask.new('rcov') do |t|
|
44
|
-
t.pattern = FileList['spec/**/*_spec.rb']
|
45
|
-
t.rcov = true
|
46
|
-
t.rcov_opts = %w(--exclude gems/*,spec/*,.bundle/*, --aggregate coverage.data)
|
47
|
-
end
|
48
|
-
|
49
|
-
RCov::VerifyTask.new(:verify_coverage) do |t|
|
50
|
-
t.require_exact_threshold = false
|
51
|
-
t.threshold = (RUBY_VERSION == "1.8.7" ? 95 : 0)
|
52
|
-
end
|
53
|
-
|
54
|
-
desc "Run all examples and verify coverage"
|
55
|
-
task :spec_and_verify_coverage => [:rcov, :verify_coverage] do
|
56
|
-
end
|
data/formtastic.gemspec
CHANGED
@@ -25,15 +25,16 @@ Gem::Specification.new do |s|
|
|
25
25
|
|
26
26
|
s.add_dependency(%q<actionpack>, [">= 3.0"])
|
27
27
|
|
28
|
-
s.add_development_dependency(%q<
|
28
|
+
s.add_development_dependency(%q<nokogiri>, ["< 1.6.0"]) # 1.6 requires Ruby 1.9.2, drop in v3.0
|
29
|
+
s.add_development_dependency(%q<rspec-rails>, ["~> 2.12.0"])
|
29
30
|
s.add_development_dependency(%q<rspec_tag_matchers>, [">= 1.0.0"])
|
30
31
|
s.add_development_dependency(%q<hpricot>, ["~> 0.8.3"])
|
31
32
|
s.add_development_dependency(%q<BlueCloth>) # for YARD
|
32
33
|
s.add_development_dependency(%q<yard>, ["~> 0.6"])
|
33
|
-
s.add_development_dependency(%q<rcov>, ["~> 0.9.9"])
|
34
34
|
s.add_development_dependency(%q<colored>)
|
35
35
|
s.add_development_dependency(%q<tzinfo>)
|
36
|
-
s.add_development_dependency(%q<ammeter>, ["
|
36
|
+
s.add_development_dependency(%q<ammeter>, ["0.2.5"])
|
37
37
|
s.add_development_dependency(%q<appraisal>)
|
38
38
|
s.add_development_dependency(%q<rake>)
|
39
|
+
s.add_development_dependency(%q<activemodel>)
|
39
40
|
end
|
@@ -81,6 +81,13 @@ module Formtastic
|
|
81
81
|
fields_for(record_or_name_or_array, *(args << options), &block)
|
82
82
|
end
|
83
83
|
|
84
|
+
def initialize(object_name, object, template, options, block=nil)
|
85
|
+
super
|
86
|
+
if respond_to?('multipart=') && options.is_a?(Hash) && options[:html]
|
87
|
+
self.multipart = options[:html][:multipart]
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
84
91
|
end
|
85
92
|
|
86
93
|
end
|
@@ -58,6 +58,12 @@ module Formtastic
|
|
58
58
|
@@default_form_class = 'formtastic'
|
59
59
|
mattr_accessor :default_form_class
|
60
60
|
|
61
|
+
# Allows to set a custom field_error_proc wrapper. By default this wrapper
|
62
|
+
# is disabled since `formtastic` already adds an error class to the LI tag
|
63
|
+
# containing the input. Change this from `config/initializers/formtastic.rb`.
|
64
|
+
@@field_error_proc = proc { |html_tag, instance_tag| html_tag }
|
65
|
+
mattr_accessor :field_error_proc
|
66
|
+
|
61
67
|
# Wrapper around Rails' own `form_for` helper to set the `:builder` option to
|
62
68
|
# `Formtastic::FormBuilder` and to set some class names on the `<form>` tag such as
|
63
69
|
# `formtastic` and the downcased and underscored model name (eg `post`).
|
@@ -155,7 +161,7 @@ module Formtastic
|
|
155
161
|
when Array then options[:as] || singularizer.call(record_or_name_or_array.last.class) # [@post, @comment] # => "comment"
|
156
162
|
else options[:as] || singularizer.call(record_or_name_or_array.class) # @post => "post"
|
157
163
|
end
|
158
|
-
options[:html][:class] = class_names.join(" ")
|
164
|
+
options[:html][:class] = class_names.compact.join(" ")
|
159
165
|
|
160
166
|
with_custom_field_error_proc do
|
161
167
|
self.form_for(record_or_name_or_array, *(args << options), &proc)
|
@@ -178,17 +184,9 @@ module Formtastic
|
|
178
184
|
|
179
185
|
protected
|
180
186
|
|
181
|
-
# Override the default ActiveRecordHelper behaviour of wrapping the input.
|
182
|
-
# This gets taken care of semantically by adding an error class to the LI tag
|
183
|
-
# containing the input.
|
184
|
-
# @private
|
185
|
-
FIELD_ERROR_PROC = proc do |html_tag, instance_tag|
|
186
|
-
html_tag
|
187
|
-
end
|
188
|
-
|
189
187
|
def with_custom_field_error_proc(&block)
|
190
188
|
default_field_error_proc = ::ActionView::Base.field_error_proc
|
191
|
-
::ActionView::Base.field_error_proc =
|
189
|
+
::ActionView::Base.field_error_proc = @@field_error_proc
|
192
190
|
yield
|
193
191
|
ensure
|
194
192
|
::ActionView::Base.field_error_proc = default_field_error_proc
|
@@ -232,6 +232,7 @@ module Formtastic
|
|
232
232
|
# @todo Many many more examples. Some of the detail probably needs to be pushed out to the relevant methods too.
|
233
233
|
# @todo More i18n examples.
|
234
234
|
def input(method, options = {})
|
235
|
+
method = method.to_sym if method.is_a?(String)
|
235
236
|
options = options.dup # Allow options to be shared without being tainted by Formtastic
|
236
237
|
options[:as] ||= default_input_type(method, options)
|
237
238
|
|
@@ -85,10 +85,21 @@ module Formtastic
|
|
85
85
|
|
86
86
|
scope_conditions = conditions_from_reflection.empty? ? nil : {:conditions => conditions_from_reflection}
|
87
87
|
if conditions_from_options.any?
|
88
|
-
|
88
|
+
if Util.rails3?
|
89
|
+
reflection.klass.scoped(scope_conditions).where(conditions_from_options)
|
90
|
+
else
|
91
|
+
reflection.klass.where(scope_conditions[:conditions]).where(conditions_from_options)
|
92
|
+
end
|
89
93
|
else
|
90
|
-
|
91
|
-
|
94
|
+
|
95
|
+
if Util.rails3?
|
96
|
+
find_options_from_options.merge!(:include => group_by) if self.respond_to?(:group_by) && group_by
|
97
|
+
reflection.klass.scoped(scope_conditions).where(find_options_from_options)
|
98
|
+
else
|
99
|
+
coll = reflection.klass.where(scope_conditions)
|
100
|
+
coll = coll.includes(group_by) if self.respond_to?(:group_by) && group_by
|
101
|
+
coll.where(find_options_from_options)
|
102
|
+
end
|
92
103
|
end
|
93
104
|
end
|
94
105
|
end
|
@@ -113,7 +124,7 @@ module Formtastic
|
|
113
124
|
# Avoids an issue where `send_or_call` can be a String and duck can be something simple like
|
114
125
|
# `:first`, which obviously String responds to.
|
115
126
|
def send_or_call_or_object(duck, object)
|
116
|
-
return object if object.is_a?(String) # TODO what about other classes etc?
|
127
|
+
return object if object.is_a?(String) || object.is_a?(Integer) # TODO what about other classes etc?
|
117
128
|
send_or_call(duck, object)
|
118
129
|
end
|
119
130
|
|
@@ -10,13 +10,10 @@ module Formtastic
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def label_html_options
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
opts[:class] << 'label'
|
18
|
-
|
19
|
-
opts
|
13
|
+
{
|
14
|
+
:for => input_html_options[:id],
|
15
|
+
:class => ['label'],
|
16
|
+
}
|
20
17
|
end
|
21
18
|
|
22
19
|
def label_text
|
@@ -8,7 +8,7 @@ module Formtastic
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def formtastic_options
|
11
|
-
[:priority_countries, :priority_zones, :member_label, :member_value, :collection, :required, :label, :as, :hint, :input_html, :
|
11
|
+
[:priority_countries, :priority_zones, :member_label, :member_value, :collection, :required, :label, :as, :hint, :input_html, :value_as_class, :find_options, :class]
|
12
12
|
end
|
13
13
|
|
14
14
|
end
|
@@ -65,6 +65,9 @@ module Formtastic
|
|
65
65
|
# @example Change the labels for each fragment
|
66
66
|
# <%= f.input :publish_at, :as => :date_select, :labels => { :year => "Y", :month => "M", :day => "D" } %>
|
67
67
|
#
|
68
|
+
# @example Suppress the labels for all fragments
|
69
|
+
# <%= f.input :publish_at, :as => :date_select, :labels => false %>
|
70
|
+
#
|
68
71
|
# @example Skip a fragment (defaults to 1, skips all following fragments)
|
69
72
|
# <%= f.input :publish_at, :as => :datetime_select, :discard_minute => true %>
|
70
73
|
# <%= f.input :publish_at, :as => :datetime_select, :discard_hour => true %>
|
@@ -130,8 +133,10 @@ module Formtastic
|
|
130
133
|
end
|
131
134
|
|
132
135
|
def fragment_label(fragment)
|
133
|
-
labels_from_options = options[:labels]
|
134
|
-
if labels_from_options
|
136
|
+
labels_from_options = options.key?(:labels) ? options[:labels] : {}
|
137
|
+
if !labels_from_options
|
138
|
+
''
|
139
|
+
elsif labels_from_options.key?(fragment)
|
135
140
|
labels_from_options[fragment]
|
136
141
|
else
|
137
142
|
::I18n.t(fragment.to_s, :default => fragment.to_s.humanize, :scope => [:datetime, :prompts])
|
@@ -183,8 +188,11 @@ module Formtastic
|
|
183
188
|
|
184
189
|
def i18n_date_fragments
|
185
190
|
order = ::I18n.t(:order, :scope => [:date])
|
186
|
-
|
187
|
-
|
191
|
+
if order.is_a?(Array)
|
192
|
+
order.map &:to_sym
|
193
|
+
else
|
194
|
+
nil
|
195
|
+
end
|
188
196
|
end
|
189
197
|
|
190
198
|
def fragments_wrapping(&block)
|