simple_form_awesome 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. data/CHANGELOG.md +327 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +25 -0
  4. data/lib/generators/simple_form/USAGE +3 -0
  5. data/lib/generators/simple_form/install_generator.rb +48 -0
  6. data/lib/generators/simple_form/templates/AUI_README +19 -0
  7. data/lib/generators/simple_form/templates/README +12 -0
  8. data/lib/generators/simple_form/templates/_form.html.erb +13 -0
  9. data/lib/generators/simple_form/templates/_form.html.haml +10 -0
  10. data/lib/generators/simple_form/templates/_form.html.slim +10 -0
  11. data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +142 -0
  12. data/lib/generators/simple_form/templates/config/initializers/simple_form_aui.rb +21 -0
  13. data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +45 -0
  14. data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +26 -0
  15. data/lib/generators/simple_form/templates/config/locales/simple_form.en.yml +26 -0
  16. data/lib/simple_form/action_view_extensions/builder.rb +340 -0
  17. data/lib/simple_form/action_view_extensions/form_helper.rb +72 -0
  18. data/lib/simple_form/components/errors.rb +35 -0
  19. data/lib/simple_form/components/hints.rb +18 -0
  20. data/lib/simple_form/components/html5.rb +26 -0
  21. data/lib/simple_form/components/label_input.rb +15 -0
  22. data/lib/simple_form/components/labels.rb +79 -0
  23. data/lib/simple_form/components/maxlength.rb +41 -0
  24. data/lib/simple_form/components/min_max.rb +50 -0
  25. data/lib/simple_form/components/pattern.rb +34 -0
  26. data/lib/simple_form/components/placeholders.rb +16 -0
  27. data/lib/simple_form/components/readonly.rb +22 -0
  28. data/lib/simple_form/components.rb +20 -0
  29. data/lib/simple_form/core_ext/hash.rb +16 -0
  30. data/lib/simple_form/error_notification.rb +48 -0
  31. data/lib/simple_form/form_builder.rb +482 -0
  32. data/lib/simple_form/helpers/autofocus.rb +11 -0
  33. data/lib/simple_form/helpers/disabled.rb +15 -0
  34. data/lib/simple_form/helpers/readonly.rb +15 -0
  35. data/lib/simple_form/helpers/required.rb +35 -0
  36. data/lib/simple_form/helpers/validators.rb +44 -0
  37. data/lib/simple_form/helpers.rb +12 -0
  38. data/lib/simple_form/i18n_cache.rb +22 -0
  39. data/lib/simple_form/inputs/aui_string_input.rb +10 -0
  40. data/lib/simple_form/inputs/base.rb +184 -0
  41. data/lib/simple_form/inputs/block_input.rb +14 -0
  42. data/lib/simple_form/inputs/boolean_input.rb +78 -0
  43. data/lib/simple_form/inputs/collection_check_boxes_input.rb +21 -0
  44. data/lib/simple_form/inputs/collection_input.rb +101 -0
  45. data/lib/simple_form/inputs/collection_radio_buttons_input.rb +63 -0
  46. data/lib/simple_form/inputs/collection_select_input.rb +14 -0
  47. data/lib/simple_form/inputs/date_time_input.rb +28 -0
  48. data/lib/simple_form/inputs/file_input.rb +9 -0
  49. data/lib/simple_form/inputs/grouped_collection_select_input.rb +41 -0
  50. data/lib/simple_form/inputs/hidden_input.rb +17 -0
  51. data/lib/simple_form/inputs/numeric_input.rb +24 -0
  52. data/lib/simple_form/inputs/password_input.rb +12 -0
  53. data/lib/simple_form/inputs/priority_input.rb +24 -0
  54. data/lib/simple_form/inputs/range_input.rb +14 -0
  55. data/lib/simple_form/inputs/string_input.rb +23 -0
  56. data/lib/simple_form/inputs/text_area_input.rb +12 -0
  57. data/lib/simple_form/inputs/text_input.rb +11 -0
  58. data/lib/simple_form/inputs.rb +23 -0
  59. data/lib/simple_form/map_type.rb +16 -0
  60. data/lib/simple_form/version.rb +3 -0
  61. data/lib/simple_form/wrappers/builder.rb +103 -0
  62. data/lib/simple_form/wrappers/many.rb +73 -0
  63. data/lib/simple_form/wrappers/root.rb +36 -0
  64. data/lib/simple_form/wrappers/single.rb +24 -0
  65. data/lib/simple_form/wrappers.rb +8 -0
  66. data/lib/simple_form.rb +221 -0
  67. data/test/action_view_extensions/builder_test.rb +583 -0
  68. data/test/action_view_extensions/form_helper_test.rb +143 -0
  69. data/test/components/label_test.rb +327 -0
  70. data/test/form_builder/association_test.rb +186 -0
  71. data/test/form_builder/button_test.rb +47 -0
  72. data/test/form_builder/error_notification_test.rb +79 -0
  73. data/test/form_builder/error_test.rb +121 -0
  74. data/test/form_builder/general_test.rb +402 -0
  75. data/test/form_builder/hint_test.rb +138 -0
  76. data/test/form_builder/input_field_test.rb +63 -0
  77. data/test/form_builder/label_test.rb +71 -0
  78. data/test/form_builder/wrapper_test.rb +203 -0
  79. data/test/generators/simple_form_generator_test.rb +42 -0
  80. data/test/inputs/boolean_input_test.rb +140 -0
  81. data/test/inputs/collection_check_boxes_input_test.rb +224 -0
  82. data/test/inputs/collection_radio_buttons_input_test.rb +326 -0
  83. data/test/inputs/collection_select_input_test.rb +241 -0
  84. data/test/inputs/datetime_input_test.rb +99 -0
  85. data/test/inputs/disabled_test.rb +78 -0
  86. data/test/inputs/discovery_test.rb +69 -0
  87. data/test/inputs/file_input_test.rb +16 -0
  88. data/test/inputs/general_test.rb +116 -0
  89. data/test/inputs/grouped_collection_select_input_test.rb +118 -0
  90. data/test/inputs/hidden_input_test.rb +30 -0
  91. data/test/inputs/numeric_input_test.rb +173 -0
  92. data/test/inputs/priority_input_test.rb +43 -0
  93. data/test/inputs/readonly_test.rb +101 -0
  94. data/test/inputs/required_test.rb +113 -0
  95. data/test/inputs/string_input_test.rb +146 -0
  96. data/test/inputs/text_input_test.rb +24 -0
  97. data/test/simple_form_test.rb +9 -0
  98. data/test/support/discovery_inputs.rb +27 -0
  99. data/test/support/misc_helpers.rb +138 -0
  100. data/test/support/mock_controller.rb +24 -0
  101. data/test/support/models.rb +216 -0
  102. data/test/test_helper.rb +95 -0
  103. metadata +217 -0
@@ -0,0 +1,12 @@
1
+ module SimpleForm
2
+ module Inputs
3
+ class TextAreaInput < TextInput
4
+ def input
5
+ input_html_classes.unshift(:textarea).delete(:text_area)
6
+ input_html_options[:style] ||= ""
7
+ input_html_options[:style] += ";height: 61px; width: 251px;"
8
+ super
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ module SimpleForm
2
+ module Inputs
3
+ class TextInput < Base
4
+ enable :placeholder, :maxlength
5
+
6
+ def input
7
+ @builder.text_area(attribute_name, input_html_options)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,23 @@
1
+ module SimpleForm
2
+ module Inputs
3
+ autoload :Base, 'simple_form/inputs/base'
4
+ autoload :BlockInput, 'simple_form/inputs/block_input'
5
+ autoload :BooleanInput, 'simple_form/inputs/boolean_input'
6
+ autoload :CollectionCheckBoxesInput, 'simple_form/inputs/collection_check_boxes_input'
7
+ autoload :CollectionInput, 'simple_form/inputs/collection_input'
8
+ autoload :CollectionRadioButtonsInput, 'simple_form/inputs/collection_radio_buttons_input'
9
+ autoload :CollectionSelectInput, 'simple_form/inputs/collection_select_input'
10
+ autoload :DateTimeInput, 'simple_form/inputs/date_time_input'
11
+ autoload :FileInput, 'simple_form/inputs/file_input'
12
+ autoload :GroupedCollectionSelectInput, 'simple_form/inputs/grouped_collection_select_input'
13
+ autoload :HiddenInput, 'simple_form/inputs/hidden_input'
14
+ autoload :NumericInput, 'simple_form/inputs/numeric_input'
15
+ autoload :PasswordInput, 'simple_form/inputs/password_input'
16
+ autoload :PriorityInput, 'simple_form/inputs/priority_input'
17
+ autoload :RangeInput, 'simple_form/inputs/range_input'
18
+ autoload :StringInput, 'simple_form/inputs/string_input'
19
+ autoload :TextInput, 'simple_form/inputs/text_input'
20
+ autoload :TextAreaInput, 'simple_form/inputs/text_area_input'
21
+ autoload :AuiStringInput, 'simple_form/inputs/aui_string_input'
22
+ end
23
+ end
@@ -0,0 +1,16 @@
1
+ require 'active_support/core_ext/class/attribute'
2
+
3
+ module SimpleForm
4
+ module MapType
5
+ def self.extended(base)
6
+ base.class_attribute :mappings
7
+ base.mappings = {}
8
+ end
9
+
10
+ def map_type(*types)
11
+ map_to = types.extract_options![:to]
12
+ raise ArgumentError, "You need to give :to as option to map_type" unless map_to
13
+ self.mappings = mappings.merge types.each_with_object({}) { |t, m| m[t] = map_to }
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,3 @@
1
+ module SimpleForm
2
+ VERSION = "2.2.0".freeze
3
+ end
@@ -0,0 +1,103 @@
1
+ module SimpleForm
2
+ module Wrappers
3
+ # Provides the builder syntax for components. The builder provides
4
+ # three methods `use`, `optional` and `wrapper` and they allow the following invocations:
5
+ #
6
+ # config.wrappers do |b|
7
+ # # Use a single component
8
+ # b.use :html5
9
+ #
10
+ # # Use the component, but do not automatically lookup. It will only be triggered when
11
+ # # :placeholder is explicitly set.
12
+ # b.optional :placeholder
13
+ #
14
+ # # Use a component with specific wrapper options
15
+ # b.use :error, :wrap_with => { :tag => "span", :class => "error" }
16
+ #
17
+ # # Use a set of components by wrapping them in a tag+class.
18
+ # b.wrapper :tag => "div", :class => "another" do |ba|
19
+ # ba.use :label
20
+ # ba.use :input
21
+ # end
22
+ #
23
+ # # Use a set of components by wrapping them in a tag+class.
24
+ # # This wrapper is identified by :label_input, which means it can
25
+ # # be turned off on demand with `f.input :name, :label_input => false`
26
+ # b.wrapper :label_input, :tag => "div", :class => "another" do |ba|
27
+ # ba.use :label
28
+ # ba.use :input
29
+ # end
30
+ # end
31
+ #
32
+ # The builder also accepts default options at the root level. This is usually
33
+ # used if you want a component to be disabled by default:
34
+ #
35
+ # config.wrappers :hint => false do |b|
36
+ # b.use :hint
37
+ # b.use :label_input
38
+ # end
39
+ #
40
+ # In the example above, hint defaults to false, which means it won't automatically
41
+ # do the lookup anymore. It will only be triggered when :hint is explicitly set.
42
+ class Builder
43
+ def initialize(options)
44
+ @options = options
45
+ @components = []
46
+ end
47
+
48
+ def use(name, options=nil, &block)
49
+ if block_given?
50
+ ActiveSupport::Deprecation.warn "Passing a block to use is deprecated. " \
51
+ "Please use wrapper instead of use."
52
+ return wrapper(name, options, &block)
53
+ end
54
+
55
+ if options && options.keys != [:wrap_with]
56
+ ActiveSupport::Deprecation.warn "Passing :tag, :class and others to use is deprecated. " \
57
+ "Please invoke b.use #{name.inspect}, :wrap_with => #{options.inspect} instead."
58
+ options = { :wrap_with => options }
59
+ end
60
+
61
+ if options && wrapper = options[:wrap_with]
62
+ @components << Single.new(name, wrapper)
63
+ else
64
+ @components << name
65
+ end
66
+ end
67
+
68
+ def optional(name, options=nil, &block)
69
+ if block_given?
70
+ ActiveSupport::Deprecation.warn "Passing a block to optional is deprecated. " \
71
+ "Please use wrapper instead of optional."
72
+ return wrapper(name, options, &block)
73
+ end
74
+
75
+ if options && options.keys != [:wrap_with]
76
+ ActiveSupport::Deprecation.warn "Passing :tag, :class and others to optional is deprecated. " \
77
+ "Please invoke b.optional #{name.inspect}, :wrap_with => #{options.inspect} instead."
78
+ options = { :wrap_with => options }
79
+ end
80
+
81
+ @options[name] = false
82
+ use(name, options, &block)
83
+ end
84
+
85
+ def wrapper(name, options=nil)
86
+ if block_given?
87
+ name, options = nil, name if name.is_a?(Hash)
88
+ builder = self.class.new(@options)
89
+ options ||= {}
90
+ options[:tag] = :div if options[:tag].nil?
91
+ yield builder
92
+ @components << Many.new(name, builder.to_a, options)
93
+ else
94
+ raise ArgumentError, "A block is required as argument to wrapper"
95
+ end
96
+ end
97
+
98
+ def to_a
99
+ @components
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,73 @@
1
+ module SimpleForm
2
+ module Wrappers
3
+ # A wrapper is an object that holds several components and render them.
4
+ # A component may either be a symbol or any object that responds to `render`.
5
+ # This API allows inputs/components to be easily wrapped, removing the
6
+ # need to modify the code only to wrap input in an extra tag.
7
+ #
8
+ # `Many` represents a wrapper around several components at the same time.
9
+ # It may optionally receive a namespace, allowing it to be configured
10
+ # on demand on input generation.
11
+ class Many
12
+ attr_reader :namespace, :defaults, :components
13
+ alias :to_sym :namespace
14
+
15
+ def initialize(namespace, components, defaults={})
16
+ @namespace = namespace
17
+ @components = components
18
+ @defaults = defaults
19
+ @defaults[:tag] = :div unless @defaults.key?(:tag)
20
+ @defaults[:class] = Array.wrap(@defaults[:class])
21
+ end
22
+
23
+ def render(input)
24
+ content = "".html_safe
25
+ options = input.options
26
+
27
+ components.each do |component|
28
+ next if options[component] == false
29
+ rendered = component.respond_to?(:render) ? component.render(input) : input.send(component)
30
+ content.safe_concat rendered.to_s if rendered
31
+ end
32
+
33
+ wrap(input, options, content)
34
+ end
35
+
36
+ def find(name)
37
+ return self if namespace == name
38
+
39
+ @components.each do |c|
40
+ if c.is_a?(Symbol)
41
+ return nil if c == namespace
42
+ elsif value = c.find(name)
43
+ return value
44
+ end
45
+ end
46
+
47
+ nil
48
+ end
49
+
50
+ private
51
+
52
+ def wrap(input, options, content)
53
+ return content if options[namespace] == false
54
+
55
+ tag = (namespace && options[:"#{namespace}_tag"]) || @defaults[:tag]
56
+ return content unless tag
57
+
58
+ klass = html_classes(input, options)
59
+ opts = html_options(options)
60
+ opts[:class] = (klass << opts[:class]).join(' ').strip unless klass.empty?
61
+ input.template.content_tag(tag, content, opts)
62
+ end
63
+
64
+ def html_options(options)
65
+ options[:"#{namespace}_html"] || {}
66
+ end
67
+
68
+ def html_classes(input, options)
69
+ @defaults[:class].dup
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,36 @@
1
+ module SimpleForm
2
+ module Wrappers
3
+ # `Root` is the root wrapper for all components. It is special cased to
4
+ # always have a namespace and to add special html classes.
5
+ class Root < Many
6
+ attr_reader :options
7
+
8
+ def initialize(*args)
9
+ super(:wrapper, *args)
10
+ @options = @defaults.except(:tag, :class, :error_class, :hint_class)
11
+ end
12
+
13
+ def render(input)
14
+ input.options.reverse_merge!(@options)
15
+ super
16
+ end
17
+
18
+ # Provide a fallback if name cannot be found.
19
+ def find(name)
20
+ super || SimpleForm::Wrappers::Many.new(name, [name])
21
+ end
22
+
23
+ private
24
+
25
+ def html_classes(input, options)
26
+ css = options[:wrapper_class] ? Array.wrap(options[:wrapper_class]) : @defaults[:class]
27
+ css += SimpleForm.additional_classes_for(:wrapper) do
28
+ input.additional_classes + [input.input_class]
29
+ end
30
+ css << (options[:wrapper_error_class] || @defaults[:error_class]) if input.has_errors?
31
+ css << (options[:wrapper_hint_class] || @defaults[:hint_class]) if input.has_hint?
32
+ css.compact
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,24 @@
1
+ module SimpleForm
2
+ module Wrappers
3
+ # `Single` is an optimization for a wrapper that has only one component.
4
+ class Single < Many
5
+ def initialize(name, options={})
6
+ super(name, [name], options)
7
+ end
8
+
9
+ def render(input)
10
+ options = input.options
11
+ if options[namespace] != false
12
+ content = input.send(namespace)
13
+ wrap(input, options, content) if content
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def html_options(options)
20
+ [:label, :input].include?(namespace) ? {} : super
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,8 @@
1
+ module SimpleForm
2
+ module Wrappers
3
+ autoload :Builder, 'simple_form/wrappers/builder'
4
+ autoload :Many, 'simple_form/wrappers/many'
5
+ autoload :Root, 'simple_form/wrappers/root'
6
+ autoload :Single, 'simple_form/wrappers/single'
7
+ end
8
+ end
@@ -0,0 +1,221 @@
1
+ require 'action_view'
2
+ require 'simple_form/action_view_extensions/form_helper'
3
+ require 'simple_form/action_view_extensions/builder'
4
+ require 'active_support/core_ext/hash/slice'
5
+ require 'active_support/core_ext/hash/except'
6
+ require 'active_support/core_ext/hash/reverse_merge'
7
+
8
+ module SimpleForm
9
+ autoload :Components, 'simple_form/components'
10
+ autoload :ErrorNotification, 'simple_form/error_notification'
11
+ autoload :FormBuilder, 'simple_form/form_builder'
12
+ autoload :Helpers, 'simple_form/helpers'
13
+ autoload :I18nCache, 'simple_form/i18n_cache'
14
+ autoload :Inputs, 'simple_form/inputs'
15
+ autoload :MapType, 'simple_form/map_type'
16
+ autoload :Wrappers, 'simple_form/wrappers'
17
+
18
+ ## CONFIGURATION OPTIONS
19
+
20
+ # Method used to tidy up errors.
21
+ mattr_accessor :error_method
22
+ @@error_method = :first
23
+
24
+ # Default tag used for error notification helper.
25
+ mattr_accessor :error_notification_tag
26
+ @@error_notification_tag = :p
27
+
28
+ # CSS class to add for error notification helper.
29
+ mattr_accessor :error_notification_class
30
+ @@error_notification_class = :error_notification
31
+
32
+ # Series of attemps to detect a default label method for collection.
33
+ mattr_accessor :collection_label_methods
34
+ @@collection_label_methods = [ :to_label, :name, :title, :to_s ]
35
+
36
+ # Series of attemps to detect a default value method for collection.
37
+ mattr_accessor :collection_value_methods
38
+ @@collection_value_methods = [ :id, :to_s ]
39
+
40
+ # You can wrap a collection of radio/check boxes in a pre-defined tag, defaulting to none.
41
+ mattr_accessor :collection_wrapper_tag
42
+ @@collection_wrapper_tag = nil
43
+
44
+ # You can define the class to use on all collection wrappers, defaulting to none.
45
+ mattr_accessor :collection_wrapper_class
46
+ @@collection_wrapper_class = nil
47
+
48
+ # You can wrap each item in a collection of radio/check boxes with a tag,
49
+ # defaulting to none. Please note that when using :boolean_style = :nested,
50
+ # SimpleForm will force this option to be a :label.
51
+ mattr_accessor :item_wrapper_tag
52
+ @@item_wrapper_tag = :span
53
+
54
+ # You can define the class to use on all item wrappers, defaulting to none.
55
+ mattr_accessor :item_wrapper_class
56
+ @@item_wrapper_class = nil
57
+
58
+ # How the label text should be generated altogether with the required text.
59
+ mattr_accessor :label_text
60
+ @@label_text = lambda { |label, required| "#{required} #{label}" }
61
+
62
+ # You can define the class to use on all labels. Default is nil.
63
+ mattr_accessor :label_class
64
+ @@label_class = nil
65
+
66
+ # Define the way to render check boxes / radio buttons with labels.
67
+ # :inline => input + label (default)
68
+ # :nested => label > input
69
+ mattr_accessor :boolean_style
70
+ @@boolean_style = :inline
71
+
72
+ # You can define the class to use on all forms. Default is simple_form.
73
+ mattr_accessor :form_class
74
+ @@form_class = :simple_form
75
+
76
+ # You can define which elements should obtain additional classes
77
+ mattr_accessor :generate_additional_classes_for
78
+ @@generate_additional_classes_for = [:wrapper, :label, :input]
79
+
80
+ # Whether attributes are required by default (or not).
81
+ mattr_accessor :required_by_default
82
+ @@required_by_default = true
83
+
84
+ # Tell browsers whether to use default HTML5 validations (novalidate option).
85
+ mattr_accessor :browser_validations
86
+ @@browser_validations = true
87
+
88
+ # Collection of methods to detect if a file type was given.
89
+ mattr_accessor :file_methods
90
+ @@file_methods = [ :mounted_as, :file?, :public_filename ]
91
+
92
+ # Custom mappings for input types. This should be a hash containing a regexp
93
+ # to match as key, and the input type that will be used when the field name
94
+ # matches the regexp as value, such as { /count/ => :integer }.
95
+ mattr_accessor :input_mappings
96
+ @@input_mappings = nil
97
+
98
+ # Custom wrappers for input types. This should be a hash containing an input
99
+ # type as key and the wrapper that will be used for all inputs with specified type.
100
+ # e.g { :string => :string_wrapper, :boolean => :boolean_wrapper }
101
+ mattr_accessor :wrapper_mappings
102
+ @@wrapper_mappings = nil
103
+
104
+ # Default priority for time_zone inputs.
105
+ mattr_accessor :time_zone_priority
106
+ @@time_zone_priority = nil
107
+
108
+ # Default priority for country inputs.
109
+ mattr_accessor :country_priority
110
+ @@country_priority = nil
111
+
112
+ # Maximum size allowed for inputs.
113
+ mattr_accessor :default_input_size
114
+ @@default_input_size = 50
115
+
116
+ # When off, do not use translations in labels. Disabling translation in
117
+ # hints and placeholders can be done manually in the wrapper API.
118
+ mattr_accessor :translate_labels
119
+ @@translate_labels = true
120
+
121
+ # Automatically discover new inputs in Rails' autoload path.
122
+ mattr_accessor :inputs_discovery
123
+ @@inputs_discovery = true
124
+
125
+ # Cache SimpleForm inputs discovery
126
+ mattr_accessor :cache_discovery
127
+ @@cache_discovery = defined?(Rails) && !Rails.env.development?
128
+
129
+ # Adds a class to each generated button, mostly for compatiblity
130
+ mattr_accessor :button_class
131
+ @@button_class = 'button'
132
+
133
+ ## WRAPPER CONFIGURATION
134
+ # The default wrapper to be used by the FormBuilder.
135
+ mattr_accessor :default_wrapper
136
+ @@default_wrapper = :default
137
+ @@wrappers = {}
138
+
139
+ # Retrieves a given wrapper
140
+ def self.wrapper(name)
141
+ @@wrappers[name.to_sym] or raise WrapperNotFound, "Couldn't find wrapper with name #{name}"
142
+ end
143
+
144
+ # Raised when fails to find a given wrapper name
145
+ class WrapperNotFound < StandardError
146
+ end
147
+
148
+ # Define a new wrapper using SimpleForm::Wrappers::Builder
149
+ # and store it in the given name.
150
+ def self.wrappers(*args, &block)
151
+ if block_given?
152
+ options = args.extract_options!
153
+ name = args.first || :default
154
+ @@wrappers[name.to_sym] = build(options, &block)
155
+ else
156
+ @@wrappers
157
+ end
158
+ end
159
+
160
+ # Builds a new wrapper using SimpleForm::Wrappers::Builder.
161
+ def self.build(options={})
162
+ options[:tag] = :div if options[:tag].nil?
163
+ builder = SimpleForm::Wrappers::Builder.new(options)
164
+ yield builder
165
+ SimpleForm::Wrappers::Root.new(builder.to_a, options)
166
+ end
167
+
168
+ wrappers :class => :input, :hint_class => :field_with_hint, :error_class => :field_with_errors do |b|
169
+ b.use :html5
170
+
171
+ b.use :min_max
172
+ b.use :maxlength
173
+ b.use :placeholder
174
+ b.optional :pattern
175
+ b.optional :readonly
176
+
177
+ b.use :label_input
178
+ b.use :hint, :wrap_with => { :tag => :span, :class => :hint }
179
+ b.use :error, :wrap_with => { :tag => :span, :class => :error }
180
+ end
181
+
182
+ ## SETUP
183
+
184
+ DEPRECATED = %w(hint_tag hint_class error_tag error_class error_notification_id wrapper_tag wrapper_class wrapper_error_class components html5)
185
+ @@deprecated = []
186
+
187
+ DEPRECATED.each do |method|
188
+ class_eval "def self.#{method}=(*); @@deprecated << :#{method}=; end"
189
+ class_eval "def self.#{method}; deprecation_warn 'SimpleForm.#{method} is deprecated and has no effect'; end"
190
+ end
191
+
192
+ def self.translate=(value)
193
+ deprecation_warn "SimpleForm.translate= is disabled in favor of translate_labels="
194
+ self.translate_labels = value
195
+ end
196
+
197
+ def self.translate
198
+ deprecation_warn "SimpleForm.translate is disabled in favor of translate_labels"
199
+ self.translate_labels
200
+ end
201
+
202
+ def self.deprecation_warn(message)
203
+ ActiveSupport::Deprecation.warn "[SIMPLE_FORM] #{message}", caller
204
+ end
205
+
206
+ def self.additional_classes_for(component)
207
+ generate_additional_classes_for.include?(component) ? yield : []
208
+ end
209
+
210
+ # Default way to setup SimpleForm. Run rails generate simple_form:install
211
+ # to create a fresh initializer with all configuration values.
212
+ def self.setup
213
+ yield self
214
+
215
+ unless @@deprecated.empty?
216
+ raise "[SIMPLE FORM] Your SimpleForm initializer file is using the following methods: #{@@deprecated.to_sentence}. " <<
217
+ "Those methods are part of the outdated configuration API. Updating to the new API is easy and fast. " <<
218
+ "Check for more info here: https://github.com/plataformatec/simple_form/wiki/Upgrading-to-Simple-Form-2.0"
219
+ end
220
+ end
221
+ end