simple_form collection wrapper (radios buttons) : double encapsulation of items

纵然是瞬间 提交于 2019-12-03 13:11:46

Summary:

I had done something similar to this before by creating a custom input that inherits from SimpleForm::Inputs::CollectionRadioButtonsInput and overloading just a few methods. For more on custom input components, see https://github.com/plataformatec/simple_form/wiki/Adding-custom-input-components.

In any case, the code below produces your desired html markup almost exactly using simple_form v2.1.0 and rails v3.2.15.

Code:

# File: app/inputs/semantic_ui_radio_buttons_input.rb

class SemanticUiRadioButtonsInput < SimpleForm::Inputs::CollectionRadioButtonsInput

  # Creates a radio button set for use with Semantic UI

  def input
    label_method, value_method = detect_collection_methods
    iopts = { 
      :checked => 1,
      :item_wrapper_tag => 'div',
      :item_wrapper_class => 'field',
      :collection_wrapper_tag => 'div',
      :collection_wrapper_class => 'grouped inline fields'
     }
    return @builder.send(
      "collection_radio_buttons",
      attribute_name,
      collection,
      value_method,
      label_method,
      iopts,
      input_html_options,
      &collection_block_for_nested_boolean_style
    )
  end # method

  protected

  def build_nested_boolean_style_item_tag(collection_builder)
    tag = String.new
    tag << '<div class="ui radio checkbox">'.html_safe
    tag << collection_builder.radio_button + collection_builder.label
    tag << '</div>'.html_safe
    return tag.html_safe
  end # method

end # class

Then, in your form, just do:

-# File: app/views/<resource>/_form.html.haml

-# Define the collection
- child_care_coll = %w( Infant Toddler Preschool Kindergarten ).map!.with_index(1).to_a

-# Render the radio inputs
= f.input :child_care_type,
  :collection    => child_care_coll,
  :label_method  => :first,
  :value_method  => :last,
  :as            => :semantic_ui_radio_buttons

Results:

<div class="input semantic_ui_radio_buttons optional childcare_child_care_type">

  <label class="semantic_ui_radio_buttons optional control-label">
    Child care type
  </label>

  <div class="grouped inline fields">

    <div class="field">
      <div class="ui radio checkbox">
        <input checked="checked" class="semantic_ui_radio_buttons optional" id="childcare_child_care_type_1" name="childcare[child_care_type]" type="radio" value="1">
        <label for="childcare_child_care_type_1">Infant</label>
      </div>
    </div>

    ...

    <div class="field">
      <div class="ui radio checkbox">
        <input class="semantic_ui_radio_buttons optional" id="childcare_child_care_type_4" name="childcare[child_care_type]" type="radio" value="4">
        <label for="childcare_child_care_type_4">Kindergarten</label>
      </div>
    </div>

  </div>

</div>

I was having trouble with the same problem until I looked through config/initializers/simple_form.rb.

Turns out you can set the option here (line ~51):

# Define the way to render check boxes / radio buttons with labels.
# Defaults to :nested for bootstrap config.
#   inline: input + label
#   nested: label > input
config.boolean_style = :inline

A bit further down you can also define the default wrapper tag and wrapper tag class for the collection (line ~81):

 # You can wrap a collection of radio/check boxes in a pre-defined tag, defaulting to none.
 config.collection_wrapper_tag = :div

 # You can define the class to use on all collection wrappers. Defaulting to none.
 config.collection_wrapper_class = 'styled-radios'

Hope this helps someone :)

*using gem 'simple_form'

With updated versions 'simple_form', '~> 3.0.2' and Semantic UI 0.19.3, I achieved it with following code.

class SemanticCheckBoxesInput < SimpleForm::Inputs::CollectionCheckBoxesInput
  def input
    label_method, value_method = detect_collection_methods
    options[:collection_wrapper_tag] = 'div'
    options[:collection_wrapper_class] = 'grouped inline fields'

    @builder.send("collection_check_boxes",
                  attribute_name, collection, value_method, label_method,
                  input_options, input_html_options, &collection_block_for_nested_boolean_style
    )
  end

  protected
  def item_wrapper_class
    "ui checkbox field"
  end
end

and in the view

= f.association :branches, as: :semantic_check_boxes

Here is the output:

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!