Form_for + bootstrap (how to make them work together for formatting?)

I’m on a crunch (first) project in rails. My deadline is Friday, and I’ve lost all modesty about posting dumb questions etc. Please help if you can…

I’m using form_for to create a form associated with my model. That works. I’m using bootstrap for the overall site design. That works. The problem: I am having a hell of time formatting the form (e.g. getting checkboxes, text fields, and radio buttons to be inline, all at once). Also if the page is refreshed, any inline formatting I happened to accomplish goes away, and bootstrap default layouts are taking over. Relevant line of code here is:

<%= form_for @student, url: {action: "create"}, html: {class: "form-inline"} do |f| %>

And for the form items I’m using things like…

  <%= f.label :phone_number, "Phone Number" %>
  <%= text_field(:student, :phone_number) %></br></br>

  <%= f.radio_button(:device_type, value: 1) %>
  <%= label :device_type, 'I like this button and want to select it', :value => 1 %></br>

  <%= f.check_box(:active, value: 1, checked: false) %>
  <%= f.label(:active, "I have reviewed and agree to the Terms of Use") %>

I know that’s not perfect code above, but I’ve tried a million combinations.

So anyone have advice? What’s the best way to accomplish: bootstrap + form associated with my model + control over the layout like inline elements, including that they stay inline after a page refresh, which happens if the user data doesn’t pass validation.

I see gems like simple_form, formtastic for bootstrap and so on but I really was looking for a non-gem solution just to simplify things, plus I don’t know which of those would be best for my situation. If you can’t tell, I’m not a designer but am playing one on this project.

Thanks!

You’re probably seeing the layout change when there are validation errors because Rails wraps fields and labels with validation errors in a <div>. Both <input> and <label> are inline elements (that is, in CSS they have display: inline by default), but <div> is a block element (display: block by default).

Take this field for example:

<%= f.label :phone_number, "Phone Number" %>
<%= text_field(:student, :phone_number) %>

Normally, the output will look something like this:

<label for="my_model_phone_number">Phone Number</label>
<input id="my_model_phone_number" name="my_model[phone_number]">

When that field has validation errors however, the output looks like this:

<div class="field_with_errors"><label for="my_model_phone_number">Phone Number</label></div>
<div class="field_with_errors"><input id="my_model_phone_number" name="my_model[phone_number]"></div>

You can mitigate the effects by telling this <div> to display like an inline element with a little bit of CSS:

div.field_with_errors {
  display: inline;
}

While this should solve this specific problem, you may hit others in the future. I’d suggest that using one of the Bootstrap form gems will prove simpler in the long run, and will probably let you use more of Bootstrap’s built in styles (for form field error states, etc.)

Hope that helps.

George, thank you. I tried the CSS fix you gave, and it did work to resolve the form reload issue. But I took your other point too, and ultimately decided to switch to Simple_Form (careful to install with the --bootstrap option) to gain a little control over the form layout in general. It took quite a while to make the switch and get everything working and formatted – but it works! It’s much cleaner. Thanks again.

1 Like

Next time, I would look at using simple_form with the correct Bootstrap 3/4 initializer. It styles it right up for you.

1 Like

I ran into the same issue using bootstrap and simple form was my answer as well. It saved me tons of time. When in doubt look to see if there is a gem that has already solved that functionality.