diff --git a/README.md b/README.md index 107cf9fc..6cd8ae83 100644 --- a/README.md +++ b/README.md @@ -262,7 +262,7 @@ the wrapper as well: <% end %> ``` -By default, **Simple Form** generates a hidden field to handle the un-checked case for boolean fields. +By default, **Simple Form** generates a hidden field to handle the un-checked case for boolean fields. Passing `unchecked_value: false` in the options for boolean fields will cause this hidden field to be omitted, following the convention in Rails. You can also specify `include_hidden: false` to skip the hidden field: @@ -1187,6 +1187,43 @@ by passing the html5 option: <%= f.input :expires_at, as: :date, html5: true %> ``` +## Wrapper Mappings + +The simplest default wrapper for all inputs is defined in the simple_form initializer. + +``` +config.default_wrapper = :default +``` + +As custom wrappers are added to your configuration it may become appropriate to map an input to a specific wrapper, a good example of this would be the config that is generated with the bootstrap install. This would override *:default* with *:bs5_boolean_collection* for those inputs only. + +``` +config.wrapper_mappings = { + # ..8<.. + check_boxes: :bs5_boolean_collection, + radio_buttons: :bs5_boolean_collection, + # ..8<.. +} +``` + +This may be further exhanced to have multiple sets of wrapper mappings so that you can use a set of mappings for a single form or set of fields, instead of setting the wrapper for each input. + +``` +config.wrapper_mappings[:tables] = { + select: :bs5_select2, + string: :bs5_input_float, +} +``` + +The form builder accepts a *:wrapper_mappings* option to cope with this situation. + +``` +simple_form_for(object, wrapper_mappings: :table) do |f| + f.input :name +end +``` + + ### Using non Active Record objects There are few ways to build forms with objects that don't inherit from Active Record, as diff --git a/lib/simple_form.rb b/lib/simple_form.rb index e813398a..0012bf86 100644 --- a/lib/simple_form.rb +++ b/lib/simple_form.rb @@ -139,11 +139,21 @@ def self.configured? #:nodoc: # Custom wrappers for input types. This should be a hash containing an input # type as key and the wrapper that will be used for all inputs with specified type. - # e.g { string: :string_wrapper, boolean: :boolean_wrapper } + # e.g config.wrapper_mappings = { string: :string_wrapper, boolean: :boolean_wrapper } # You can also set a wrapper mapping per form basis. # e.g simple_form_for(@foo, wrapper_mappings: { check_boxes: :bootstrap_checkbox }) - mattr_accessor :wrapper_mappings - @@wrapper_mappings = nil + # If you wish to create another set of wrappers you can do so + # config.wrapper_mappings[:inline] = { string: :inline_string } + # Which will allow referencing a set of wrappers with the set key + # e.g simple_form_for(@foo, wrapper_mappings: :custom) + + def self.wrapper_mappings + @@wrapper_mappings ||= {} + end + + def self.wrapper_mappings=(opts) + wrapper_mappings[:default] = opts + end # Namespaces where SimpleForm should look for custom input classes that override # default inputs. Namespaces are given as string to allow lazy loading inputs. diff --git a/lib/simple_form/form_builder.rb b/lib/simple_form/form_builder.rb index da723cb7..d3b5f5d2 100644 --- a/lib/simple_form/form_builder.rb +++ b/lib/simple_form/form_builder.rb @@ -636,11 +636,10 @@ def find_mapping(input_type) # 1) It tries to find a wrapper for the current form # 2) If not, it tries to find a config def find_wrapper_mapping(input_type) - if options[:wrapper_mappings] && options[:wrapper_mappings][input_type] - options[:wrapper_mappings][input_type] - else - SimpleForm.wrapper_mappings && SimpleForm.wrapper_mappings[input_type] - end + mapping = options[:wrapper_mappings] + mapping.is_a?(Hash) && mapping[input_type] || + SimpleForm.wrapper_mappings.fetch(mapping, {}).try(:[], input_type) || + SimpleForm.wrapper_mappings.fetch(:default, {}).try(:[], input_type) end def find_wrapper(input_type, options) diff --git a/test/form_builder/wrapper_test.rb b/test/form_builder/wrapper_test.rb index 9c7786ee..85a4fd23 100644 --- a/test/form_builder/wrapper_test.rb +++ b/test/form_builder/wrapper_test.rb @@ -245,6 +245,23 @@ class WrapperTest < ActionView::TestCase end end + test 'uses custom wrapper mapping for specified in config mapping' do + swap_wrapper :another do + swap SimpleForm, wrapper_mappings: { string: :not_found } do + begin + SimpleForm.wrapper_mappings[:custom] = { string: :another } + with_concat_form_for @user, wrapper_mappings: :custom do |f| + concat f.input :name + end + assert_select "section.custom_wrapper div.another_wrapper label" + assert_select "section.custom_wrapper div.another_wrapper input.string" + ensure + SimpleForm.wrapper_mappings.delete(:custom) + end + end + end + end + test 'uses custom wrapper mapping per form basis' do swap_wrapper :another do with_concat_form_for @user, wrapper_mappings: { string: :another } do |f|