formtastic-rails3 0.9.10.1 → 1.0.0.beta3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.textile +32 -16
- data/Rakefile +11 -11
- data/lib/formtastic.rb +95 -30
- data/lib/formtastic/railtie.rb +1 -1
- data/lib/formtastic/util.rb +3 -2
- data/lib/generators/formtastic/form/form_generator.rb +4 -4
- data/spec/buttons_spec.rb +1 -1
- data/spec/commit_button_spec.rb +1 -1
- data/spec/custom_builder_spec.rb +1 -1
- data/spec/defaults_spec.rb +1 -1
- data/spec/error_proc_spec.rb +1 -1
- data/spec/errors_spec.rb +1 -1
- data/spec/form_helper_spec.rb +1 -1
- data/spec/helpers/layout_helper_spec.rb +21 -0
- data/spec/i18n_spec.rb +1 -1
- data/spec/include_blank_spec.rb +1 -1
- data/spec/input_spec.rb +99 -93
- data/spec/inputs/boolean_input_spec.rb +1 -1
- data/spec/inputs/check_boxes_input_spec.rb +120 -6
- data/spec/inputs/country_input_spec.rb +1 -1
- data/spec/inputs/date_input_spec.rb +1 -1
- data/spec/inputs/datetime_input_spec.rb +1 -1
- data/spec/inputs/file_input_spec.rb +1 -1
- data/spec/inputs/hidden_input_spec.rb +1 -1
- data/spec/inputs/numeric_input_spec.rb +1 -1
- data/spec/inputs/password_input_spec.rb +1 -1
- data/spec/inputs/radio_input_spec.rb +61 -2
- data/spec/inputs/select_input_spec.rb +1 -1
- data/spec/inputs/string_input_spec.rb +36 -19
- data/spec/inputs/text_input_spec.rb +1 -1
- data/spec/inputs/time_input_spec.rb +24 -2
- data/spec/inputs/time_zone_input_spec.rb +1 -1
- data/spec/inputs_spec.rb +37 -2
- data/spec/label_spec.rb +42 -1
- data/spec/semantic_errors_spec.rb +1 -1
- data/spec/semantic_fields_for_spec.rb +1 -1
- data/spec/spec_helper.rb +15 -39
- data/spec/{custom_macros.rb → support/custom_macros.rb} +0 -7
- data/spec/support/output_buffer.rb +4 -0
- data/spec/support/test_environment.rb +45 -0
- metadata +20 -14
- data/spec/layout_helper_spec.rb +0 -31
data/README.textile
CHANGED
@@ -77,20 +77,33 @@ h2. Documentation
|
|
77
77
|
RDoc documentation _should_ be automatically generated after each commit and made available on the "rdoc.info website":http://rdoc.info/projects/justinfrench/formtastic.
|
78
78
|
|
79
79
|
|
80
|
-
h2.
|
80
|
+
h2. A Note About Rails 3 Support
|
81
81
|
|
82
|
-
|
82
|
+
Formtastic 1.0 will only support the latest stable Rails 2.x. We're maintaining a rails3 branch which aims to provide both Rails 2.x and 3.x support, which is targeted for the 1.1 release soon after 1.0, around the same time Rails 3.0 ships.
|
83
|
+
|
84
|
+
If you have a Rails 3 project and would like to use Formtastic's rails3 branch, bundler provides you with the ability to do this easily. Just add Formtastic as a git dependency in your Gemfile with the :branch option:
|
83
85
|
|
84
86
|
<pre>
|
85
|
-
|
87
|
+
gem 'formtastic', :git => "http://github.com/justinfrench/formtastic.git", :branch => "rails3"
|
86
88
|
</pre>
|
87
89
|
|
88
|
-
|
90
|
+
Please be aware that Rails 3 is still under heavy development (even in the later betas), as is Formtastic, so our rails3 branch is very much "on the edge", just like Rails. if you find issues, compatibility issues with Rails 2 or 3, please report an issue on Github.
|
91
|
+
|
92
|
+
|
93
|
+
h2. Installation under Rails 2.x
|
94
|
+
|
95
|
+
Install the Formtastic gem:
|
89
96
|
|
90
97
|
<pre>
|
91
98
|
sudo gem install formtastic
|
92
99
|
</pre>
|
93
100
|
|
101
|
+
Or try the 1.0.0.beta2:
|
102
|
+
|
103
|
+
<pre>
|
104
|
+
sudo gem install formtastic --pre
|
105
|
+
</pre>
|
106
|
+
|
94
107
|
And add it to your environment.rb configuration as a gem dependency:
|
95
108
|
|
96
109
|
<pre>
|
@@ -113,6 +126,7 @@ A proof-of-concept stylesheet is provided which you can include in your layout.
|
|
113
126
|
</head>
|
114
127
|
</pre>
|
115
128
|
|
129
|
+
|
116
130
|
h2. Usage
|
117
131
|
|
118
132
|
Forms are really boring to code... you want to get onto the good stuff as fast as possible.
|
@@ -517,12 +531,18 @@ If you want to add your own input types to encapsulate your own logic or interfa
|
|
517
531
|
|
518
532
|
@Formtastic::SemanticFormHelper.builder = MyCustomBuilder@
|
519
533
|
|
534
|
+
h2. Security
|
535
|
+
|
536
|
+
By default formtastic escapes html entities in both labels and hints unless a string is marked as html_safe. If you are using an older rails version which doesn't know html_safe, or you want to globally turn this feature off, you can set the following in your initializer:
|
520
537
|
|
538
|
+
Formtastic::SemanticFormBuilder.escape_html_entities_in_hints_and_labels = false
|
521
539
|
|
522
540
|
|
523
|
-
h2.
|
541
|
+
h2. Focus
|
524
542
|
|
525
|
-
Formtastic
|
543
|
+
Formtastic is close to shipping a 1.0 release candidate after more than a year of active development. 1.0 will be compatible with Rails 2, and this is our top priority right now. We've also been working hard on a Rails 2 *and* 3 compatible version in the rails3 branch, targeting a 1.1 release shortly after Rails 3.0 ships.
|
544
|
+
|
545
|
+
There's heaps more we want to do, but we have to do this first.
|
526
546
|
|
527
547
|
|
528
548
|
h2. Dependencies
|
@@ -536,18 +556,14 @@ There are none, but...
|
|
536
556
|
|
537
557
|
h2. Compatibility
|
538
558
|
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
Well...there's a TextMate-bundle in town, dedicated to make usage of Formtastic in the "TextMate":http://macromates.com/ editor even more of a breeze:
|
544
|
-
|
545
|
-
"Formtastic.tmbundle":http://github.com/grimen/formtastic_tmbundle
|
546
|
-
|
559
|
+
* We're only testing Formtastic with the latest Rails 2.x stable release. Patches are welcome to allow backwards compatibility with older versions of Rails, of course.
|
560
|
+
* Development of a Rails 2 *and* 3 compatible version of Formtastic is underway in the rails3 branch, targeting a Formtastic 1.1 release shortly after Rails 3.0 ships.
|
561
|
+
* Formtastic, much like Rails 2, is very ActiveRecord-centric. Many people are using Formtastic (especially the rails3 branch) successfully with other ActiveModel-like ORMs and classes (DataMapper, MongoMapper, Mongoid, Authlogic, Devise...) but we're not guaranteeing anything at this stage. Patches are welcome, but it's not our core focus right now. Shipping a solid 1.0 and Rails 3 compatible 1.1 is.
|
562
|
+
|
547
563
|
|
548
564
|
h2. How to contribute
|
549
565
|
|
550
|
-
|
566
|
+
Please ensure that you provide appropriate spec/test coverage and ensure the documentation is up-to-date. Bonus points if you perform your changes in a clean topic branch rather than master, and if you create an issue on GH for us to discuss your changes. Pull requests tend to get lost.
|
551
567
|
|
552
568
|
Please also keep your commits *atomic* so that they are more likely to apply cleanly. That means that each commit should contain the smallest possible logical change. Don't commit two features at once, don't update the gemspec at the same time you add a feature, don't fix a whole bunch of whitespace in a file at the same time you change a few lines, etc, etc.
|
553
569
|
|
@@ -556,7 +572,7 @@ For significant changes, you may wish to discuss your idea on the Formtastic Goo
|
|
556
572
|
|
557
573
|
h2. Maintainers & Contributors
|
558
574
|
|
559
|
-
Formtastic is maintained by "Justin French":http://
|
575
|
+
Formtastic is maintained by "Justin French":http://github.com/justinfrench, "Morton Jonuschat":http://github.com/yabawock and "Gabriel Sobrinho":http://github.com/sobrinho. "Denis Major":http://github.com/denismajor1 is doing some amazing documentation work in the wiki, and we very much appreciate the past efforts of "José Valim":http://github.com/josevalim and "Jonas Grimfelt":http://github.com/grimen and over 40 other contributors.
|
560
576
|
|
561
577
|
@git shortlog -n -s --no-merges@
|
562
578
|
|
data/Rakefile
CHANGED
@@ -37,14 +37,14 @@ begin
|
|
37
37
|
Find out more and get involved:
|
38
38
|
http://github.com/justinfrench/formtastic
|
39
39
|
http://groups.google.com.au/group/formtastic
|
40
|
-
|
40
|
+
|
41
41
|
All credit goes to the original author, Justin French.
|
42
42
|
========================================================================
|
43
43
|
}
|
44
|
-
|
44
|
+
|
45
45
|
gem 'jeweler', '>= 1.0.0'
|
46
46
|
require 'jeweler'
|
47
|
-
|
47
|
+
|
48
48
|
Jeweler::Tasks.new do |s|
|
49
49
|
s.name = GEM
|
50
50
|
s.summary = SUMMARY
|
@@ -53,21 +53,21 @@ begin
|
|
53
53
|
s.description = SUMMARY
|
54
54
|
s.author = AUTHOR
|
55
55
|
s.post_install_message = INSTALL_MESSAGE
|
56
|
-
|
56
|
+
|
57
57
|
s.require_path = 'lib'
|
58
58
|
s.files = %w(MIT-LICENSE README.textile Rakefile) + Dir.glob("{rails,lib,generators,spec}/**/*")
|
59
|
-
|
59
|
+
|
60
60
|
# Runtime dependencies: When installing Formtastic these will be checked if they are installed.
|
61
61
|
# Will be offered to install these if they are not already installed.
|
62
62
|
s.add_dependency 'activesupport', '>= 3.0.0beta3'
|
63
63
|
s.add_dependency 'actionpack', '>= 3.0.0beta3'
|
64
|
-
|
64
|
+
|
65
65
|
# Development dependencies. Not installed by default.
|
66
66
|
# Install with: sudo gem install formtastic --development
|
67
67
|
s.add_development_dependency 'rspec-rails', '>= 1.2.6'
|
68
68
|
s.add_development_dependency 'rspec_tag_matchers', '>= 1.0.0'
|
69
69
|
end
|
70
|
-
|
70
|
+
|
71
71
|
Jeweler::GemcutterTasks.new
|
72
72
|
rescue LoadError
|
73
73
|
puts "[formtastic:] Jeweler - or one of its dependencies - is not available. Install it with: sudo gem install jeweler -s http://gemcutter.org"
|
@@ -106,19 +106,19 @@ if defined?(Spec)
|
|
106
106
|
end
|
107
107
|
end
|
108
108
|
|
109
|
-
if defined?(
|
109
|
+
if defined?(RSpec)
|
110
110
|
desc 'Test the formtastic plugin.'
|
111
|
-
|
111
|
+
RSpec::Core::RakeTask.new('spec') do |t|
|
112
112
|
t.pattern = FileList['spec/**/*_spec.rb']
|
113
113
|
end
|
114
114
|
|
115
115
|
desc 'Test the formtastic plugin with specdoc formatting and colors'
|
116
|
-
|
116
|
+
RSpec::Core::RakeTask.new('specdoc') do |t|
|
117
117
|
t.pattern = FileList['spec/**/*_spec.rb']
|
118
118
|
end
|
119
119
|
|
120
120
|
desc "Run all examples with RCov"
|
121
|
-
|
121
|
+
RSpec::Core::RakeTask.new('examples_with_rcov') do |t|
|
122
122
|
t.pattern = FileList['spec/**/*_spec.rb']
|
123
123
|
t.rcov = true
|
124
124
|
t.rcov_opts = ['--exclude', 'spec,Library']
|
data/lib/formtastic.rb
CHANGED
@@ -20,11 +20,12 @@ module Formtastic #:nodoc:
|
|
20
20
|
@@file_methods = [ :file?, :public_filename, :filename ]
|
21
21
|
@@priority_countries = ["Australia", "Canada", "United Kingdom", "United States"]
|
22
22
|
@@i18n_lookups_by_default = false
|
23
|
+
@@escape_html_entities_in_hints_and_labels = true
|
23
24
|
@@default_commit_button_accesskey = nil
|
24
25
|
|
25
26
|
cattr_accessor :default_text_field_size, :default_text_area_height, :all_fields_required_by_default, :include_blank_for_select_by_default,
|
26
27
|
:required_string, :optional_string, :inline_errors, :label_str_method, :collection_label_methods,
|
27
|
-
:inline_order, :file_methods, :priority_countries, :i18n_lookups_by_default, :default_commit_button_accesskey
|
28
|
+
:inline_order, :file_methods, :priority_countries, :i18n_lookups_by_default, :escape_html_entities_in_hints_and_labels, :default_commit_button_accesskey
|
28
29
|
|
29
30
|
RESERVED_COLUMNS = [:created_at, :updated_at, :created_on, :updated_on, :lock_version, :version]
|
30
31
|
|
@@ -483,7 +484,7 @@ module Formtastic #:nodoc:
|
|
483
484
|
# Collects association columns (relation columns) for the current form object class.
|
484
485
|
#
|
485
486
|
def association_columns(*by_associations) #:nodoc:
|
486
|
-
if @object.present?
|
487
|
+
if @object.present? && @object.class.respond_to?(:reflections)
|
487
488
|
@object.class.reflections.collect do |name, _|
|
488
489
|
if by_associations.present?
|
489
490
|
name if by_associations.include?(_.macro)
|
@@ -528,9 +529,17 @@ module Formtastic #:nodoc:
|
|
528
529
|
raise ArgumentError, 'You gave :for option with a block to inputs method, ' <<
|
529
530
|
'but the block does not accept any argument.' if block.arity <= 0
|
530
531
|
|
531
|
-
|
532
|
+
lambda do |f|
|
533
|
+
contents = f.inputs(*args){ block.call(f) }
|
534
|
+
template.concat(contents) if ::Formtastic::Util.rails3?
|
535
|
+
contents
|
536
|
+
end
|
532
537
|
else
|
533
|
-
|
538
|
+
lambda do |f|
|
539
|
+
contents = f.inputs(*args)
|
540
|
+
template.concat(contents) if ::Formtastic::Util.rails3?
|
541
|
+
contents
|
542
|
+
end
|
534
543
|
end
|
535
544
|
|
536
545
|
fields_for_args = [options.delete(:for), options.delete(:for_options) || {}].flatten
|
@@ -541,7 +550,7 @@ module Formtastic #:nodoc:
|
|
541
550
|
#
|
542
551
|
def strip_formtastic_options(options) #:nodoc:
|
543
552
|
options.except(:value_method, :label_method, :collection, :required, :label,
|
544
|
-
:as, :hint, :input_html, :label_html, :value_as_class)
|
553
|
+
:as, :hint, :input_html, :label_html, :value_as_class, :find_options)
|
545
554
|
end
|
546
555
|
|
547
556
|
# Determins if the attribute (eg :title) should be considered required or not.
|
@@ -889,15 +898,20 @@ module Formtastic #:nodoc:
|
|
889
898
|
html_options[:checked] = selected_value == value if selected_option_is_present
|
890
899
|
|
891
900
|
li_content = template.content_tag(:label,
|
892
|
-
Formtastic::Util.html_safe("#{self.radio_button(input_name, value, html_options)} #{label}"),
|
901
|
+
Formtastic::Util.html_safe("#{self.radio_button(input_name, value, html_options)} #{escape_html_entities(label)}"),
|
893
902
|
:for => input_id
|
894
903
|
)
|
895
904
|
|
896
905
|
li_options = value_as_class ? { :class => [method.to_s.singularize, value.to_s.downcase].join('_') } : {}
|
897
906
|
template.content_tag(:li, Formtastic::Util.html_safe(li_content), li_options)
|
898
907
|
end
|
899
|
-
|
900
|
-
|
908
|
+
|
909
|
+
template.content_tag(:fieldset,
|
910
|
+
template.content_tag(:legend,
|
911
|
+
template.label_tag(nil, localized_string(method, options[:label], :label) || humanized_attribute_name(method), :for => nil), :class => :label
|
912
|
+
) <<
|
913
|
+
template.content_tag(:ol, Formtastic::Util.html_safe(list_item_content.join))
|
914
|
+
)
|
901
915
|
end
|
902
916
|
alias :boolean_radio_input :radio_input
|
903
917
|
|
@@ -1016,6 +1030,7 @@ module Formtastic #:nodoc:
|
|
1016
1030
|
i18n_date_order = ::I18n.t(:order, :scope => [:date])
|
1017
1031
|
i18n_date_order = nil unless i18n_date_order.is_a?(Array)
|
1018
1032
|
inputs = options.delete(:order) || i18n_date_order || [:year, :month, :day]
|
1033
|
+
inputs = [] if options[:ignore_date]
|
1019
1034
|
labels = options.delete(:labels) || {}
|
1020
1035
|
|
1021
1036
|
time_inputs = [:hour, :minute]
|
@@ -1123,6 +1138,15 @@ module Formtastic #:nodoc:
|
|
1123
1138
|
# f.input :authors, :as => :check_boxes, :selected => Author.most_popular.collect(&:id)
|
1124
1139
|
# f.input :authors, :as => :check_boxes, :selected => nil # override any defaults: select none
|
1125
1140
|
#
|
1141
|
+
#
|
1142
|
+
# Formtastic works around a bug in rails handling of check box collections by
|
1143
|
+
# not generating the hidden fields for state checking of the checkboxes
|
1144
|
+
# The :hidden_fields option provides a way to re-enable these hidden inputs by
|
1145
|
+
# setting it to true.
|
1146
|
+
#
|
1147
|
+
# f.input :authors, :as => :check_boxes, hidden_fields => false
|
1148
|
+
# f.input :authors, :as => :check_boxes, hidden_fields => true
|
1149
|
+
#
|
1126
1150
|
# Finally, you can set :value_as_class => true if you want the li wrapper around each checkbox / label
|
1127
1151
|
# combination to contain a class with the value of the radio button (useful for applying specific
|
1128
1152
|
# CSS or Javascript to a particular checkbox).
|
@@ -1132,15 +1156,13 @@ module Formtastic #:nodoc:
|
|
1132
1156
|
html_options = options.delete(:input_html) || {}
|
1133
1157
|
|
1134
1158
|
input_name = generate_association_input_name(method)
|
1159
|
+
hidden_fields = options.delete(:hidden_fields)
|
1135
1160
|
value_as_class = options.delete(:value_as_class)
|
1136
1161
|
unchecked_value = options.delete(:unchecked_value) || ''
|
1137
1162
|
html_options = { :name => "#{@object_name}[#{input_name}][]" }.merge(html_options)
|
1138
1163
|
input_ids = []
|
1139
1164
|
|
1140
|
-
|
1141
|
-
selected_values = (options.key?(:checked) ? options[:checked] : options[:selected]) if selected_option_is_present
|
1142
|
-
selected_values = [*selected_values].compact
|
1143
|
-
|
1165
|
+
selected_values = find_selected_values_for_column(method, options)
|
1144
1166
|
disabled_option_is_present = options.key?(:disabled)
|
1145
1167
|
disabled_values = [*options[:disabled]] if disabled_option_is_present
|
1146
1168
|
|
@@ -1150,12 +1172,12 @@ module Formtastic #:nodoc:
|
|
1150
1172
|
input_id = generate_html_id(input_name, value.to_s.gsub(/\s/, '_').gsub(/\W/, '').downcase)
|
1151
1173
|
input_ids << input_id
|
1152
1174
|
|
1153
|
-
html_options[:checked] = selected_values.include?(value)
|
1175
|
+
html_options[:checked] = selected_values.include?(value)
|
1154
1176
|
html_options[:disabled] = disabled_values.include?(value) if disabled_option_is_present
|
1155
1177
|
html_options[:id] = input_id
|
1156
1178
|
|
1157
1179
|
li_content = template.content_tag(:label,
|
1158
|
-
Formtastic::Util.html_safe("#{self.
|
1180
|
+
Formtastic::Util.html_safe("#{self.create_check_boxes(input_name, html_options, value, unchecked_value, hidden_fields)} #{escape_html_entities(label)}"),
|
1159
1181
|
:for => input_id
|
1160
1182
|
)
|
1161
1183
|
|
@@ -1163,7 +1185,40 @@ module Formtastic #:nodoc:
|
|
1163
1185
|
template.content_tag(:li, Formtastic::Util.html_safe(li_content), li_options)
|
1164
1186
|
end
|
1165
1187
|
|
1166
|
-
|
1188
|
+
template.content_tag(:fieldset,
|
1189
|
+
template.content_tag(:legend,
|
1190
|
+
template.label_tag(nil, localized_string(method, options[:label], :label) || humanized_attribute_name(method), :for => nil), :class => :label
|
1191
|
+
) <<
|
1192
|
+
template.content_tag(:ol, Formtastic::Util.html_safe(list_item_content.join))
|
1193
|
+
)
|
1194
|
+
end
|
1195
|
+
|
1196
|
+
# Used by check_boxes input. The selected values will be set either by:
|
1197
|
+
#
|
1198
|
+
# * Explicitly provided through :selected or :checked
|
1199
|
+
# * Values retrieved through an association
|
1200
|
+
#
|
1201
|
+
# If the collection is not a hash or an array of strings, fixnums or symbols,
|
1202
|
+
# we use value_method to retrieve an array with the values
|
1203
|
+
#
|
1204
|
+
def find_selected_values_for_column(method, options)
|
1205
|
+
selected_option_is_present = [:selected, :checked].any? { |k| options.key?(k) }
|
1206
|
+
if selected_option_is_present
|
1207
|
+
selected_values = (options.key?(:checked) ? options[:checked] : options[:selected])
|
1208
|
+
elsif object.respond_to?(method)
|
1209
|
+
collection = [object.send(method)].compact.flatten
|
1210
|
+
label, value = detect_label_and_value_method!(collection, options)
|
1211
|
+
selected_values = collection.map { |o| send_or_call(value, o) }
|
1212
|
+
end
|
1213
|
+
selected_values = [*selected_values].compact
|
1214
|
+
selected_values
|
1215
|
+
end
|
1216
|
+
|
1217
|
+
# Outputs a checkbox tag. If called with no_hidden_input = true a plain check_box_tag is returned,
|
1218
|
+
# otherwise the helper uses the output generated by the rails check_box method.
|
1219
|
+
def create_check_boxes(input_name, html_options = {}, checked_value = "1", unchecked_value = "0", hidden_fields = false)
|
1220
|
+
return template.check_box_tag(input_name, checked_value, html_options[:checked], html_options) unless hidden_fields == true
|
1221
|
+
self.check_box(input_name, html_options, checked_value, unchecked_value)
|
1167
1222
|
end
|
1168
1223
|
|
1169
1224
|
# Outputs a country select input, wrapping around a regular country_select helper.
|
@@ -1224,7 +1279,7 @@ module Formtastic #:nodoc:
|
|
1224
1279
|
#
|
1225
1280
|
def inline_hints_for(method, options) #:nodoc:
|
1226
1281
|
options[:hint] = localized_string(method, options[:hint], :hint)
|
1227
|
-
return if options[:hint].blank?
|
1282
|
+
return if options[:hint].blank? or options[:hint].kind_of? Hash
|
1228
1283
|
template.content_tag(:p, Formtastic::Util.html_safe(options[:hint]), :class => 'inline-hints')
|
1229
1284
|
end
|
1230
1285
|
|
@@ -1311,7 +1366,7 @@ module Formtastic #:nodoc:
|
|
1311
1366
|
html_options.except(:builder, :parent)
|
1312
1367
|
)
|
1313
1368
|
|
1314
|
-
template.concat(fieldset) if block_given? &&
|
1369
|
+
template.concat(fieldset) if block_given? && !Formtastic::Util.rails3?
|
1315
1370
|
fieldset
|
1316
1371
|
end
|
1317
1372
|
|
@@ -1402,7 +1457,8 @@ module Formtastic #:nodoc:
|
|
1402
1457
|
|
1403
1458
|
# Return if we have an Array of strings, fixnums or arrays
|
1404
1459
|
return collection if (collection.instance_of?(Array) || collection.instance_of?(Range)) &&
|
1405
|
-
[Array, Fixnum, String, Symbol].include?(collection.first.class)
|
1460
|
+
[Array, Fixnum, String, Symbol].include?(collection.first.class) &&
|
1461
|
+
!(options.include?(:label_method) || options.include?(:value_method))
|
1406
1462
|
|
1407
1463
|
label, value = detect_label_and_value_method!(collection, options)
|
1408
1464
|
collection.map { |o| [send_or_call(label, o), send_or_call(value, o)] }
|
@@ -1419,7 +1475,6 @@ module Formtastic #:nodoc:
|
|
1419
1475
|
if conditions = reflection.options[:conditions]
|
1420
1476
|
options[:find_options][:conditions] = reflection.klass.merge_conditions(conditions, options[:find_options][:conditions])
|
1421
1477
|
end
|
1422
|
-
|
1423
1478
|
reflection.klass.find(:all, options[:find_options])
|
1424
1479
|
else
|
1425
1480
|
create_boolean_collection(options)
|
@@ -1542,7 +1597,8 @@ module Formtastic #:nodoc:
|
|
1542
1597
|
elsif type == :numeric || column.nil? || column.limit.nil?
|
1543
1598
|
{ :size => @@default_text_field_size }
|
1544
1599
|
else
|
1545
|
-
{ :maxlength => column.limit,
|
1600
|
+
{ :maxlength => column.limit,
|
1601
|
+
:size => @@default_text_field_size && [column.limit, @@default_text_field_size].min }
|
1546
1602
|
end
|
1547
1603
|
end
|
1548
1604
|
|
@@ -1622,7 +1678,7 @@ module Formtastic #:nodoc:
|
|
1622
1678
|
key = value if value.is_a?(::Symbol)
|
1623
1679
|
|
1624
1680
|
if value.is_a?(::String)
|
1625
|
-
value
|
1681
|
+
escape_html_entities(value)
|
1626
1682
|
else
|
1627
1683
|
use_i18n = value.nil? ? @@i18n_lookups_by_default : (value != false)
|
1628
1684
|
|
@@ -1644,6 +1700,7 @@ module Formtastic #:nodoc:
|
|
1644
1700
|
|
1645
1701
|
i18n_value = ::Formtastic::I18n.t(defaults.shift,
|
1646
1702
|
options.merge(:default => defaults, :scope => type.to_s.pluralize.to_sym))
|
1703
|
+
i18n_value = escape_html_entities(i18n_value) if i18n_value.is_a?(::String)
|
1647
1704
|
i18n_value.blank? ? nil : i18n_value
|
1648
1705
|
end
|
1649
1706
|
end
|
@@ -1676,6 +1733,14 @@ module Formtastic #:nodoc:
|
|
1676
1733
|
options
|
1677
1734
|
end
|
1678
1735
|
|
1736
|
+
def escape_html_entities(string) #:nodoc:
|
1737
|
+
if @@escape_html_entities_in_hints_and_labels
|
1738
|
+
# Acceppt html_safe flag as indicator to skip escaping
|
1739
|
+
string = template.escape_once(string) unless string.respond_to?(:html_safe?) && string.html_safe? == true
|
1740
|
+
end
|
1741
|
+
string
|
1742
|
+
end
|
1743
|
+
|
1679
1744
|
end
|
1680
1745
|
|
1681
1746
|
# Wrappers around form_for (etc) with :builder => SemanticFormBuilder.
|
@@ -1713,9 +1778,7 @@ module Formtastic #:nodoc:
|
|
1713
1778
|
module SemanticFormHelper
|
1714
1779
|
@@builder = ::Formtastic::SemanticFormBuilder
|
1715
1780
|
mattr_accessor :builder
|
1716
|
-
|
1717
|
-
@@default_field_error_proc = nil
|
1718
|
-
|
1781
|
+
|
1719
1782
|
# Override the default ActiveRecordHelper behaviour of wrapping the input.
|
1720
1783
|
# This gets taken care of semantically by adding an error class to the LI tag
|
1721
1784
|
# containing the input.
|
@@ -1725,11 +1788,11 @@ module Formtastic #:nodoc:
|
|
1725
1788
|
end
|
1726
1789
|
|
1727
1790
|
def with_custom_field_error_proc(&block)
|
1728
|
-
|
1791
|
+
default_field_error_proc = ::ActionView::Base.field_error_proc
|
1729
1792
|
::ActionView::Base.field_error_proc = FIELD_ERROR_PROC
|
1730
|
-
|
1731
|
-
|
1732
|
-
|
1793
|
+
yield
|
1794
|
+
ensure
|
1795
|
+
::ActionView::Base.field_error_proc = default_field_error_proc
|
1733
1796
|
end
|
1734
1797
|
|
1735
1798
|
def semantic_remote_form_for_wrapper(record_or_name_or_array, *args, &proc)
|
@@ -1749,12 +1812,14 @@ module Formtastic #:nodoc:
|
|
1749
1812
|
options[:builder] ||= @@builder
|
1750
1813
|
options[:html] ||= {}
|
1751
1814
|
|
1815
|
+
singularizer = defined?(ActiveModel::Naming.singular) ? ActiveModel::Naming.method(:singular) : ActionController::RecordIdentifier.method(:singular_class_name)
|
1816
|
+
|
1752
1817
|
class_names = options[:html][:class] ? options[:html][:class].split(" ") : []
|
1753
1818
|
class_names << "formtastic"
|
1754
1819
|
class_names << case record_or_name_or_array
|
1755
1820
|
when String, Symbol then record_or_name_or_array.to_s # :post => "post"
|
1756
|
-
when Array then
|
1757
|
-
else
|
1821
|
+
when Array then singularizer.call(record_or_name_or_array.last.class) # [@post, @comment] # => "comment"
|
1822
|
+
else singularizer.call(record_or_name_or_array.class) # @post => "post"
|
1758
1823
|
end
|
1759
1824
|
options[:html][:class] = class_names.join(" ")
|
1760
1825
|
|