Merge pull request #1093 from plataformatec/custom_inputs_namespaces

Custom inputs namespaces
This commit is contained in:
ulissesalmeida 2014-06-26 18:27:06 -03:00
commit a19333da63
6 changed files with 109 additions and 2 deletions

View File

@ -581,6 +581,28 @@ class CollectionSelectInput < SimpleForm::Inputs::CollectionSelectInput
end
```
If needed, you can namespace your custom inputs in a module and tell **Simple Form** to look for
their definitions in this module. This can avoid conflicts with other form libraries (like Formtastic) that look up
the global context to find inputs definition too.
```ruby
# app/inputs/custom_inputs/numeric_input
module CustomInputs
class NumericInput < SimpleForm::Inputs::NumericInput
def input_html_classes
super.push('no-spinner')
end
end
end
```
And in the **SimpleForm** initializer :
```ruby
# config/simple_form.rb
config.custom_inputs_namespaces << "CustomInputs"
```
## Custom form builder
You can create a custom form builder that uses **Simple Form**.

View File

@ -131,6 +131,10 @@ SimpleForm.setup do |config|
# type as key and the wrapper that will be used for all inputs with specified type.
# config.wrapper_mappings = { string: :prepend }
# Namespaces where SimpleForm should look for custom input classes that
# override default inputs.
# config.custom_inputs_namespaces << "CustomInputs"
# Default priority for time_zone inputs.
# config.time_zone_priority = nil

View File

@ -130,6 +130,14 @@ See https://github.com/plataformatec/simple_form/pull/997 for more information.
mattr_accessor :wrapper_mappings
@@wrapper_mappings = nil
# Namespaces where SimpleForm should look for custom input classes that override
# default inputs. Namespaces are given as string to allow lazy loading inputs.
# e.g. config.custom_inputs_namespaces << "CustomInputs"
# will try to find CustomInputs::NumericInput when an :integer
# field is called.
mattr_accessor :custom_inputs_namespaces
@@custom_inputs_namespaces = []
# Default priority for time_zone inputs.
mattr_accessor :time_zone_priority
@@time_zone_priority = nil

View File

@ -566,7 +566,9 @@ module SimpleForm
mapping_override(mapping) || mapping
else
camelized = "#{input_type.to_s.camelize}Input"
attempt_mapping(camelized, Object) || attempt_mapping(camelized, self.class) ||
attempt_mapping_with_custom_namespace(camelized) ||
attempt_mapping(camelized, Object) ||
attempt_mapping(camelized, self.class) ||
raise("No input found for #{input_type}")
end
end
@ -604,7 +606,9 @@ module SimpleForm
def mapping_override(klass)
name = klass.name
if name =~ /^SimpleForm::Inputs/
attempt_mapping name.split("::").last, Object
input_name = name.split("::").last
attempt_mapping_with_custom_namespace(input_name) ||
attempt_mapping(input_name, Object)
end
end
@ -617,5 +621,15 @@ module SimpleForm
raise if e.message !~ /#{mapping}$/
end
end
def attempt_mapping_with_custom_namespace(input_name)
SimpleForm.custom_inputs_namespaces.each do |namespace|
if (mapping = attempt_mapping(input_name, namespace.constantize))
return mapping
end
end
nil
end
end
end

View File

@ -14,6 +14,8 @@ class DiscoveryTest < ActionView::TestCase
Object.send :remove_const, :CustomizedInput
Object.send :remove_const, :DeprecatedInput
Object.send :remove_const, :CollectionSelectInput
CustomInputs.send :remove_const, :PasswordInput
CustomInputs.send :remove_const, :NumericInput
end
end
end
@ -61,6 +63,43 @@ class DiscoveryTest < ActionView::TestCase
end
end
test 'builder discovers new maped inputs from configured namespaces if not cached' do
discovery do
swap SimpleForm, custom_inputs_namespaces: ['CustomInputs'] do
with_form_for @user, :password
assert_select 'form input#user_password.password-custom-input'
end
end
end
test 'builder discovers new maped inputs from configured namespaces before the ones from top level namespace' do
discovery do
swap SimpleForm, custom_inputs_namespaces: ['CustomInputs'] do
with_form_for @user, :age
assert_select 'form input#user_age.numeric-custom-input'
end
end
end
test 'builder discovers new custom inputs from configured namespace before the ones from top level namespace' do
discovery do
swap SimpleForm, custom_inputs_namespaces: ['CustomInputs'] do
with_form_for @user, :name, as: 'customized'
assert_select 'form input#user_name.customized-namespace-custom-input'
end
end
end
test 'raises error when configured namespace does not exists' do
discovery do
swap SimpleForm, custom_inputs_namespaces: ['InvalidNamespace'] do
assert_raise NameError do
with_form_for @user, :age
end
end
end
end
test 'new inputs can override the input_html_options' do
discovery do
with_form_for @user, :active, as: :select

View File

@ -35,3 +35,23 @@ class CollectionSelectInput < SimpleForm::Inputs::CollectionSelectInput
super.push('chosen')
end
end
module CustomInputs
class CustomizedInput < SimpleForm::Inputs::StringInput
def input_html_classes
super.push('customized-namespace-custom-input')
end
end
class PasswordInput < SimpleForm::Inputs::PasswordInput
def input_html_classes
super.push('password-custom-input')
end
end
class NumericInput < SimpleForm::Inputs::PasswordInput
def input_html_classes
super.push('numeric-custom-input')
end
end
end