simple_form collection wrapper (radios buttons) :

2020-06-16 02:13发布

问题:

I'd like to reproduce this html sequence of radio buttons with simple_form in order to make simple_form work with http://semantic-ui.com/ syntax :

  <div class="grouped inline fields">
    <div class="field">
      <div class="ui radio checkbox">
        <input type="radio" name="fruit" checked="">
        <label>Apples</label>
      </div>
    </div>
    <div class="field">
      <div class="ui radio checkbox">
        <input type="radio" name="fruit">
        <label>Oranges</label>
      </div>
    </div>
    <div class="field">
      <div class="ui radio checkbox">
        <input type="radio" name="fruit">
        <label>Pears</label>
      </div>
    </div>
    <div class="field">
      <div class="ui radio checkbox">
        <input type="radio" name="fruit">
        <label>Grapefruit</label>
      </div>
    </div>
  </div>

So I prepared a custom wrapper :

config.wrappers :semantic_radios, tag: 'div', class: "grouped fields", error_class:   'error', hint_class: 'with_hint' do |b|
    b.use :html5
    b.use :label
    b.use :input
  end

Set some options :

config.item_wrapper_tag = :div
config.item_wrapper_class = 'ui radio checkbox'

And call this code in my form :

=f.input :child_care_type, collection: [["option 1", 1],["option 2", 2]], as: :radio_buttons, wrapper: :semantic_radios

I don't know where to customize the div.field encapsulation :

    <div class="field">
      <div class="ui radio checkbox">
        <input type="radio" name="fruit" checked="">
        <label>Apples</label>
      </div>
    </div>

My code only render this :

  <div class="ui radio checkbox">
    <input type="radio" name="fruit" checked="">
    <label>Apples</label>
  </div>

Can you help me ? I didn't find more wrapper's customization for collection :s

回答1:

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>



回答2:

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'



回答3:

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:



标签: simple-form