diff --git a/lib/simple_form.rb b/lib/simple_form.rb
index a241bf27..26eed85a 100644
--- a/lib/simple_form.rb
+++ b/lib/simple_form.rb
@@ -24,6 +24,18 @@ module SimpleForm
SimpleForm::Components.eager_load!
end
+ CUSTOM_INPUT_DEPRECATION_WARN = <<-WARN
+%{name} method now accepts a `wrapper_options` argument. The method definition without the argument is deprecated and will be removed in the next Simple Form version. Change your code from:
+
+ def %{name}
+
+to
+
+ def %{name}(wrapper_options)
+
+See https://github.com/plataformatec/simple_form/pull/997 for more information.
+ WARN
+
## CONFIGURATION OPTIONS
# Method used to tidy up errors.
@@ -189,7 +201,7 @@ module SimpleForm
end
# Builds a new wrapper using SimpleForm::Wrappers::Builder.
- def self.build(options={})
+ def self.build(options = {})
options[:tag] = :div if options[:tag].nil?
builder = SimpleForm::Wrappers::Builder.new(options)
yield builder
diff --git a/lib/simple_form/action_view_extensions/form_helper.rb b/lib/simple_form/action_view_extensions/form_helper.rb
index 1a2d3017..e5bf66b0 100644
--- a/lib/simple_form/action_view_extensions/form_helper.rb
+++ b/lib/simple_form/action_view_extensions/form_helper.rb
@@ -10,7 +10,7 @@ module SimpleForm
#
module FormHelper
- def simple_form_for(record, options={}, &block)
+ def simple_form_for(record, options = {}, &block)
options[:builder] ||= SimpleForm::FormBuilder
options[:html] ||= {}
unless options[:html].key?(:novalidate)
diff --git a/lib/simple_form/components/errors.rb b/lib/simple_form/components/errors.rb
index aad48335..b4bacf85 100644
--- a/lib/simple_form/components/errors.rb
+++ b/lib/simple_form/components/errors.rb
@@ -1,7 +1,7 @@
module SimpleForm
module Components
module Errors
- def error
+ def error(wrapper_options = nil)
error_text if has_errors?
end
diff --git a/lib/simple_form/components/hints.rb b/lib/simple_form/components/hints.rb
index f9890d5b..9323101d 100644
--- a/lib/simple_form/components/hints.rb
+++ b/lib/simple_form/components/hints.rb
@@ -2,7 +2,7 @@ module SimpleForm
module Components
# Needs to be enabled in order to do automatic lookups.
module Hints
- def hint
+ def hint(wrapper_options = nil)
@hint ||= begin
hint = options[:hint]
diff --git a/lib/simple_form/components/html5.rb b/lib/simple_form/components/html5.rb
index e3bec5bd..9d4fe515 100644
--- a/lib/simple_form/components/html5.rb
+++ b/lib/simple_form/components/html5.rb
@@ -5,7 +5,7 @@ module SimpleForm
@html5 = false
end
- def html5
+ def html5(wrapper_options = nil)
@html5 = true
if has_required?
input_html_options[:required] = true
diff --git a/lib/simple_form/components/label_input.rb b/lib/simple_form/components/label_input.rb
index f2be3ac3..080fdd96 100644
--- a/lib/simple_form/components/label_input.rb
+++ b/lib/simple_form/components/label_input.rb
@@ -7,8 +7,26 @@ module SimpleForm
include SimpleForm::Components::Labels
end
- def label_input
- options[:label] == false ? input : (label + input)
+ def label_input(wrapper_options = nil)
+ if options[:label] == false
+ deprecated_component(:input, wrapper_options)
+ else
+ deprecated_component(:label, wrapper_options) + deprecated_component(:input, wrapper_options)
+ end
+ end
+
+ private
+
+ def deprecated_component(namespace, wrapper_options)
+ method = method(namespace)
+
+ if method.arity == 0
+ ActiveSupport::Deprecation.warn(SimpleForm::CUSTOM_INPUT_DEPRECATION_WARN % { name: namespace })
+
+ method.call
+ else
+ method.call(wrapper_options)
+ end
end
end
end
diff --git a/lib/simple_form/components/labels.rb b/lib/simple_form/components/labels.rb
index ae33f5d2..5943a37c 100644
--- a/lib/simple_form/components/labels.rb
+++ b/lib/simple_form/components/labels.rb
@@ -21,11 +21,13 @@ module SimpleForm
end
end
- def label
+ def label(wrapper_options = nil)
+ label_options = merge_wrapper_options(label_html_options, wrapper_options)
+
if generate_label_for_attribute?
- @builder.label(label_target, label_text, label_html_options)
+ @builder.label(label_target, label_text, label_options)
else
- template.label_tag(nil, label_text, label_html_options)
+ template.label_tag(nil, label_text, label_options)
end
end
@@ -46,6 +48,7 @@ module SimpleForm
if options.key?(:input_html) && options[:input_html].key?(:id)
label_options[:for] = options[:input_html][:id]
end
+
label_options
end
diff --git a/lib/simple_form/components/maxlength.rb b/lib/simple_form/components/maxlength.rb
index 8ad42646..ebb265e7 100644
--- a/lib/simple_form/components/maxlength.rb
+++ b/lib/simple_form/components/maxlength.rb
@@ -2,7 +2,7 @@ module SimpleForm
module Components
# Needs to be enabled in order to do automatic lookups.
module Maxlength
- def maxlength
+ def maxlength(wrapper_options = nil)
input_html_options[:maxlength] ||= maximum_length_from_validation || limit
nil
end
diff --git a/lib/simple_form/components/min_max.rb b/lib/simple_form/components/min_max.rb
index 234845c2..95c24ac8 100644
--- a/lib/simple_form/components/min_max.rb
+++ b/lib/simple_form/components/min_max.rb
@@ -1,7 +1,7 @@
module SimpleForm
module Components
module MinMax
- def min_max
+ def min_max(wrapper_options = nil)
if numeric_validator = find_numericality_validator
validator_options = numeric_validator.options
input_html_options[:min] ||= minimum_value(validator_options)
diff --git a/lib/simple_form/components/pattern.rb b/lib/simple_form/components/pattern.rb
index 889a7333..82a21a5d 100644
--- a/lib/simple_form/components/pattern.rb
+++ b/lib/simple_form/components/pattern.rb
@@ -2,7 +2,7 @@ module SimpleForm
module Components
# Needs to be enabled in order to do automatic lookups.
module Pattern
- def pattern
+ def pattern(wrapper_options = nil)
input_html_options[:pattern] ||= pattern_source
nil
end
diff --git a/lib/simple_form/components/placeholders.rb b/lib/simple_form/components/placeholders.rb
index 992044ed..9a7520e4 100644
--- a/lib/simple_form/components/placeholders.rb
+++ b/lib/simple_form/components/placeholders.rb
@@ -2,7 +2,7 @@ module SimpleForm
module Components
# Needs to be enabled in order to do automatic lookups.
module Placeholders
- def placeholder
+ def placeholder(wrapper_options = nil)
input_html_options[:placeholder] ||= placeholder_text
nil
end
diff --git a/lib/simple_form/components/readonly.rb b/lib/simple_form/components/readonly.rb
index f4a986c2..37c2b385 100644
--- a/lib/simple_form/components/readonly.rb
+++ b/lib/simple_form/components/readonly.rb
@@ -2,7 +2,7 @@ module SimpleForm
module Components
# Needs to be enabled in order to do automatic lookups.
module Readonly
- def readonly
+ def readonly(wrapper_options = nil)
if readonly_attribute? && !has_readonly?
input_html_options[:readonly] ||= true
input_html_classes << :readonly
diff --git a/lib/simple_form/form_builder.rb b/lib/simple_form/form_builder.rb
index 94641f92..81f775a8 100644
--- a/lib/simple_form/form_builder.rb
+++ b/lib/simple_form/form_builder.rb
@@ -106,7 +106,7 @@ module SimpleForm
# Some inputs, as :time_zone and :country accepts a :priority option. If none is
# given SimpleForm.time_zone_priority and SimpleForm.country_priority are used respectively.
#
- def input(attribute_name, options={}, &block)
+ def input(attribute_name, options = {}, &block)
options = @defaults.deep_dup.deep_merge(options) if @defaults
input = find_input(attribute_name, options, &block)
@@ -130,14 +130,15 @@ module SimpleForm
#
#
- def input_field(attribute_name, options={})
+ def input_field(attribute_name, options = {})
options = options.dup
options[:input_html] = options.except(:as, :boolean_style, :collection, :label_method, :value_method, *ATTRIBUTE_COMPONENTS)
options = @defaults.deep_dup.deep_merge(options) if @defaults
input = find_input(attribute_name, options)
wrapper = find_wrapper(input.input_type, options)
- components = (wrapper.components & ATTRIBUTE_COMPONENTS) + [:input]
+ components = (wrapper.components.map(&:namespace) & ATTRIBUTE_COMPONENTS) + [:input]
+ components = components.map { |component| SimpleForm::Wrappers::Leaf.new(component) }
SimpleForm::Wrappers::Root.new(components, wrapper.options.merge(wrapper: false)).render input
end
@@ -170,7 +171,7 @@ module SimpleForm
#
# Please note that the association helper is currently only tested with Active Record. Depending on the ORM you are using your mileage may vary.
#
- def association(association, options={}, &block)
+ def association(association, options = {}, &block)
options = options.dup
return simple_fields_for(*[association,
@@ -241,7 +242,7 @@ module SimpleForm
# f.error :name
# f.error :name, id: "cool_error"
#
- def error(attribute_name, options={})
+ def error(attribute_name, options = {})
options = options.dup
options[:error_html] = options.except(:error_tag, :error_prefix, :error_method)
@@ -258,7 +259,7 @@ module SimpleForm
#
# f.full_error :token #=> Token is invalid
#
- def full_error(attribute_name, options={})
+ def full_error(attribute_name, options = {})
options = options.dup
options[:error_prefix] ||= if object.class.respond_to?(:human_attribute_name)
@@ -280,7 +281,7 @@ module SimpleForm
# f.hint :name, id: "cool_hint"
# f.hint "Don't forget to accept this"
#
- def hint(attribute_name, options={})
+ def hint(attribute_name, options = {})
options = options.dup
options[:hint_html] = options.except(:hint_tag, :hint)
@@ -331,7 +332,7 @@ module SimpleForm
# f.error_notification message: 'Something went wrong'
# f.error_notification id: 'user_error_message', class: 'form_error'
#
- def error_notification(options={})
+ def error_notification(options = {})
SimpleForm::ErrorNotification.new(self, options).render
end
@@ -471,7 +472,7 @@ module SimpleForm
private
# Find an input based on the attribute name.
- def find_input(attribute_name, options={}, &block) #:nodoc:
+ def find_input(attribute_name, options = {}, &block) #:nodoc:
column = find_attribute_column(attribute_name)
input_type = default_input_type(attribute_name, column, options)
diff --git a/lib/simple_form/helpers.rb b/lib/simple_form/helpers.rb
index 6567a7de..effeae5c 100644
--- a/lib/simple_form/helpers.rb
+++ b/lib/simple_form/helpers.rb
@@ -3,10 +3,10 @@ module SimpleForm
# For instance, disabled cannot be turned on automatically, it requires the
# user to explicitly pass the option disabled: true so it may work.
module Helpers
- autoload :Autofocus, 'simple_form/helpers/autofocus'
- autoload :Disabled, 'simple_form/helpers/disabled'
- autoload :Readonly, 'simple_form/helpers/readonly'
- autoload :Required, 'simple_form/helpers/required'
- autoload :Validators, 'simple_form/helpers/validators'
+ autoload :Autofocus, 'simple_form/helpers/autofocus'
+ autoload :Disabled, 'simple_form/helpers/disabled'
+ autoload :Readonly, 'simple_form/helpers/readonly'
+ autoload :Required, 'simple_form/helpers/required'
+ autoload :Validators, 'simple_form/helpers/validators'
end
end
diff --git a/lib/simple_form/inputs/base.rb b/lib/simple_form/inputs/base.rb
index e9eb3def..510d3766 100644
--- a/lib/simple_form/inputs/base.rb
+++ b/lib/simple_form/inputs/base.rb
@@ -79,7 +79,7 @@ module SimpleForm
end
end
- def input
+ def input(wrapper_options = nil)
raise NotImplementedError
end
@@ -167,7 +167,7 @@ module SimpleForm
# email: 'E-mail.'
#
# Take a look at our locale example file.
- def translate(namespace, default='')
+ def translate(namespace, default = '')
model_names = lookup_model_names.dup
lookups = []
@@ -184,6 +184,18 @@ module SimpleForm
I18n.t(lookups.shift, scope: :"simple_form.#{namespace}", default: lookups).presence
end
+
+ def merge_wrapper_options(options, wrapper_options)
+ if wrapper_options
+ options.merge(wrapper_options) do |_, oldval, newval|
+ if Array === oldval
+ oldval + Array(newval)
+ end
+ end
+ else
+ options
+ end
+ end
end
end
end
diff --git a/lib/simple_form/inputs/block_input.rb b/lib/simple_form/inputs/block_input.rb
index 483d393c..2bc2ff98 100644
--- a/lib/simple_form/inputs/block_input.rb
+++ b/lib/simple_form/inputs/block_input.rb
@@ -6,7 +6,7 @@ module SimpleForm
@block = block
end
- def input
+ def input(wrapper_options = nil)
template.capture(&@block)
end
end
diff --git a/lib/simple_form/inputs/boolean_input.rb b/lib/simple_form/inputs/boolean_input.rb
index b649685b..cf34f2e8 100644
--- a/lib/simple_form/inputs/boolean_input.rb
+++ b/lib/simple_form/inputs/boolean_input.rb
@@ -1,31 +1,36 @@
module SimpleForm
module Inputs
class BooleanInput < Base
- def input
+ def input(wrapper_options = nil)
+ merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
+
if nested_boolean_style?
build_hidden_field_for_checkbox +
template.label_tag(nil, class: SimpleForm.boolean_label_class) {
- build_check_box_without_hidden_field + inline_label
+ build_check_box_without_hidden_field(merged_input_options) +
+ inline_label
}
else
- build_check_box
+ build_check_box(unchecked_value, merged_input_options)
end
end
- def label_input
+ def label_input(wrapper_options = nil)
if options[:label] == false
- input
+ input(wrapper_options)
elsif nested_boolean_style?
html_options = label_html_options.dup
html_options[:class] ||= []
html_options[:class].push(SimpleForm.boolean_label_class) if SimpleForm.boolean_label_class
+ merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
+
build_hidden_field_for_checkbox +
@builder.label(label_target, html_options) {
- build_check_box_without_hidden_field + label_text
+ build_check_box_without_hidden_field(merged_input_options) + label_text
}
else
- input + label
+ input(wrapper_options) + label(wrapper_options)
end
end
@@ -35,14 +40,14 @@ module SimpleForm
# reuse the method for nested boolean style, but with no unchecked value,
# which won't generate the hidden checkbox. This is the default functionality
# in Rails > 3.2.1, and is backported in SimpleForm AV helpers.
- def build_check_box(unchecked_value = unchecked_value)
+ def build_check_box(unchecked_value, options)
@builder.check_box(attribute_name, input_html_options, checked_value, unchecked_value)
end
# Build a checkbox without generating the hidden field. See
# #build_hidden_field_for_checkbox for more info.
- def build_check_box_without_hidden_field
- build_check_box(nil)
+ def build_check_box_without_hidden_field(options)
+ build_check_box(nil, options)
end
# Create a hidden field for the current checkbox, so we can simulate Rails
diff --git a/lib/simple_form/inputs/collection_input.rb b/lib/simple_form/inputs/collection_input.rb
index 2b1eae56..db10abd9 100644
--- a/lib/simple_form/inputs/collection_input.rb
+++ b/lib/simple_form/inputs/collection_input.rb
@@ -12,7 +12,7 @@ module SimpleForm
end
end
- def input
+ def input(wrapper_options = nil)
raise NotImplementedError,
"input should be implemented by classes inheriting from CollectionInput"
end
diff --git a/lib/simple_form/inputs/collection_radio_buttons_input.rb b/lib/simple_form/inputs/collection_radio_buttons_input.rb
index 52d47785..b550f982 100644
--- a/lib/simple_form/inputs/collection_radio_buttons_input.rb
+++ b/lib/simple_form/inputs/collection_radio_buttons_input.rb
@@ -1,12 +1,15 @@
module SimpleForm
module Inputs
class CollectionRadioButtonsInput < CollectionInput
- def input
+ def input(wrapper_options = nil)
label_method, value_method = detect_collection_methods
+ merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
+
@builder.send("collection_#{input_type}",
attribute_name, collection, value_method, label_method,
- input_options, input_html_options, &collection_block_for_nested_boolean_style
+ input_options, merged_input_options,
+ &collection_block_for_nested_boolean_style
)
end
diff --git a/lib/simple_form/inputs/collection_select_input.rb b/lib/simple_form/inputs/collection_select_input.rb
index cb53d4ee..35f8978e 100644
--- a/lib/simple_form/inputs/collection_select_input.rb
+++ b/lib/simple_form/inputs/collection_select_input.rb
@@ -1,12 +1,14 @@
module SimpleForm
module Inputs
class CollectionSelectInput < CollectionInput
- def input
+ def input(wrapper_options = nil)
label_method, value_method = detect_collection_methods
+ merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
+
@builder.collection_select(
attribute_name, collection, value_method, label_method,
- input_options, input_html_options
+ input_options, merged_input_options
)
end
end
diff --git a/lib/simple_form/inputs/date_time_input.rb b/lib/simple_form/inputs/date_time_input.rb
index 0414ad2f..27cf975e 100644
--- a/lib/simple_form/inputs/date_time_input.rb
+++ b/lib/simple_form/inputs/date_time_input.rb
@@ -1,11 +1,13 @@
module SimpleForm
module Inputs
class DateTimeInput < Base
- def input
+ def input(wrapper_options = nil)
+ merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
+
if use_html5_inputs?
- @builder.send(:"#{input_type}_field", attribute_name, input_html_options)
+ @builder.send(:"#{input_type}_field", attribute_name, merged_input_options)
else
- @builder.send(:"#{input_type}_select", attribute_name, input_options, input_html_options)
+ @builder.send(:"#{input_type}_select", attribute_name, input_options, merged_input_options)
end
end
diff --git a/lib/simple_form/inputs/file_input.rb b/lib/simple_form/inputs/file_input.rb
index a0ee2908..d964dd90 100644
--- a/lib/simple_form/inputs/file_input.rb
+++ b/lib/simple_form/inputs/file_input.rb
@@ -1,8 +1,10 @@
module SimpleForm
module Inputs
class FileInput < Base
- def input
- @builder.file_field(attribute_name, input_html_options)
+ def input(wrapper_options = nil)
+ merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
+
+ @builder.file_field(attribute_name, merged_input_options)
end
end
end
diff --git a/lib/simple_form/inputs/grouped_collection_select_input.rb b/lib/simple_form/inputs/grouped_collection_select_input.rb
index bd40ee53..d1cee8fe 100644
--- a/lib/simple_form/inputs/grouped_collection_select_input.rb
+++ b/lib/simple_form/inputs/grouped_collection_select_input.rb
@@ -1,11 +1,14 @@
module SimpleForm
module Inputs
class GroupedCollectionSelectInput < CollectionInput
- def input
+ def input(wrapper_options = nil)
label_method, value_method = detect_collection_methods
+
+ merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
+
@builder.grouped_collection_select(attribute_name, grouped_collection,
group_method, group_label_method, value_method, label_method,
- input_options, input_html_options)
+ input_options, merged_input_options)
end
private
diff --git a/lib/simple_form/inputs/hidden_input.rb b/lib/simple_form/inputs/hidden_input.rb
index 889d8d3d..53b6ad23 100644
--- a/lib/simple_form/inputs/hidden_input.rb
+++ b/lib/simple_form/inputs/hidden_input.rb
@@ -3,8 +3,10 @@ module SimpleForm
class HiddenInput < Base
disable :label, :errors, :hint, :required
- def input
- @builder.hidden_field(attribute_name, input_html_options)
+ def input(wrapper_options = nil)
+ merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
+
+ @builder.hidden_field(attribute_name, merged_input_options)
end
private
diff --git a/lib/simple_form/inputs/numeric_input.rb b/lib/simple_form/inputs/numeric_input.rb
index ce0c3567..87b2ac91 100644
--- a/lib/simple_form/inputs/numeric_input.rb
+++ b/lib/simple_form/inputs/numeric_input.rb
@@ -3,16 +3,17 @@ module SimpleForm
class NumericInput < Base
enable :placeholder, :min_max
- def input
+ def input(wrapper_options = nil)
input_html_classes.unshift("numeric")
if html5?
input_html_options[:type] ||= "number"
input_html_options[:step] ||= integer? ? 1 : "any"
end
- @builder.text_field(attribute_name, input_html_options)
- end
- private
+ merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
+
+ @builder.text_field(attribute_name, merged_input_options)
+ end
end
end
end
diff --git a/lib/simple_form/inputs/password_input.rb b/lib/simple_form/inputs/password_input.rb
index 0a9a0ba6..0aa7385a 100644
--- a/lib/simple_form/inputs/password_input.rb
+++ b/lib/simple_form/inputs/password_input.rb
@@ -3,8 +3,10 @@ module SimpleForm
class PasswordInput < Base
enable :placeholder, :maxlength
- def input
- @builder.password_field(attribute_name, input_html_options)
+ def input(wrapper_options = nil)
+ merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
+
+ @builder.password_field(attribute_name, merged_input_options)
end
end
end
diff --git a/lib/simple_form/inputs/priority_input.rb b/lib/simple_form/inputs/priority_input.rb
index 19213dfd..c2272a3e 100644
--- a/lib/simple_form/inputs/priority_input.rb
+++ b/lib/simple_form/inputs/priority_input.rb
@@ -1,9 +1,11 @@
module SimpleForm
module Inputs
class PriorityInput < CollectionSelectInput
- def input
+ def input(wrapper_options = nil)
+ merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
+
@builder.send(:"#{input_type}_select", attribute_name, input_priority,
- input_options, input_html_options)
+ input_options, merged_input_options)
end
def input_priority
diff --git a/lib/simple_form/inputs/range_input.rb b/lib/simple_form/inputs/range_input.rb
index f231df33..00116fa3 100644
--- a/lib/simple_form/inputs/range_input.rb
+++ b/lib/simple_form/inputs/range_input.rb
@@ -1,7 +1,7 @@
module SimpleForm
module Inputs
class RangeInput < NumericInput
- def input
+ def input(wrapper_options = nil)
if html5?
input_html_options[:type] ||= "range"
input_html_options[:step] ||= 1
diff --git a/lib/simple_form/inputs/string_input.rb b/lib/simple_form/inputs/string_input.rb
index 44ba6910..4752be92 100644
--- a/lib/simple_form/inputs/string_input.rb
+++ b/lib/simple_form/inputs/string_input.rb
@@ -3,13 +3,15 @@ module SimpleForm
class StringInput < Base
enable :placeholder, :maxlength, :pattern
- def input
+ def input(wrapper_options = nil)
unless string?
input_html_classes.unshift("string")
input_html_options[:type] ||= input_type if html5?
end
- @builder.text_field(attribute_name, input_html_options)
+ merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
+
+ @builder.text_field(attribute_name, merged_input_options)
end
private
diff --git a/lib/simple_form/inputs/text_input.rb b/lib/simple_form/inputs/text_input.rb
index 8c840cba..d90eedac 100644
--- a/lib/simple_form/inputs/text_input.rb
+++ b/lib/simple_form/inputs/text_input.rb
@@ -3,8 +3,10 @@ module SimpleForm
class TextInput < Base
enable :placeholder, :maxlength
- def input
- @builder.text_area(attribute_name, input_html_options)
+ def input(wrapper_options = nil)
+ merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
+
+ @builder.text_area(attribute_name, merged_input_options)
end
end
end
diff --git a/lib/simple_form/wrappers.rb b/lib/simple_form/wrappers.rb
index 20241e4c..8aa11e92 100644
--- a/lib/simple_form/wrappers.rb
+++ b/lib/simple_form/wrappers.rb
@@ -4,5 +4,6 @@ module SimpleForm
autoload :Many, 'simple_form/wrappers/many'
autoload :Root, 'simple_form/wrappers/root'
autoload :Single, 'simple_form/wrappers/single'
+ autoload :Leaf, 'simple_form/wrappers/leaf'
end
end
diff --git a/lib/simple_form/wrappers/builder.rb b/lib/simple_form/wrappers/builder.rb
index 6a00f4f2..0889ad10 100644
--- a/lib/simple_form/wrappers/builder.rb
+++ b/lib/simple_form/wrappers/builder.rb
@@ -45,20 +45,20 @@ module SimpleForm
@components = []
end
- def use(name, options=nil, &block)
+ def use(name, options = {}, &block)
if options && wrapper = options[:wrap_with]
- @components << Single.new(name, wrapper)
+ @components << Single.new(name, wrapper, options.except(:wrap_with))
else
- @components << name
+ @components << Leaf.new(name, options)
end
end
- def optional(name, options=nil, &block)
+ def optional(name, options = {}, &block)
@options[name] = false
use(name, options, &block)
end
- def wrapper(name, options=nil)
+ def wrapper(name, options = nil)
if block_given?
name, options = nil, name if name.is_a?(Hash)
builder = self.class.new(@options)
diff --git a/lib/simple_form/wrappers/leaf.rb b/lib/simple_form/wrappers/leaf.rb
new file mode 100644
index 00000000..b2ecfbe6
--- /dev/null
+++ b/lib/simple_form/wrappers/leaf.rb
@@ -0,0 +1,28 @@
+module SimpleForm
+ module Wrappers
+ class Leaf
+ attr_reader :namespace
+
+ def initialize(namespace, options = {})
+ @namespace = namespace
+ @options = options
+ end
+
+ def render(input)
+ method = input.method(@namespace)
+
+ if method.arity == 0
+ ActiveSupport::Deprecation.warn(SimpleForm::CUSTOM_INPUT_DEPRECATION_WARN % { name: @namespace })
+
+ method.call
+ else
+ method.call(@options)
+ end
+ end
+
+ def find(name)
+ return self if @namespace == name
+ end
+ end
+ end
+end
diff --git a/lib/simple_form/wrappers/many.rb b/lib/simple_form/wrappers/many.rb
index 93819717..fcfbafff 100644
--- a/lib/simple_form/wrappers/many.rb
+++ b/lib/simple_form/wrappers/many.rb
@@ -1,7 +1,7 @@
module SimpleForm
module Wrappers
# A wrapper is an object that holds several components and render them.
- # A component may either be a symbol or any object that responds to `render`.
+ # A component may be any object that responds to `render`.
# This API allows inputs/components to be easily wrapped, removing the
# need to modify the code only to wrap input in an extra tag.
#
@@ -12,7 +12,7 @@ module SimpleForm
attr_reader :namespace, :defaults, :components
alias :to_sym :namespace
- def initialize(namespace, components, defaults={})
+ def initialize(namespace, components, defaults = {})
@namespace = namespace
@components = components
@defaults = defaults
@@ -25,8 +25,8 @@ module SimpleForm
options = input.options
components.each do |component|
- next if options[component] == false
- rendered = component.respond_to?(:render) ? component.render(input) : input.send(component)
+ next if options[component.namespace] == false
+ rendered = component.render(input)
content.safe_concat rendered.to_s if rendered
end
diff --git a/lib/simple_form/wrappers/single.rb b/lib/simple_form/wrappers/single.rb
index eda04208..77a6daf3 100644
--- a/lib/simple_form/wrappers/single.rb
+++ b/lib/simple_form/wrappers/single.rb
@@ -2,20 +2,24 @@ module SimpleForm
module Wrappers
# `Single` is an optimization for a wrapper that has only one component.
class Single < Many
- def initialize(name, options={})
- super(name, [name], options)
+ def initialize(name, wrapper_options = {}, options = {})
+ super(name, [Leaf.new(name, options)], wrapper_options)
end
def render(input)
options = input.options
if options[namespace] != false
- content = input.send(namespace)
+ content = component.render(input)
wrap(input, options, content) if content
end
end
private
+ def component
+ components.first
+ end
+
def html_options(options)
[:label, :input].include?(namespace) ? {} : super
end
diff --git a/test/action_view_extensions/builder_test.rb b/test/action_view_extensions/builder_test.rb
index 12766408..bb45b8ad 100644
--- a/test/action_view_extensions/builder_test.rb
+++ b/test/action_view_extensions/builder_test.rb
@@ -8,13 +8,13 @@ class BuilderTest < ActionView::TestCase
end
end
- def with_collection_radio_buttons(object, attribute, collection, value_method, text_method, options={}, html_options={}, &block)
+ def with_collection_radio_buttons(object, attribute, collection, value_method, text_method, options = {}, html_options = {}, &block)
with_concat_form_for(object) do |f|
f.collection_radio_buttons attribute, collection, value_method, text_method, options, html_options, &block
end
end
- def with_collection_check_boxes(object, attribute, collection, value_method, text_method, options={}, html_options={}, &block)
+ def with_collection_check_boxes(object, attribute, collection, value_method, text_method, options = {}, html_options = {}, &block)
with_concat_form_for(object) do |f|
f.collection_check_boxes attribute, collection, value_method, text_method, options, html_options, &block
end
diff --git a/test/components/label_test.rb b/test/components/label_test.rb
index 01c6e546..56637daa 100644
--- a/test/components/label_test.rb
+++ b/test/components/label_test.rb
@@ -7,7 +7,7 @@ class IsolatedLabelTest < ActionView::TestCase
SimpleForm::Inputs::Base.reset_i18n_cache :translate_required_html
end
- def with_label_for(object, attribute_name, type, options={})
+ def with_label_for(object, attribute_name, type, options = {})
with_concat_form_for(object) do |f|
options[:reflection] = Association.new(Company, :company, {}) if options.delete(:setup_association)
SimpleForm::Inputs::Base.new(f, attribute_name, nil, type, options).label
diff --git a/test/form_builder/error_notification_test.rb b/test/form_builder/error_notification_test.rb
index ad04e19f..751efbe9 100644
--- a/test/form_builder/error_notification_test.rb
+++ b/test/form_builder/error_notification_test.rb
@@ -3,7 +3,7 @@ require 'test_helper'
# Tests for f.error_notification
class ErrorNotificationTest < ActionView::TestCase
- def with_error_notification_for(object, options={}, &block)
+ def with_error_notification_for(object, options = {}, &block)
with_concat_form_for(object) do |f|
f.error_notification(options)
end
diff --git a/test/form_builder/wrapper_test.rb b/test/form_builder/wrapper_test.rb
index fa27204b..a7bd5b72 100644
--- a/test/form_builder/wrapper_test.rb
+++ b/test/form_builder/wrapper_test.rb
@@ -211,4 +211,45 @@ class WrapperTest < ActionView::TestCase
assert_select "section.custom_wrapper div.another_wrapper label"
assert_select "section.custom_wrapper div.another_wrapper input.string"
end
+
+ test 'input accepts attributes in the DSL' do
+ swap_wrapper :default, self.custom_wrapper_with_input_class do
+ with_concat_form_for @user do |f|
+ concat f.input :name
+ end
+ end
+
+ assert_select "div.custom_wrapper input.string.inline-class"
+ end
+
+ test 'label accepts attributes in the DSL' do
+ swap_wrapper :default, self.custom_wrapper_with_label_class do
+ with_concat_form_for @user do |f|
+ concat f.input :name
+ end
+ end
+
+ assert_select "div.custom_wrapper label.string.inline-class"
+ end
+
+ test 'label_input accepts attributes in the DSL' do
+ swap_wrapper :default, self.custom_wrapper_with_label_input_class do
+ with_concat_form_for @user do |f|
+ concat f.input :name
+ end
+ end
+
+ assert_select "div.custom_wrapper label.string.inline-class"
+ assert_select "div.custom_wrapper input.string.inline-class"
+ end
+
+ test 'input accepts data attributes in the DSL' do
+ swap_wrapper :default, self.custom_wrapper_with_input_attributes do
+ with_concat_form_for @user do |f|
+ concat f.input :name
+ end
+ end
+
+ assert_select "div.custom_wrapper input.string[data-modal=true]"
+ end
end
diff --git a/test/inputs/discovery_test.rb b/test/inputs/discovery_test.rb
index 307c5461..6103f9ba 100644
--- a/test/inputs/discovery_test.rb
+++ b/test/inputs/discovery_test.rb
@@ -2,7 +2,7 @@ require 'test_helper'
class DiscoveryTest < ActionView::TestCase
# Setup new inputs and remove them after the test.
- def discovery(value=false)
+ def discovery(value = false)
swap SimpleForm, cache_discovery: value do
begin
load "support/discovery_inputs.rb"
@@ -12,6 +12,7 @@ class DiscoveryTest < ActionView::TestCase
Object.send :remove_const, :StringInput
Object.send :remove_const, :NumericInput
Object.send :remove_const, :CustomizedInput
+ Object.send :remove_const, :DeprecatedInput
Object.send :remove_const, :CollectionSelectInput
end
end
@@ -66,4 +67,14 @@ class DiscoveryTest < ActionView::TestCase
assert_select 'form select#user_active.select.chosen'
end
end
+
+ test 'inputs method without wrapper_options are deprecated' do
+ discovery do
+ assert_deprecated do
+ with_form_for @user, :name, as: :deprecated
+ end
+
+ assert_select 'form section input#user_name.string'
+ end
+ end
end
diff --git a/test/support/discovery_inputs.rb b/test/support/discovery_inputs.rb
index 167f33dc..eebf4db8 100644
--- a/test/support/discovery_inputs.rb
+++ b/test/support/discovery_inputs.rb
@@ -1,16 +1,26 @@
class StringInput < SimpleForm::Inputs::StringInput
- def input
+ def input(wrapper_options = nil)
"".html_safe
end
end
class NumericInput < SimpleForm::Inputs::NumericInput
- def input
+ def input(wrapper_options = nil)
"".html_safe
end
end
class CustomizedInput < SimpleForm::Inputs::StringInput
+ def input(wrapper_options = nil)
+ "".html_safe
+ end
+
+ def input_method
+ :text_field
+ end
+end
+
+class DeprecatedInput < SimpleForm::Inputs::StringInput
def input
"".html_safe
end
diff --git a/test/support/misc_helpers.rb b/test/support/misc_helpers.rb
index 5ddac2c3..61b03d55 100644
--- a/test/support/misc_helpers.rb
+++ b/test/support/misc_helpers.rb
@@ -46,7 +46,7 @@ module MiscHelpers
end
end
- def swap_wrapper(name=:default, wrapper=self.custom_wrapper)
+ def swap_wrapper(name = :default, wrapper = self.custom_wrapper)
old = SimpleForm.wrappers[name]
SimpleForm.wrappers[name] = wrapper
yield
@@ -68,6 +68,32 @@ module MiscHelpers
end
end
+ def custom_wrapper_with_input_class
+ SimpleForm.build tag: :div, class: "custom_wrapper" do |b|
+ b.use :label
+ b.use :input, class: 'inline-class'
+ end
+ end
+
+ def custom_wrapper_with_label_class
+ SimpleForm.build tag: :div, class: "custom_wrapper" do |b|
+ b.use :label, class: 'inline-class'
+ b.use :input
+ end
+ end
+
+ def custom_wrapper_with_input_attributes
+ SimpleForm.build tag: :div, class: "custom_wrapper" do |b|
+ b.use :input, data: { modal: true }
+ end
+ end
+
+ def custom_wrapper_with_label_input_class
+ SimpleForm.build tag: :div, class: "custom_wrapper" do |b|
+ b.use :label_input, class: 'inline-class'
+ end
+ end
+
def custom_wrapper_with_wrapped_input
SimpleForm.build tag: :div, class: "custom_wrapper" do |b|
b.wrapper tag: :div, class: 'elem' do |component|
@@ -142,7 +168,7 @@ module MiscHelpers
end
end
- def with_input_for(object, attribute_name, type, options={})
+ def with_input_for(object, attribute_name, type, options = {})
with_concat_form_for(object) do |f|
f.input(attribute_name, options.merge(as: type))
end
diff --git a/test/support/models.rb b/test/support/models.rb
index 531aee58..77197ae7 100644
--- a/test/support/models.rb
+++ b/test/support/models.rb
@@ -66,7 +66,7 @@ class User
new attributes
end
- def initialize(options={})
+ def initialize(options = {})
@new_record = false
options.each do |key, value|
send("#{key}=", value)