simple_form 1.4.0 → 1.4.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of simple_form might be problematic. Click here for more details.
- data/.travis.yml +1 -0
- data/CHANGELOG.rdoc +11 -0
- data/Gemfile +1 -1
- data/README.rdoc +23 -2
- data/lib/generators/simple_form/templates/simple_form.rb +2 -2
- data/lib/simple_form/action_view_extensions/form_helper.rb +3 -1
- data/lib/simple_form/form_builder.rb +2 -2
- data/lib/simple_form/inputs/base.rb +14 -6
- data/lib/simple_form/version.rb +1 -1
- data/test/action_view_extensions/form_helper_test.rb +12 -0
- data/test/components/label_test.rb +19 -0
- data/test/form_builder_test.rb +35 -6
- data/test/inputs_test.rb +8 -0
- data/test/support/models.rb +5 -0
- metadata +5 -7
data/.travis.yml
CHANGED
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
== 1.4.1
|
2
|
+
|
3
|
+
* enhancements
|
4
|
+
* ignore required attribute when conditional validations are present
|
5
|
+
|
6
|
+
* bug fix
|
7
|
+
* Do not use required='required' when browser validations are turned off
|
8
|
+
* Sanitize HMTL attributes in error and hint helpers when options are present
|
9
|
+
* Improve i18n lookup by ignoring explicit child index given to form builder (tests by github.com/rywall)
|
10
|
+
* Fixes the form specific validation option if specified on the form itself (by github.com/medihack)
|
11
|
+
|
1
12
|
== 1.4.0
|
2
13
|
|
3
14
|
* enhancements
|
data/Gemfile
CHANGED
data/README.rdoc
CHANGED
@@ -232,6 +232,16 @@ All web forms need buttons, right? SimpleForm wraps them in the DSL, acting like
|
|
232
232
|
|
233
233
|
The above will simply call submit. You choose to use it or not, it's just a question of taste.
|
234
234
|
|
235
|
+
== Wrapping Rails Form Helpers
|
236
|
+
|
237
|
+
Say you wanted to use a rails form helper but still wrap it in SimpleForm goodness? You can, by calling input with a block like so:
|
238
|
+
|
239
|
+
<%= f.input :role do %>
|
240
|
+
<%= f.select :role, Role.all.map { |r| [r.name, r.id, { :class => r.company.id }] }, :include_blank => true %>
|
241
|
+
<% end %>
|
242
|
+
|
243
|
+
In the above example, we're taking advantage of Rails 3's select method that allows us to pass in a hash of additional attributes for each option.
|
244
|
+
|
235
245
|
== Extra helpers
|
236
246
|
|
237
247
|
SimpleForm also comes with some extra helpers you can use inside rails default forms without relying on simple_form_for helper. They are listed below.
|
@@ -275,6 +285,13 @@ Creates a collection of check boxes with labels associated (same API as collecti
|
|
275
285
|
<input id="user_options_false" name="user[options][]" type="checkbox" value="false" />
|
276
286
|
<label class="collection_check_box" for="user_options_false">No</label>
|
277
287
|
|
288
|
+
To use this with associations in your model, you can do the following:
|
289
|
+
|
290
|
+
form_for @user do |f|
|
291
|
+
f.collection_check_boxes :role_ids, Role.all, :id, :name # using :roles here is not going to work.
|
292
|
+
end
|
293
|
+
|
294
|
+
|
278
295
|
== Mappings/Inputs available
|
279
296
|
|
280
297
|
SimpleForm comes with a lot of default mappings:
|
@@ -308,9 +325,9 @@ SimpleForm comes with a lot of default mappings:
|
|
308
325
|
It is very easy to add custom inputs to SimpleForm. For instance, if you want to add a custom input that extends the string one, you just need to add this file:
|
309
326
|
|
310
327
|
# app/inputs/currency_input.rb
|
311
|
-
class CurrencyInput < SimpleForm::Inputs::
|
328
|
+
class CurrencyInput < SimpleForm::Inputs::Base
|
312
329
|
def input
|
313
|
-
"$ #{
|
330
|
+
"$ #{@builder.text_field(attribute_name, input_html_options)}".html_safe
|
314
331
|
end
|
315
332
|
end
|
316
333
|
|
@@ -425,6 +442,10 @@ If you want to have all other HTML 5 features, such as the new field types, you
|
|
425
442
|
|
426
443
|
This option adds a new `novalidate` property to the form, instructing it to skip all HTML 5 validation. The inputs will still be generated with the required and other attributes, that might help you to use some generic javascript validation.
|
427
444
|
|
445
|
+
You can also add `novalidate` to a specific form by setting the option on the form itself:
|
446
|
+
|
447
|
+
<%= simple_form_for(resource, :html => {:novalidate => true}) do |form| %>
|
448
|
+
|
428
449
|
Please notice that any of the configurations above will disable the `placeholder` component, which is an HTML 5 feature. We believe most of the newest browsers are handling this attribute fine, and if they aren't, any plugin you use would take of using the placeholder attribute to do it. However, you can disable it if you want, by removing the placeholder component from the components list in SimpleForm configuration file.
|
429
450
|
|
430
451
|
== Configuration
|
@@ -43,10 +43,10 @@ SimpleForm.setup do |config|
|
|
43
43
|
# You can wrap each item in a collection of radio/check boxes with a tag, defaulting to span.
|
44
44
|
# config.item_wrapper_tag = :span
|
45
45
|
|
46
|
-
# Series of
|
46
|
+
# Series of attempts to detect a default label method for collection.
|
47
47
|
# config.collection_label_methods = [ :to_label, :name, :title, :to_s ]
|
48
48
|
|
49
|
-
# Series of
|
49
|
+
# Series of attempts to detect a default value method for collection.
|
50
50
|
# config.collection_value_methods = [ :id, :to_s ]
|
51
51
|
|
52
52
|
# How the label text should be generated altogether with the required text.
|
@@ -40,7 +40,9 @@ module SimpleForm
|
|
40
40
|
else dom_class(record_or_name_or_array)
|
41
41
|
end
|
42
42
|
options[:html] ||= {}
|
43
|
-
options[:html]
|
43
|
+
unless options[:html].key?(:novalidate)
|
44
|
+
options[:html][:novalidate] = !SimpleForm.browser_validations
|
45
|
+
end
|
44
46
|
options[:html][:class] = "\#{SimpleForm.form_class} \#{css_class} \#{options[:html][:class]}".strip
|
45
47
|
|
46
48
|
with_custom_field_error_proc do
|
@@ -204,7 +204,7 @@ module SimpleForm
|
|
204
204
|
# f.error :name, :id => "cool_error"
|
205
205
|
#
|
206
206
|
def error(attribute_name, options={})
|
207
|
-
options[:error_html] = options.
|
207
|
+
options[:error_html] = options.except(:error_tag, :error_prefix, :error_method)
|
208
208
|
column = find_attribute_column(attribute_name)
|
209
209
|
input_type = default_input_type(attribute_name, column, options)
|
210
210
|
SimpleForm::Inputs::Base.new(self, attribute_name, column, input_type, options).error
|
@@ -238,7 +238,7 @@ module SimpleForm
|
|
238
238
|
# f.hint "Don't forget to accept this"
|
239
239
|
#
|
240
240
|
def hint(attribute_name, options={})
|
241
|
-
options[:hint_html] = options.
|
241
|
+
options[:hint_html] = options.except(:hint_tag)
|
242
242
|
if attribute_name.is_a?(String)
|
243
243
|
options[:hint] = attribute_name
|
244
244
|
attribute_name, column, input_type = nil, nil, nil
|
@@ -66,7 +66,9 @@ module SimpleForm
|
|
66
66
|
if !options[:required].nil?
|
67
67
|
options[:required]
|
68
68
|
elsif has_validators?
|
69
|
-
(attribute_validators + reflection_validators).any?
|
69
|
+
(attribute_validators + reflection_validators).any? do |v|
|
70
|
+
v.kind == :presence && !conditional_validators?(v)
|
71
|
+
end
|
70
72
|
else
|
71
73
|
attribute_required_by_default?
|
72
74
|
end
|
@@ -74,7 +76,7 @@ module SimpleForm
|
|
74
76
|
|
75
77
|
# Whether this input is valid for HTML 5 required attribute.
|
76
78
|
def has_required?
|
77
|
-
attribute_required? && SimpleForm.html5
|
79
|
+
attribute_required? && SimpleForm.html5 && SimpleForm.browser_validations
|
78
80
|
end
|
79
81
|
|
80
82
|
def has_autofocus?
|
@@ -93,6 +95,10 @@ module SimpleForm
|
|
93
95
|
reflection ? object.class.validators_on(reflection.name) : []
|
94
96
|
end
|
95
97
|
|
98
|
+
def conditional_validators?(validator)
|
99
|
+
validator.options.include?(:if) || validator.options.include?(:unless)
|
100
|
+
end
|
101
|
+
|
96
102
|
def attribute_required_by_default?
|
97
103
|
SimpleForm.required_by_default
|
98
104
|
end
|
@@ -169,7 +175,8 @@ module SimpleForm
|
|
169
175
|
I18n.t(lookups.shift, :scope => :"simple_form.#{namespace}", :default => lookups).presence
|
170
176
|
end
|
171
177
|
|
172
|
-
# Extract the model names from the object_name mess
|
178
|
+
# Extract the model names from the object_name mess, ignoring numeric and
|
179
|
+
# explicit child indexes.
|
173
180
|
#
|
174
181
|
# Example:
|
175
182
|
#
|
@@ -177,9 +184,10 @@ module SimpleForm
|
|
177
184
|
# ["route", "blocks", "blocks_learning_object", "foo"]
|
178
185
|
#
|
179
186
|
def lookup_model_names
|
180
|
-
|
181
|
-
|
182
|
-
|
187
|
+
child_index = @builder.options[:child_index]
|
188
|
+
names = object_name.to_s.scan(/([a-zA-Z_]+)/).flatten
|
189
|
+
names.delete(child_index) if child_index
|
190
|
+
names.each { |name| name.gsub!('_attributes', '') }
|
183
191
|
end
|
184
192
|
|
185
193
|
# The action to be used in lookup.
|
data/lib/simple_form/version.rb
CHANGED
@@ -25,6 +25,18 @@ class FormHelperTest < ActionView::TestCase
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
+
test 'a form specific disabled validation option should override the default enabled browser validation configuration option' do
|
29
|
+
concat(simple_form_for(:user, :html => { :novalidate => true }) do |f| end)
|
30
|
+
assert_select 'form[novalidate="novalidate"]'
|
31
|
+
end
|
32
|
+
|
33
|
+
test 'a form specific enabled validation option should override the disabled browser validation configuration option' do
|
34
|
+
swap SimpleForm, :browser_validations => false do
|
35
|
+
concat(simple_form_for(:user, :html => { :novalidate => false }) do |f| end)
|
36
|
+
assert_no_select 'form[novalidate]'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
28
40
|
test 'simple form should add object name as css class to form when object is not present' do
|
29
41
|
concat(simple_form_for(:user) do |f| end)
|
30
42
|
assert_select 'form.simple_form.user'
|
@@ -133,6 +133,25 @@ class LabelTest < ActionView::TestCase
|
|
133
133
|
end
|
134
134
|
end
|
135
135
|
|
136
|
+
test 'label should do correct i18n lookup for nested has_many models with no nested translation' do
|
137
|
+
@user.tags = [Tag.new(1, 'Empresa')]
|
138
|
+
|
139
|
+
store_translations(:en, :simple_form => { :labels => {
|
140
|
+
:user => { :name => 'Usuario' },
|
141
|
+
:tags => { :name => 'Nome da empresa' }
|
142
|
+
} } ) do
|
143
|
+
with_concat_form_for @user do |f|
|
144
|
+
concat f.input :name
|
145
|
+
concat(f.simple_fields_for(:tags, :child_index => "new_index") do |tags_form|
|
146
|
+
concat(tags_form.input :name)
|
147
|
+
end)
|
148
|
+
end
|
149
|
+
|
150
|
+
assert_select 'label[for=user_name]', /Usuario/
|
151
|
+
assert_select 'label[for=user_tags_attributes_new_index_name]', /Nome da empresa/
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
136
155
|
test 'label should have css class from type' do
|
137
156
|
with_label_for @user, :name, :string
|
138
157
|
assert_select 'label.string'
|
data/test/form_builder_test.rb
CHANGED
@@ -52,7 +52,7 @@ class FormBuilderTest < ActionView::TestCase
|
|
52
52
|
end
|
53
53
|
|
54
54
|
# All
|
55
|
-
test 'nested simple fields should
|
55
|
+
test 'nested simple fields should yield an instance of FormBuilder' do
|
56
56
|
simple_form_for :user do |f|
|
57
57
|
f.simple_fields_for :posts do |posts_form|
|
58
58
|
assert posts_form.instance_of?(SimpleForm::FormBuilder)
|
@@ -90,7 +90,7 @@ class FormBuilderTest < ActionView::TestCase
|
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
93
|
-
test 'builder uses the first matching custom input map when more than one
|
93
|
+
test 'builder uses the first matching custom input map when more than one matches' do
|
94
94
|
swap SimpleForm, :input_mappings => { /count$/ => :integer, /^post_/ => :password } do
|
95
95
|
with_form_for @user, :post_count
|
96
96
|
assert_no_select 'form input#user_post_count.password'
|
@@ -338,6 +338,20 @@ class FormBuilderTest < ActionView::TestCase
|
|
338
338
|
assert_select 'input.optional#user_name'
|
339
339
|
end
|
340
340
|
|
341
|
+
test 'builder input should not be required when ActiveModel::Validations is included and if option is present' do
|
342
|
+
with_form_for @validating_user, :age
|
343
|
+
assert_no_select 'input.required'
|
344
|
+
assert_no_select 'input[required]'
|
345
|
+
assert_select 'input.optional#validating_user_age'
|
346
|
+
end
|
347
|
+
|
348
|
+
test 'builder input should not be required when ActiveModel::Validations is included and unless option is present' do
|
349
|
+
with_form_for @validating_user, :amount
|
350
|
+
assert_no_select 'input.required'
|
351
|
+
assert_no_select 'input[required]'
|
352
|
+
assert_select 'input.optional#validating_user_amount'
|
353
|
+
end
|
354
|
+
|
341
355
|
# WRAPPERS
|
342
356
|
test 'builder support wrapping around an specific tag' do
|
343
357
|
swap SimpleForm, :wrapper_tag => :p do
|
@@ -456,6 +470,14 @@ class FormBuilderTest < ActionView::TestCase
|
|
456
470
|
assert_no_select 'span.error[error_html]'
|
457
471
|
end
|
458
472
|
|
473
|
+
test 'builder should generate an error tag with a clean HTML when errors options are present' do
|
474
|
+
with_error_for @user, :name, :error_tag => :p, :error_prefix => 'Name', :error_method => :first
|
475
|
+
assert_no_select 'p.error[error_html]'
|
476
|
+
assert_no_select 'p.error[error_tag]'
|
477
|
+
assert_no_select 'p.error[error_prefix]'
|
478
|
+
assert_no_select 'p.error[error_method]'
|
479
|
+
end
|
480
|
+
|
459
481
|
test 'builder should allow passing options to error tag' do
|
460
482
|
with_error_for @user, :name, :id => 'name_error'
|
461
483
|
assert_select 'span.error#name_error', "can't be blank"
|
@@ -501,6 +523,13 @@ class FormBuilderTest < ActionView::TestCase
|
|
501
523
|
assert_no_select 'span.hint[hint_html]'
|
502
524
|
end
|
503
525
|
|
526
|
+
test 'builder should generate a hint componet tag with a clean HTML when hint_tag option is present' do
|
527
|
+
with_hint_for @user, 'Hello World!', :hint_tag => :p
|
528
|
+
assert_no_select 'p.hint[hint]'
|
529
|
+
assert_no_select 'p.hint[hint_html]'
|
530
|
+
assert_no_select 'p.hint[hint_tag]'
|
531
|
+
end
|
532
|
+
|
504
533
|
test 'builder should allow passing options to hint tag' do
|
505
534
|
with_hint_for @user, :name, :hint => 'Hello World!', :id => 'name_hint'
|
506
535
|
assert_select 'span.hint#name_hint', 'Hello World!'
|
@@ -559,7 +588,7 @@ class FormBuilderTest < ActionView::TestCase
|
|
559
588
|
end
|
560
589
|
end
|
561
590
|
|
562
|
-
test 'builder association with a block
|
591
|
+
test 'builder association with a block calls simple_fields_for' do
|
563
592
|
simple_form_for @user do |f|
|
564
593
|
f.association :posts do |posts_form|
|
565
594
|
assert posts_form.instance_of?(SimpleForm::FormBuilder)
|
@@ -578,7 +607,7 @@ class FormBuilderTest < ActionView::TestCase
|
|
578
607
|
assert_equal 3, calls
|
579
608
|
end
|
580
609
|
|
581
|
-
test 'builder association
|
610
|
+
test 'builder association marks input as required based on both association and attribute' do
|
582
611
|
swap SimpleForm, :required_by_default => false do
|
583
612
|
with_association_for @validating_user, :company, :collection => []
|
584
613
|
assert_select 'label.required'
|
@@ -595,7 +624,7 @@ class FormBuilderTest < ActionView::TestCase
|
|
595
624
|
assert_select 'form select option[value=3]', 'Tag 3'
|
596
625
|
end
|
597
626
|
|
598
|
-
test 'builder does not preload collection association if preload false' do
|
627
|
+
test 'builder does not preload collection association if preload is false' do
|
599
628
|
value = @user.company
|
600
629
|
value.expects(:to_a).never
|
601
630
|
with_association_for @user, :company, :preload => false
|
@@ -605,7 +634,7 @@ class FormBuilderTest < ActionView::TestCase
|
|
605
634
|
assert_select 'form select option[value=3]', 'Company 3'
|
606
635
|
end
|
607
636
|
|
608
|
-
test 'builder does not preload non
|
637
|
+
test 'builder does not preload non-collection association' do
|
609
638
|
value = @user.company
|
610
639
|
value.expects(:to_a).never
|
611
640
|
with_association_for @user, :company, :preload => false
|
data/test/inputs_test.rb
CHANGED
@@ -780,6 +780,14 @@ class InputTest < ActionView::TestCase
|
|
780
780
|
end
|
781
781
|
end
|
782
782
|
|
783
|
+
test 'when not using browser validations, input should not generate required html attribute' do
|
784
|
+
swap SimpleForm, :browser_validations => false do
|
785
|
+
with_input_for @user, :name, :string
|
786
|
+
assert_select 'input[type=text].required'
|
787
|
+
assert_no_select 'input[type=text][required]'
|
788
|
+
end
|
789
|
+
end
|
790
|
+
|
783
791
|
test 'collection input with select type should not generate invalid required html attribute' do
|
784
792
|
with_input_for @user, :name, :select, :collection => ['Jose' , 'Carlos']
|
785
793
|
assert_select 'select.required'
|
data/test/support/models.rb
CHANGED
@@ -61,6 +61,9 @@ class User
|
|
61
61
|
def company_attributes=(*)
|
62
62
|
end
|
63
63
|
|
64
|
+
def tags_attributes=(*)
|
65
|
+
end
|
66
|
+
|
64
67
|
def column_for_attribute(attribute)
|
65
68
|
column_type, limit = case attribute.to_sym
|
66
69
|
when :name, :status, :password then [:string, 100]
|
@@ -124,6 +127,8 @@ class ValidatingUser < User
|
|
124
127
|
include ActiveModel::Validations
|
125
128
|
validates :name, :presence => true
|
126
129
|
validates :company, :presence => true
|
130
|
+
validates :age, :presence => true, :if => Proc.new { |user| user.name }
|
131
|
+
validates :amount, :presence => true, :unless => Proc.new { |user| user.age }
|
127
132
|
validates_numericality_of :age,
|
128
133
|
:greater_than_or_equal_to => 18,
|
129
134
|
:less_than_or_equal_to => 99,
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple_form
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 5
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 4
|
9
|
-
-
|
10
|
-
version: 1.4.
|
9
|
+
- 1
|
10
|
+
version: 1.4.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- "Jos\xC3\xA9 Valim"
|
@@ -16,8 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2011-
|
20
|
-
default_executable:
|
19
|
+
date: 2011-06-14 00:00:00 Z
|
21
20
|
dependencies: []
|
22
21
|
|
23
22
|
description: Forms made easy!
|
@@ -90,7 +89,6 @@ files:
|
|
90
89
|
- test/support/mock_response.rb
|
91
90
|
- test/support/models.rb
|
92
91
|
- test/test_helper.rb
|
93
|
-
has_rdoc: true
|
94
92
|
homepage: http://github.com/plataformatec/simple_form
|
95
93
|
licenses: []
|
96
94
|
|
@@ -120,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
120
118
|
requirements: []
|
121
119
|
|
122
120
|
rubyforge_project: simple_form
|
123
|
-
rubygems_version: 1.
|
121
|
+
rubygems_version: 1.8.5
|
124
122
|
signing_key:
|
125
123
|
specification_version: 3
|
126
124
|
summary: Forms made easy!
|