2
votes

I am using Simple_form and Bootstrap.

I would like to use a horizontal wrapper, but I need to make the label wider and the input narrower. I would like to do this with bootstrap 4 vs custom css.

The label and input should be on the same line (inline), and right aligned.

col-md-8 for label and col-md-4 for input. How do I do that?

 <%= f.input :role, :wrapper =>:horizontal_range, input_wrapper_html: { class: "col-md-4"}, label_wrapper_html: {class: "col-md-8"} %>

EDIT: I should add that the f.input :role is contained within a

<div class='row'>
  <div class='col-md-6"> 
      f.input :role 
  </div>
</div>

Second,

I need to add a % at the end of my input. However, it does not seem to work.

 <%= f.input :pct_of_car , append: "%",  :wrapper =>:horizontal_range %>

However, this does not seem to work. What is wrong with my syntax?

Third, how would one modify the vertical collection_inline to have 2 or 3 columns?

  # vertical input for inline radio buttons and check boxes
  config.wrappers :bs_vertical_collection_inline, item_wrapper_class: 'form-check form-check-inline', tag: 'fieldset', class: 'form-group', error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
    b.use :html5
    b.optional :readonly
    b.wrapper :legend_tag, tag: 'legend', class: 'col-form-label pt-0' do |ba|
      ba.use :label_text
    end
    b.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'
    b.use :full_error, wrap_with: { tag: 'div', class: 'invalid-feedback d-block' }
    b.use :hint, wrap_with: { tag: 'small', class: 'form-text text-muted' }
  end

Currently all the checkboxes are listed inline and have no structure. I need to list the choices in 2 or 3 columns so that they are easier to read. This is also a long list, so may need to wrap the choices in a scroll box.

2

2 Answers

3
votes

You need to define your own custom wrapper or modify the default ones.

First, ensure you have the default wrappers in your repository.

Run rails g simple_form:install --bootstrap if you can not locate app/initializers/simple_form_bootstrap.rb.

Second, locate the Bootstrap grid classes in this initializer. For a horizontal form, they are found in a block that looks like this:

config.wrappers :horizontal_form, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
    b.use :html5
    b.use :placeholder
    b.optional :maxlength
    b.optional :minlength
    b.optional :pattern
    b.optional :min_max
    b.optional :readonly
    b.use :label, class: 'col-sm-3 control-label'

    b.wrapper tag: 'div', class: 'col-sm-9' do |ba|
      ba.use :input, class: 'form-control'
      ba.use :error, wrap_with: { tag: 'span', class: 'help-block' }
      ba.use :hint,  wrap_with: { tag: 'p', class: 'help-block' }
    end
  end

Third, change the wrapper!

In this snippet, change col-sm-9 to col-sm-8. Also Change col-sm-3 to col-sm-4.

Finishing up

Save. Restart your Rails server. Now all forms will have 33% width labels, and 66% width inputs.

If you don't want to apply this globally, pass the wrapper: :my_wrapper option to any input and create a new custom wrapper that does what you'd like it to do.

Gotta love SimpleForm!

2
votes

To set class for input and label, please use input_html and label_html:

<%= f.input :role, :wrapper => :horizontal_range, input_html: { class: "col-md-4"}, label_html: {class: "col-md-8"} %>

Regarding the second issue - if you are not using hints, probably the easiest solution would be to do it like this:

<%= f.input :pct_of_car , hint: "%",  :wrapper =>:horizontal_range %>

Then, you can style it by adding a custom class to the hint with hint_html option (similar to input_html and label_html).

Update

A better solution for adding custom text is to use block for the input:

<%= f.input(:role, :wrapper => :horizontal_range, label_html: {class: "col-md-8"}) do %>
  <div class='col-md-4'>
    <%= f.input(:role, components: [:input], :wrapper => false, label: false) %>
    <span>%</span>
  </div>
<% end %>

Thanks to that, your label has col-md-8 class, and input with your text are wrapped in a div with col-md-4 class.