simple_form 1.3.0 → 1.3.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/.gitignore +2 -0
- data/.gitmodules +3 -0
- data/CHANGELOG.rdoc +85 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +82 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +16 -2
- data/Rakefile +27 -0
- data/lib/generators/simple_form/templates/_form.html.haml +2 -2
- data/lib/simple_form/action_view_extensions/builder.rb +30 -5
- data/lib/simple_form/action_view_extensions/form_helper.rb +3 -4
- data/lib/simple_form/components/labels.rb +1 -1
- data/lib/simple_form/form_builder.rb +18 -13
- data/lib/simple_form/inputs/base.rb +13 -3
- data/lib/simple_form/inputs/collection_input.rb +5 -0
- data/lib/simple_form/inputs/date_time_input.rb +4 -0
- data/lib/simple_form/inputs/priority_input.rb +5 -1
- data/lib/simple_form/map_type.rb +5 -2
- data/lib/simple_form/version.rb +1 -1
- data/simple_form.gemspec +22 -0
- data/test/components/label_test.rb +10 -0
- data/test/form_builder_test.rb +49 -0
- data/test/inputs_test.rb +84 -0
- data/test/support/misc_helpers.rb +14 -0
- data/test/support/models.rb +2 -1
- metadata +20 -27
data/.gitignore
ADDED
data/.gitmodules
ADDED
data/CHANGELOG.rdoc
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
* enhancements
|
2
|
+
* Add :autofocus HTML5 attribute support (by github.com/jpzwarte)
|
3
|
+
* Add possibility to specify custom builder and inherit mappings (by github.com/rejeep)
|
4
|
+
* Make custom mappings work with all attributes types (by github.com/rafaelfranca)
|
5
|
+
* Add support for procs/lambdas in text/value methods for collection_select
|
6
|
+
|
7
|
+
* deprecation
|
8
|
+
* removed the deprecated :remote_form_for
|
9
|
+
|
10
|
+
* bug fix
|
11
|
+
* Only add the "required" HTML 5 attribute for valid inputs, disable in selects (not allowed)
|
12
|
+
* Fix error when using hints without an attribute (by github.com/butsjoh and github.com/rafaelfranca)
|
13
|
+
* Fix messy html output for hint, error and label components (by github.com/butsjoh and github.com/rafaelfranca)
|
14
|
+
* Allow direct setting of for attribute on label (by github.com/Bertg)
|
15
|
+
|
16
|
+
== 1.3.0
|
17
|
+
|
18
|
+
* enhancements
|
19
|
+
* Allow collection input to accept a collection of symbols
|
20
|
+
* Add default css class to button
|
21
|
+
* Allow forms for objects that don't respond to the "errors" method
|
22
|
+
* collection_check_boxes and collection_radio now wrap the input in the label
|
23
|
+
* Automatic add min/max values for numeric attributes based on validations and step for integers - HTML5 (by github.com/dasch)
|
24
|
+
* Add :placeholder option for string inputs, allowing customization through I18n - HTML5 (by github.com/jonathan)
|
25
|
+
* Add :search and :tel input types, with :tel mapping automatically from attributes matching "phone" - HTML5
|
26
|
+
* Add :required html attribute for required inputs - HTML5
|
27
|
+
* Add optional :components option to input to control component rendering (by github.com/khoan)
|
28
|
+
* Add SimpleForm.translate as an easy way to turn off SimpleForm internal translations
|
29
|
+
* Add :disabled option for all inputs (by github.com/fabiob)
|
30
|
+
* Add collection wrapper tag and item wrapper tag to wrap elements in collection helpers - radio / check boxes
|
31
|
+
* Add SimpleForm.input_mappings to allow configuring custom mappings for inputs (by github.com/TMaYaD)
|
32
|
+
|
33
|
+
* bug fix
|
34
|
+
* Search for validations on both association and attribute
|
35
|
+
* Use controller.action_name to lookup action only when available, to fix issue with Rspec views tests (by github.com/rafaelfranca)
|
36
|
+
|
37
|
+
== 1.2.2
|
38
|
+
|
39
|
+
* enhancements
|
40
|
+
* Compatibility with Rails 3 RC
|
41
|
+
|
42
|
+
== 1.2.1
|
43
|
+
|
44
|
+
* enhancements
|
45
|
+
* Added haml generator support (by github.com/grimen)
|
46
|
+
* Added error_notification message to form builder
|
47
|
+
* Added required by default as configuration option
|
48
|
+
* Added label_input as component, allowing boolean to change its order (input appearing first than label)
|
49
|
+
* Added error_method to tidy up how errors are exhibited
|
50
|
+
* Added error class on wrappers (by github.com/jduff)
|
51
|
+
* Changed numeric types to have type=number for HTML5
|
52
|
+
|
53
|
+
== 1.2.0
|
54
|
+
|
55
|
+
* deprecation
|
56
|
+
* Changed simple_form_install generator to simple_form:install
|
57
|
+
|
58
|
+
* enhancements
|
59
|
+
* Added support to presence validation to check if attribute is required or not (by github.com/gcirne)
|
60
|
+
* Added .input as class to wrapper tag
|
61
|
+
* Added config options for hint and error tags (by github.com/tjogin)
|
62
|
+
|
63
|
+
== 1.1.3
|
64
|
+
|
65
|
+
* deprecation
|
66
|
+
* removed :conditions, :order, :joins and :include support in f.association
|
67
|
+
|
68
|
+
== 1.1.2
|
69
|
+
|
70
|
+
* bug fix
|
71
|
+
* Ensure type is set to "text" and not "string"
|
72
|
+
|
73
|
+
== 1.1.1
|
74
|
+
|
75
|
+
* bug fix
|
76
|
+
* Fix some escaping issues
|
77
|
+
|
78
|
+
== 1.1.0
|
79
|
+
|
80
|
+
* enhancements
|
81
|
+
* Rails 3 support with generators, templates and HTML 5
|
82
|
+
|
83
|
+
== 1.0
|
84
|
+
|
85
|
+
* First release
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
abstract (1.0.0)
|
5
|
+
actionmailer (3.0.3)
|
6
|
+
actionpack (= 3.0.3)
|
7
|
+
mail (~> 2.2.9)
|
8
|
+
actionpack (3.0.3)
|
9
|
+
activemodel (= 3.0.3)
|
10
|
+
activesupport (= 3.0.3)
|
11
|
+
builder (~> 2.1.2)
|
12
|
+
erubis (~> 2.6.6)
|
13
|
+
i18n (~> 0.4)
|
14
|
+
rack (~> 1.2.1)
|
15
|
+
rack-mount (~> 0.6.13)
|
16
|
+
rack-test (~> 0.5.6)
|
17
|
+
tzinfo (~> 0.3.23)
|
18
|
+
activemodel (3.0.3)
|
19
|
+
activesupport (= 3.0.3)
|
20
|
+
builder (~> 2.1.2)
|
21
|
+
i18n (~> 0.4)
|
22
|
+
activerecord (3.0.3)
|
23
|
+
activemodel (= 3.0.3)
|
24
|
+
activesupport (= 3.0.3)
|
25
|
+
arel (~> 2.0.2)
|
26
|
+
tzinfo (~> 0.3.23)
|
27
|
+
activeresource (3.0.3)
|
28
|
+
activemodel (= 3.0.3)
|
29
|
+
activesupport (= 3.0.3)
|
30
|
+
activesupport (3.0.3)
|
31
|
+
arel (2.0.6)
|
32
|
+
builder (2.1.2)
|
33
|
+
columnize (0.3.2)
|
34
|
+
erubis (2.6.6)
|
35
|
+
abstract (>= 1.0.0)
|
36
|
+
i18n (0.5.0)
|
37
|
+
linecache (0.43)
|
38
|
+
mail (2.2.12)
|
39
|
+
activesupport (>= 2.3.6)
|
40
|
+
i18n (>= 0.4.0)
|
41
|
+
mime-types (~> 1.16)
|
42
|
+
treetop (~> 1.4.8)
|
43
|
+
mime-types (1.16)
|
44
|
+
mocha (0.9.10)
|
45
|
+
rake
|
46
|
+
polyglot (0.3.1)
|
47
|
+
rack (1.2.1)
|
48
|
+
rack-mount (0.6.13)
|
49
|
+
rack (>= 1.0.0)
|
50
|
+
rack-test (0.5.6)
|
51
|
+
rack (>= 1.0)
|
52
|
+
rails (3.0.3)
|
53
|
+
actionmailer (= 3.0.3)
|
54
|
+
actionpack (= 3.0.3)
|
55
|
+
activerecord (= 3.0.3)
|
56
|
+
activeresource (= 3.0.3)
|
57
|
+
activesupport (= 3.0.3)
|
58
|
+
bundler (~> 1.0)
|
59
|
+
railties (= 3.0.3)
|
60
|
+
railties (3.0.3)
|
61
|
+
actionpack (= 3.0.3)
|
62
|
+
activesupport (= 3.0.3)
|
63
|
+
rake (>= 0.8.7)
|
64
|
+
thor (~> 0.14.4)
|
65
|
+
rake (0.8.7)
|
66
|
+
ruby-debug (0.10.4)
|
67
|
+
columnize (>= 0.1)
|
68
|
+
ruby-debug-base (~> 0.10.4.0)
|
69
|
+
ruby-debug-base (0.10.4)
|
70
|
+
linecache (>= 0.3)
|
71
|
+
thor (0.14.6)
|
72
|
+
treetop (1.4.9)
|
73
|
+
polyglot (>= 0.3.1)
|
74
|
+
tzinfo (0.3.23)
|
75
|
+
|
76
|
+
PLATFORMS
|
77
|
+
ruby
|
78
|
+
|
79
|
+
DEPENDENCIES
|
80
|
+
mocha
|
81
|
+
rails (~> 3.0.0)
|
82
|
+
ruby-debug
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 PlataformaTec http://blog.plataformatec.com.br/
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
CHANGED
@@ -370,9 +370,23 @@ SimpleForm has several configuration values. You can read and change them in the
|
|
370
370
|
|
371
371
|
rails generate simple_form:install
|
372
372
|
|
373
|
-
==
|
373
|
+
== Custom form builder
|
374
374
|
|
375
|
-
|
375
|
+
You can create a custom form builder that uses SimpleForm.
|
376
|
+
|
377
|
+
Create a helper method that calls simple_form_for with a custom builder:
|
378
|
+
|
379
|
+
def custom_form_for(object, *args, &block)
|
380
|
+
simple_form_for(object, *(args << { :builder => CustomFormBuilder }), &block)
|
381
|
+
end
|
382
|
+
|
383
|
+
Create a form builder class that inherits from SimpleForm::FormBuilder.
|
384
|
+
|
385
|
+
class CustomFormBuilder < SimpleForm::FormBuilder
|
386
|
+
def input(attribute_name, *args, &block)
|
387
|
+
super(attribute_name, *(args << { :input_html => { :class => 'custom' } }), &block)
|
388
|
+
end
|
389
|
+
end
|
376
390
|
|
377
391
|
== Maintainers
|
378
392
|
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'bundler'
|
4
|
+
Bundler::GemHelper.install_tasks
|
5
|
+
|
6
|
+
require 'rake/testtask'
|
7
|
+
require 'rake/rdoctask'
|
8
|
+
|
9
|
+
desc 'Default: run unit tests.'
|
10
|
+
task :default => :test
|
11
|
+
|
12
|
+
desc 'Test the simple_form plugin.'
|
13
|
+
Rake::TestTask.new(:test) do |t|
|
14
|
+
t.libs << 'lib'
|
15
|
+
t.libs << 'test'
|
16
|
+
t.pattern = 'test/**/*_test.rb'
|
17
|
+
t.verbose = true
|
18
|
+
end
|
19
|
+
|
20
|
+
desc 'Generate documentation for the simple_form plugin.'
|
21
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
22
|
+
rdoc.rdoc_dir = 'rdoc'
|
23
|
+
rdoc.title = 'SimpleForm'
|
24
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
25
|
+
rdoc.rdoc_files.include('README.rdoc')
|
26
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
27
|
+
end
|
@@ -6,8 +6,8 @@
|
|
6
6
|
prohibited this <%= singular_name %> from being saved:
|
7
7
|
|
8
8
|
%ul
|
9
|
-
|
10
|
-
|
9
|
+
- @<%= singular_name %>.errors.full_messages.each do |msg|
|
10
|
+
%li= msg
|
11
11
|
|
12
12
|
.inputs
|
13
13
|
<%- attributes.each do |attribute| -%>
|
@@ -7,7 +7,9 @@ module SimpleForm
|
|
7
7
|
# Create a collection of radio inputs for the attribute. Basically this
|
8
8
|
# helper will create a radio input associated with a label for each
|
9
9
|
# text/value option in the collection, using value_method and text_method
|
10
|
-
# to convert these text/value.
|
10
|
+
# to convert these text/value. You can give a symbol or a proc to both
|
11
|
+
# value_method and text_method, that will be evaluated for each item in
|
12
|
+
# the collection.
|
11
13
|
#
|
12
14
|
# == Examples
|
13
15
|
#
|
@@ -42,9 +44,11 @@ module SimpleForm
|
|
42
44
|
end
|
43
45
|
end
|
44
46
|
|
45
|
-
# Creates a collection of check boxes for each item in the collection,
|
46
|
-
# with a clickable label. Use value_method and text_method to
|
47
|
-
# the collection for use as text/value in check boxes.
|
47
|
+
# Creates a collection of check boxes for each item in the collection,
|
48
|
+
# associated with a clickable label. Use value_method and text_method to
|
49
|
+
# convert items in the collection for use as text/value in check boxes.
|
50
|
+
# You can give a symbol or a proc to both value_method and text_method,
|
51
|
+
# that will be evaluated for each item in the collection.
|
48
52
|
#
|
49
53
|
# == Examples
|
50
54
|
#
|
@@ -154,4 +158,25 @@ module SimpleForm
|
|
154
158
|
end
|
155
159
|
end
|
156
160
|
|
157
|
-
ActionView::Helpers::FormBuilder
|
161
|
+
class ActionView::Helpers::FormBuilder
|
162
|
+
include SimpleForm::ActionViewExtensions::Builder
|
163
|
+
|
164
|
+
# Override default Rails collection_select helper to handle lambdas/procs in
|
165
|
+
# text and value methods, so it works the same way as collection_radio and
|
166
|
+
# collection_check_boxes in SimpleForm. If none of text/value methods is a
|
167
|
+
# callable object, then it just delegates back to original collection select.
|
168
|
+
#
|
169
|
+
alias :original_collection_select :collection_select
|
170
|
+
def collection_select(attribute, collection, value_method, text_method, options={}, html_options={})
|
171
|
+
if value_method.respond_to?(:call) || text_method.respond_to?(:call)
|
172
|
+
collection = collection.map do |item|
|
173
|
+
value = value_for_collection(item, value_method)
|
174
|
+
text = value_for_collection(item, text_method)
|
175
|
+
[value, text]
|
176
|
+
end
|
177
|
+
value_method, text_method = :first, :last
|
178
|
+
end
|
179
|
+
|
180
|
+
original_collection_select(attribute, collection, value_method, text_method, options, html_options)
|
181
|
+
end
|
182
|
+
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module SimpleForm
|
2
2
|
module ActionViewExtensions
|
3
|
-
# This
|
4
|
-
# fields_for and remote_form_for.
|
3
|
+
# This module creates simple form wrappers around default form_for and fields_for.
|
5
4
|
#
|
6
5
|
# Example:
|
7
6
|
#
|
@@ -30,11 +29,11 @@ module SimpleForm
|
|
30
29
|
result
|
31
30
|
end
|
32
31
|
|
33
|
-
[:form_for, :fields_for
|
32
|
+
[:form_for, :fields_for].each do |helper|
|
34
33
|
class_eval <<-METHOD, __FILE__, __LINE__
|
35
34
|
def simple_#{helper}(record_or_name_or_array, *args, &block)
|
36
35
|
options = args.extract_options!
|
37
|
-
options[:builder]
|
36
|
+
options[:builder] ||= SimpleForm::FormBuilder
|
38
37
|
css_class = case record_or_name_or_array
|
39
38
|
when String, Symbol then record_or_name_or_array.to_s
|
40
39
|
when Array then dom_class(record_or_name_or_array.last)
|
@@ -37,7 +37,7 @@ module SimpleForm
|
|
37
37
|
|
38
38
|
def label_html_options
|
39
39
|
label_options = html_options_for(:label, [input_type, required_class])
|
40
|
-
label_options[:for] = options[:input_html][:id] if options.key?(:input_html)
|
40
|
+
label_options[:for] = options[:input_html][:id] if options.key?(:input_html) && options[:input_html].key?(:id)
|
41
41
|
label_options
|
42
42
|
end
|
43
43
|
|
@@ -175,7 +175,7 @@ module SimpleForm
|
|
175
175
|
# f.error :name, :id => "cool_error"
|
176
176
|
#
|
177
177
|
def error(attribute_name, options={})
|
178
|
-
options[:error_html] = options
|
178
|
+
options[:error_html] = options.dup
|
179
179
|
column = find_attribute_column(attribute_name)
|
180
180
|
input_type = default_input_type(attribute_name, column, options)
|
181
181
|
SimpleForm::Inputs::Base.new(self, attribute_name, column, input_type, options).error
|
@@ -192,7 +192,7 @@ module SimpleForm
|
|
192
192
|
# f.hint "Don't forget to accept this"
|
193
193
|
#
|
194
194
|
def hint(attribute_name, options={})
|
195
|
-
options[:hint_html] = options
|
195
|
+
options[:hint_html] = options.dup
|
196
196
|
if attribute_name.is_a?(String)
|
197
197
|
options[:hint] = attribute_name
|
198
198
|
attribute_name, column, input_type = nil, nil, nil
|
@@ -219,8 +219,8 @@ module SimpleForm
|
|
219
219
|
def label(attribute_name, *args)
|
220
220
|
return super if args.first.is_a?(String)
|
221
221
|
options = args.extract_options!
|
222
|
+
options[:label_html] = options.dup
|
222
223
|
options[:label] = options.delete(:label)
|
223
|
-
options[:label_html] = options
|
224
224
|
options[:required] = options.delete(:required)
|
225
225
|
column = find_attribute_column(attribute_name)
|
226
226
|
input_type = default_input_type(attribute_name, column, options)
|
@@ -250,9 +250,9 @@ module SimpleForm
|
|
250
250
|
def default_input_type(attribute_name, column, options) #:nodoc:
|
251
251
|
return options[:as].to_sym if options[:as]
|
252
252
|
return :select if options[:collection]
|
253
|
+
custom_type = find_custom_type(attribute_name.to_s) and return custom_type
|
253
254
|
|
254
255
|
input_type = column.try(:type)
|
255
|
-
|
256
256
|
case input_type
|
257
257
|
when :timestamp
|
258
258
|
:datetime
|
@@ -264,10 +264,6 @@ module SimpleForm
|
|
264
264
|
when /email/ then :email
|
265
265
|
when /phone/ then :tel
|
266
266
|
when /url/ then :url
|
267
|
-
else
|
268
|
-
SimpleForm.input_mappings.find { |match, type|
|
269
|
-
attribute_name.to_s =~ match
|
270
|
-
}.try(:last) if SimpleForm.input_mappings
|
271
267
|
end
|
272
268
|
|
273
269
|
match || input_type || file_method?(attribute_name) || :string
|
@@ -276,21 +272,30 @@ module SimpleForm
|
|
276
272
|
end
|
277
273
|
end
|
278
274
|
|
275
|
+
def find_custom_type(attribute_name)
|
276
|
+
SimpleForm.input_mappings.find { |match, type|
|
277
|
+
attribute_name =~ match
|
278
|
+
}.try(:last) if SimpleForm.input_mappings
|
279
|
+
end
|
280
|
+
|
279
281
|
# Checks if attribute is a file_method.
|
280
282
|
def file_method?(attribute_name) #:nodoc:
|
281
283
|
file = @object.send(attribute_name) if @object.respond_to?(attribute_name)
|
282
284
|
:file if file && SimpleForm.file_methods.any? { |m| file.respond_to?(m) }
|
283
285
|
end
|
284
286
|
|
285
|
-
# Finds the database column for the given attribute
|
287
|
+
# Finds the database column for the given attribute.
|
286
288
|
def find_attribute_column(attribute_name) #:nodoc:
|
287
|
-
|
289
|
+
if @object.respond_to?(:column_for_attribute)
|
290
|
+
@object.column_for_attribute(attribute_name)
|
291
|
+
end
|
288
292
|
end
|
289
293
|
|
290
|
-
# Find reflection related to association
|
294
|
+
# Find reflection related to association.
|
291
295
|
def find_association_reflection(association) #:nodoc:
|
292
|
-
|
296
|
+
if @object.class.respond_to?(:reflect_on_association)
|
297
|
+
@object.class.reflect_on_association(association)
|
298
|
+
end
|
293
299
|
end
|
294
|
-
|
295
300
|
end
|
296
301
|
end
|
@@ -28,8 +28,9 @@ module SimpleForm
|
|
28
28
|
@reflection = options.delete(:reflection)
|
29
29
|
@options = options
|
30
30
|
@input_html_options = html_options_for(:input, input_html_classes).tap do |o|
|
31
|
-
o[:required]
|
32
|
-
o[:disabled]
|
31
|
+
o[:required] = true if has_required?
|
32
|
+
o[:disabled] = true if disabled?
|
33
|
+
o[:autofocus] = true if has_autofocus?
|
33
34
|
end
|
34
35
|
end
|
35
36
|
|
@@ -71,8 +72,17 @@ module SimpleForm
|
|
71
72
|
end
|
72
73
|
end
|
73
74
|
|
75
|
+
# Whether this input is valid for HTML 5 required attribute.
|
76
|
+
def has_required?
|
77
|
+
attribute_required?
|
78
|
+
end
|
79
|
+
|
80
|
+
def has_autofocus?
|
81
|
+
options[:autofocus]
|
82
|
+
end
|
83
|
+
|
74
84
|
def has_validators?
|
75
|
-
object.class.respond_to?(:validators_on)
|
85
|
+
attribute_name && object.class.respond_to?(:validators_on)
|
76
86
|
end
|
77
87
|
|
78
88
|
def attribute_validators
|
@@ -31,6 +31,11 @@ module SimpleForm
|
|
31
31
|
@collection ||= (options.delete(:collection) || self.class.boolean_collection).to_a
|
32
32
|
end
|
33
33
|
|
34
|
+
# Select components does not allow the required html tag.
|
35
|
+
def has_required?
|
36
|
+
super && input_type != :select
|
37
|
+
end
|
38
|
+
|
34
39
|
# Check if :include_blank must be included by default.
|
35
40
|
def skip_include_blank?
|
36
41
|
(options.keys & [:prompt, :include_blank, :default, :selected]).any? ||
|
data/lib/simple_form/map_type.rb
CHANGED
data/lib/simple_form/version.rb
CHANGED
data/simple_form.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "simple_form/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "simple_form"
|
7
|
+
s.version = SimpleForm::VERSION.dup
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.summary = "Forms made easy!"
|
10
|
+
s.email = "contact@plataformatec.com.br"
|
11
|
+
s.homepage = "http://github.com/plataformatec/simple_form"
|
12
|
+
s.description = "Forms made easy!"
|
13
|
+
s.authors = ['José Valim', 'Carlos Antônio']
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.test_files -= Dir["test/support/country_select/**/*"]
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.rubyforge_project = "simple_form"
|
22
|
+
end
|
@@ -170,6 +170,16 @@ class LabelTest < ActionView::TestCase
|
|
170
170
|
assert_select 'label[for=my_new_id]'
|
171
171
|
end
|
172
172
|
|
173
|
+
test 'label should allow overwriting of for attribute' do
|
174
|
+
with_label_for @user, :name, :string, :label_html => { :for => 'my_new_id' }
|
175
|
+
assert_select 'label[for=my_new_id]'
|
176
|
+
end
|
177
|
+
|
178
|
+
test 'label should allow overwriting of for attribute with input_html not containing id' do
|
179
|
+
with_label_for @user, :name, :string, :label_html => { :for => 'my_new_id' }, :input_html => {:class => 'foo'}
|
180
|
+
assert_select 'label[for=my_new_id]'
|
181
|
+
end
|
182
|
+
|
173
183
|
test 'label should use default input id when it was not overridden' do
|
174
184
|
with_label_for @user, :name, :string, :input_html => { :class => 'my_new_id' }
|
175
185
|
assert_select 'label[for=user_name]'
|
data/test/form_builder_test.rb
CHANGED
@@ -9,6 +9,12 @@ class FormBuilderTest < ActionView::TestCase
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
+
def with_custom_form_for(object, *args, &block)
|
13
|
+
with_concat_custom_form_for(object) do |f|
|
14
|
+
f.input(*args, &block)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
12
18
|
def with_button_for(object, *args)
|
13
19
|
with_concat_form_for(object) do |f|
|
14
20
|
f.button(*args)
|
@@ -70,6 +76,14 @@ class FormBuilderTest < ActionView::TestCase
|
|
70
76
|
end
|
71
77
|
end
|
72
78
|
|
79
|
+
test 'builder should allow adding custom input mappings for integer input types' do
|
80
|
+
swap SimpleForm, :input_mappings => { /lock_version/ => :hidden } do
|
81
|
+
with_form_for @user, :lock_version
|
82
|
+
assert_no_select 'form input#user_lock_version.integer'
|
83
|
+
assert_select 'form input#user_lock_version.hidden'
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
73
87
|
test 'builder uses the first matching custom input map when more than one match' do
|
74
88
|
swap SimpleForm, :input_mappings => { /count$/ => :integer, /^post_/ => :password } do
|
75
89
|
with_form_for @user, :post_count
|
@@ -78,6 +92,14 @@ class FormBuilderTest < ActionView::TestCase
|
|
78
92
|
end
|
79
93
|
end
|
80
94
|
|
95
|
+
test 'builder uses the custom map only for matched attributes' do
|
96
|
+
swap SimpleForm, :input_mappings => { /lock_version/ => :hidden } do
|
97
|
+
with_form_for @user, :post_count
|
98
|
+
assert_no_select 'form input#user_post_count.hidden'
|
99
|
+
assert_select 'form input#user_post_count.string'
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
81
103
|
# INPUT TYPES
|
82
104
|
test 'builder should generate text fields for string columns' do
|
83
105
|
with_form_for @user, :name
|
@@ -371,6 +393,11 @@ class FormBuilderTest < ActionView::TestCase
|
|
371
393
|
assert_select 'span.error', "can't be blank"
|
372
394
|
end
|
373
395
|
|
396
|
+
test 'builder should generate an error tag with a clean HTML' do
|
397
|
+
with_error_for @user, :name
|
398
|
+
assert_no_select 'span.error[error_html]'
|
399
|
+
end
|
400
|
+
|
374
401
|
test 'builder should allow passing options to error tag' do
|
375
402
|
with_error_for @user, :name, :id => 'name_error'
|
376
403
|
assert_select 'span.error#name_error', "can't be blank"
|
@@ -384,11 +411,22 @@ class FormBuilderTest < ActionView::TestCase
|
|
384
411
|
end
|
385
412
|
end
|
386
413
|
|
414
|
+
test 'builder should generate a hint component tag for the given text for a model with ActiveModel::Validations' do
|
415
|
+
with_hint_for @validating_user, 'Hello World!'
|
416
|
+
assert_select 'span.hint', 'Hello World!'
|
417
|
+
end
|
418
|
+
|
387
419
|
test 'builder should generate a hint component tag for the given text' do
|
388
420
|
with_hint_for @user, 'Hello World!'
|
389
421
|
assert_select 'span.hint', 'Hello World!'
|
390
422
|
end
|
391
423
|
|
424
|
+
test 'builder should generate a hint componet tag with a clean HTML' do
|
425
|
+
with_hint_for @validating_user, 'Hello World!'
|
426
|
+
assert_no_select 'span.hint[hint]'
|
427
|
+
assert_no_select 'span.hint[hint_html]'
|
428
|
+
end
|
429
|
+
|
392
430
|
test 'builder should allow passing options to hint tag' do
|
393
431
|
with_hint_for @user, :name, :hint => 'Hello World!', :id => 'name_hint'
|
394
432
|
assert_select 'span.hint#name_hint', 'Hello World!'
|
@@ -400,6 +438,11 @@ class FormBuilderTest < ActionView::TestCase
|
|
400
438
|
assert_select 'label.string[for=user_name]', /Name/
|
401
439
|
end
|
402
440
|
|
441
|
+
test 'builder should generate a label componet tag with a clean HTML' do
|
442
|
+
with_label_for @user, :name
|
443
|
+
assert_no_select 'label.string[label_html]'
|
444
|
+
end
|
445
|
+
|
403
446
|
test 'builder should add a required class to label if the attribute is required' do
|
404
447
|
with_label_for @validating_user, :name
|
405
448
|
assert_select 'label.string.required[for=validating_user_name]', /Name/
|
@@ -562,4 +605,10 @@ class FormBuilderTest < ActionView::TestCase
|
|
562
605
|
assert_select 'form ul', :count => 1
|
563
606
|
assert_select 'form ul li', :count => 3
|
564
607
|
end
|
608
|
+
|
609
|
+
# CUSTOM FORM BUILDER
|
610
|
+
test 'custom builder should inherit mappings' do
|
611
|
+
with_custom_form_for @user, :email
|
612
|
+
assert_select 'form input[type=email]#user_email.custom'
|
613
|
+
end
|
565
614
|
end
|
data/test/inputs_test.rb
CHANGED
@@ -62,6 +62,41 @@ class InputTest < ActionView::TestCase
|
|
62
62
|
assert_select 'select.datetime:not([disabled])'
|
63
63
|
end
|
64
64
|
|
65
|
+
test 'input should generate autofocus attribute based on the autofocus option' do
|
66
|
+
with_input_for @user, :name, :string, :autofocus => true
|
67
|
+
assert_select 'input.string[autofocus]'
|
68
|
+
with_input_for @user, :description, :text, :autofocus => true
|
69
|
+
assert_select 'textarea.text[autofocus]'
|
70
|
+
with_input_for @user, :age, :integer, :autofocus => true
|
71
|
+
assert_select 'input.integer[autofocus]'
|
72
|
+
with_input_for @user, :born_at, :date, :autofocus => true
|
73
|
+
assert_select 'select.date[autofocus]'
|
74
|
+
with_input_for @user, :created_at, :datetime, :autofocus => true
|
75
|
+
assert_select 'select.datetime[autofocus]'
|
76
|
+
|
77
|
+
with_input_for @user, :name, :string, :autofocus => false
|
78
|
+
assert_select 'input.string:not([autofocus])'
|
79
|
+
with_input_for @user, :description, :text, :autofocus => false
|
80
|
+
assert_select 'textarea.text:not([autofocus])'
|
81
|
+
with_input_for @user, :age, :integer, :autofocus => false
|
82
|
+
assert_select 'input.integer:not([autofocus])'
|
83
|
+
with_input_for @user, :born_at, :date, :autofocus => false
|
84
|
+
assert_select 'select.date:not([autofocus])'
|
85
|
+
with_input_for @user, :created_at, :datetime, :autofocus => false
|
86
|
+
assert_select 'select.datetime:not([autofocus])'
|
87
|
+
|
88
|
+
with_input_for @user, :name, :string
|
89
|
+
assert_select 'input.string:not([autofocus])'
|
90
|
+
with_input_for @user, :description, :text
|
91
|
+
assert_select 'textarea.text:not([autofocus])'
|
92
|
+
with_input_for @user, :age, :integer
|
93
|
+
assert_select 'input.integer:not([autofocus])'
|
94
|
+
with_input_for @user, :born_at, :date
|
95
|
+
assert_select 'select.date:not([autofocus])'
|
96
|
+
with_input_for @user, :created_at, :datetime
|
97
|
+
assert_select 'select.datetime:not([autofocus])'
|
98
|
+
end
|
99
|
+
|
65
100
|
test 'input should render components according to an optional :components option' do
|
66
101
|
with_input_for @user, :name, :string, :components => [:input, :label]
|
67
102
|
assert_select 'input + label'
|
@@ -321,6 +356,12 @@ class InputTest < ActionView::TestCase
|
|
321
356
|
assert_no_select 'select option[value=]', /^$/
|
322
357
|
end
|
323
358
|
|
359
|
+
test 'priority input should not generate invalid required html attribute' do
|
360
|
+
with_input_for @user, :country, :country
|
361
|
+
assert_select 'select.required'
|
362
|
+
assert_no_select 'select[required]'
|
363
|
+
end
|
364
|
+
|
324
365
|
# DateTime input
|
325
366
|
test 'input should generate a datetime select by default for datetime attributes' do
|
326
367
|
with_input_for @user, :created_at, :datetime
|
@@ -395,6 +436,12 @@ class InputTest < ActionView::TestCase
|
|
395
436
|
assert_select 'label[for=project_created_at_4i]'
|
396
437
|
end
|
397
438
|
|
439
|
+
test 'date time input should not generate invalid required html attribute' do
|
440
|
+
with_input_for @user, :delivery_time, :time, :required => true
|
441
|
+
assert_select 'select.required'
|
442
|
+
assert_no_select 'select[required]'
|
443
|
+
end
|
444
|
+
|
398
445
|
# CollectionInput
|
399
446
|
test 'input should generate boolean radio buttons by default for radio types' do
|
400
447
|
with_input_for @user, :active, :radio
|
@@ -559,6 +606,31 @@ class InputTest < ActionView::TestCase
|
|
559
606
|
assert_select 'label.collection_radio', 'CARLOS'
|
560
607
|
end
|
561
608
|
|
609
|
+
test 'input should allow overriding label and value method using a lambda for collection selects' do
|
610
|
+
with_input_for @user, :name, :select,
|
611
|
+
:collection => ['Jose' , 'Carlos'],
|
612
|
+
:label_method => lambda { |i| i.upcase },
|
613
|
+
:value_method => lambda { |i| i.downcase }
|
614
|
+
assert_select 'select option[value=jose]', "JOSE"
|
615
|
+
assert_select 'select option[value=carlos]', "CARLOS"
|
616
|
+
end
|
617
|
+
|
618
|
+
test 'input should allow overriding only label but not value method using a lambda for collection select' do
|
619
|
+
with_input_for @user, :name, :select,
|
620
|
+
:collection => ['Jose' , 'Carlos'],
|
621
|
+
:label_method => lambda { |i| i.upcase }
|
622
|
+
assert_select 'select option[value=Jose]', "JOSE"
|
623
|
+
assert_select 'select option[value=Carlos]', "CARLOS"
|
624
|
+
end
|
625
|
+
|
626
|
+
test 'input should allow overriding only value but not label method using a lambda for collection select' do
|
627
|
+
with_input_for @user, :name, :select,
|
628
|
+
:collection => ['Jose' , 'Carlos'],
|
629
|
+
:value_method => lambda { |i| i.downcase }
|
630
|
+
assert_select 'select option[value=jose]', "Jose"
|
631
|
+
assert_select 'select option[value=carlos]', "Carlos"
|
632
|
+
end
|
633
|
+
|
562
634
|
test 'input should allow symbols for collections' do
|
563
635
|
with_input_for @user, :name, :select, :collection => [:jose, :carlos]
|
564
636
|
assert_select 'select.select#user_name'
|
@@ -566,6 +638,18 @@ class InputTest < ActionView::TestCase
|
|
566
638
|
assert_select 'select option[value=carlos]', 'carlos'
|
567
639
|
end
|
568
640
|
|
641
|
+
test 'collection input with radio type should generate required html attribute' do
|
642
|
+
with_input_for @user, :name, :radio, :collection => ['Jose' , 'Carlos']
|
643
|
+
assert_select 'input[type=radio].required'
|
644
|
+
assert_select 'input[type=radio][required]'
|
645
|
+
end
|
646
|
+
|
647
|
+
test 'collection input with select type should not generate invalid required html attribute' do
|
648
|
+
with_input_for @user, :name, :select, :collection => ['Jose' , 'Carlos']
|
649
|
+
assert_select 'select.required'
|
650
|
+
assert_no_select 'select[required]'
|
651
|
+
end
|
652
|
+
|
569
653
|
# With no object
|
570
654
|
test 'input should be generated properly when object is not present' do
|
571
655
|
with_input_for :project, :name, :string
|
@@ -28,4 +28,18 @@ module MiscHelpers
|
|
28
28
|
def with_concat_form_for(object, &block)
|
29
29
|
concat simple_form_for(object, &block)
|
30
30
|
end
|
31
|
+
|
32
|
+
def with_concat_custom_form_for(object, &block)
|
33
|
+
concat custom_form_for(object, &block)
|
34
|
+
end
|
35
|
+
|
36
|
+
def custom_form_for(object, *args, &block)
|
37
|
+
simple_form_for(object, *(args << { :builder => CustomFormBuilder }), &block)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class CustomFormBuilder < SimpleForm::FormBuilder
|
42
|
+
def input(attribute_name, *args, &block)
|
43
|
+
super(attribute_name, *(args << { :input_html => { :class => 'custom' } }), &block)
|
44
|
+
end
|
31
45
|
end
|
data/test/support/models.rb
CHANGED
@@ -40,7 +40,7 @@ class User
|
|
40
40
|
|
41
41
|
attr_accessor :id, :name, :company, :company_id, :time_zone, :active, :description, :created_at, :updated_at,
|
42
42
|
:credit_limit, :age, :password, :delivery_time, :born_at, :special_company_id, :country, :url, :tag_ids,
|
43
|
-
:avatar, :email, :status, :residence_country, :phone_number, :post_count
|
43
|
+
:avatar, :email, :status, :residence_country, :phone_number, :post_count, :lock_version
|
44
44
|
|
45
45
|
def initialize(options={})
|
46
46
|
options.each do |key, value|
|
@@ -70,6 +70,7 @@ class User
|
|
70
70
|
when :delivery_time then :time
|
71
71
|
when :created_at then :datetime
|
72
72
|
when :updated_at then :timestamp
|
73
|
+
when :lock_version then :integer
|
73
74
|
end
|
74
75
|
Column.new(attribute, column_type, limit)
|
75
76
|
end
|
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:
|
5
|
-
prerelease:
|
4
|
+
hash: 25
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 1.3.
|
9
|
+
- 1
|
10
|
+
version: 1.3.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- "Jos\xC3\xA9 Valim"
|
@@ -16,34 +16,27 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date:
|
19
|
+
date: 2011-02-06 00:00:00 -02:00
|
20
20
|
default_executable:
|
21
|
-
dependencies:
|
22
|
-
|
23
|
-
prerelease: false
|
24
|
-
type: :runtime
|
25
|
-
name: rails
|
26
|
-
version_requirements: &id001 !ruby/object:Gem::Requirement
|
27
|
-
none: false
|
28
|
-
requirements:
|
29
|
-
- - ~>
|
30
|
-
- !ruby/object:Gem::Version
|
31
|
-
hash: 7
|
32
|
-
segments:
|
33
|
-
- 3
|
34
|
-
- 0
|
35
|
-
- 0
|
36
|
-
version: 3.0.0
|
37
|
-
requirement: *id001
|
21
|
+
dependencies: []
|
22
|
+
|
38
23
|
description: Forms made easy!
|
39
24
|
email: contact@plataformatec.com.br
|
40
25
|
executables: []
|
41
26
|
|
42
27
|
extensions: []
|
43
28
|
|
44
|
-
extra_rdoc_files:
|
45
|
-
|
29
|
+
extra_rdoc_files: []
|
30
|
+
|
46
31
|
files:
|
32
|
+
- .gitignore
|
33
|
+
- .gitmodules
|
34
|
+
- CHANGELOG.rdoc
|
35
|
+
- Gemfile
|
36
|
+
- Gemfile.lock
|
37
|
+
- MIT-LICENSE
|
38
|
+
- README.rdoc
|
39
|
+
- Rakefile
|
47
40
|
- init.rb
|
48
41
|
- lib/generators/simple_form/USAGE
|
49
42
|
- lib/generators/simple_form/install_generator.rb
|
@@ -78,7 +71,7 @@ files:
|
|
78
71
|
- lib/simple_form/inputs/string_input.rb
|
79
72
|
- lib/simple_form/map_type.rb
|
80
73
|
- lib/simple_form/version.rb
|
81
|
-
-
|
74
|
+
- simple_form.gemspec
|
82
75
|
- test/action_view_extensions/builder_test.rb
|
83
76
|
- test/action_view_extensions/form_helper_test.rb
|
84
77
|
- test/components/error_test.rb
|
@@ -123,8 +116,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
116
|
version: "0"
|
124
117
|
requirements: []
|
125
118
|
|
126
|
-
rubyforge_project:
|
127
|
-
rubygems_version: 1.
|
119
|
+
rubyforge_project: simple_form
|
120
|
+
rubygems_version: 1.5.0
|
128
121
|
signing_key:
|
129
122
|
specification_version: 3
|
130
123
|
summary: Forms made easy!
|