Davor
Davor

Reputation: 1237

Custom wrapper for Bootstrap 3 dropdown in Rails simple form

I'm using Simple Form and trying to figure out how I can style a select field the same way I've styled the rest. I can't seem to find anything online. What I want is to avoid any need to specify the wrapper name in each form, but link it to the default style - whether it's an association, a simple dropwdown, as long as it's a select it should take that style.

Here's my current initializer file (simple_form_bootstrap.rb):

SimpleForm.setup do |config|
  config.wrappers :bootstrap_form_horizontal, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
    b.use :html5
    b.use :placeholder
    b.use :label
    b.wrapper tag: :div, class: 'col-xs-9' do |ba|
      ba.use :input
      ba.use :hint,  wrap_with: { tag: 'p', class: 'help-block' }
      ba.use :error, wrap_with: { tag: 'p', class: 'help-block' }
    end
  end

  config.form_class = 'form-horizontal'
  config.label_class = 'control-label col-xs-3'
  config.button_class = 'btn btn-primary btn-lg'
  config.error_notification_tag = :div
  config.error_notification_class = 'alert alert-danger'
  config.wrapper_mappings = { :boolean => :checkbox }

  config.wrappers :checkbox, tag: :div, class: "col-xs-offset-3 col-xs-9", error_class: "has-error" do |b|
    b.use :html5
    b.wrapper tag: :div, class: "checkbox" do |ba|
      ba.use :input
    end
    b.use :hint,  wrap_with: { tag: :p, class: "help-block" }
    b.use :error, wrap_with: { tag: :span, class: "help-block" }
  end

  config.wrappers :select, tag: :div, class: "col-xs-6", error_class: "has-error" do |b|
    b.use :html5
    b.wrapper tag: :div, class: "form-control" do |ba|
      ba.use :select
    end
    b.use :hint,  wrap_with: { tag: :p, class: "help-block" }
    b.use :error, wrap_with: { tag: :span, class: "help-block" }
  end

  # Wrappers for forms and inputs using the Twitter Bootstrap toolkit.
  # Check the Bootstrap docs (http://twitter.github.com/bootstrap)
  # to learn about the different styles for forms and inputs,
  # buttons and other elements.
  config.default_wrapper = :bootstrap_form_horizontal
end

Basically the part starting with config.wrappers :select is the place where I'm trying everything to get it picked up.

Any idea? Thanks!

Upvotes: 1

Views: 1046

Answers (1)

Nick Roz
Nick Roz

Reputation: 4230

This is not really well designed approach. Wrappers serve only for elements arrangement, namely for specifying their position.

For defining own styled element with custom HTML code use class Input instead. For example:

class CheckboxInput < SimpleForm::Inputs::BooleanInput
  def input
    # do whatever you want, for instance push your own class
    html_options = label_html_options.dup
    html_options[:class] ||= []
    html_options[:class].push('ui-checkbox')
    @builder.label(label_target, html_options) {
      build_check_box_without_hidden_field + template.tag(:span).html_safe
    }
  end
end

Put this class under app/inputs directory. In your case it'll be something like MySelectInput.

This is an explanation of Adding custom input components. Try out available simple form inputs on github - https://github.com/plataformatec/simple_form/blob/master/lib/simple_form/inputs.

I am not sure, but this https://github.com/plataformatec/simple_form/blob/master/lib/simple_form/inputs/collection_select_input.rb is probably what you are looking for.

In such way of nesting your input classes you are able to redefine whatever you want.

To use this custom input write:

= simple_form_for @user, html: { class: 'form-horizontal' } do |f|
  = f.input :locked, as: :checkbox_input, wrapper: :inline
  # if you have this `inline` wrapper, of course

If your class name is MySelectClass, input name will be underscored - :my_select_class.

Remember that wrapper is not an input itself. It is common for all the inputs.

Hope it helps!

Upvotes: 1

Related Questions