Thursday, June 14, 2012

Rails, simple_form, Twitter Bootstrap, and append

I wanted to put a little delete button at the end of a form field.  We start with the standard simple_form syntax for a form field.


  <%= f.input :name %>

The generated HTML has the form elements inside a set of nested divs which have the classes necessary for Bootstrap styling.

The result looks like:






If we want our delete button to appear on the same line as the form field we need to get it inside those divs.  The Wrapping Rails Form Helpers section of the simple_form documentation explains that you can pass a block to the input method, and some of the developers mentioned in ticket comments on Github that this can be used to add content near the form field.  There seems to be some discussion about improving the syntax so that you don't have to list the name of the model attribute twice, but for now that is necessary.


  <%= f.input :name do %>
    <%= f.input_field :name %>
    <%= button_tag content_tag(:i, nil, class: 'icon-remove'), type: 'button', class: 'btn btn-danger' %>
  <% end %>

The result looks like:





Looking good.  But a review of the Bootstrap documentation for forms turns up their "Append with button" example.  For that effect we need an extra div with the "input-append" class.  It isn't documented, but poking around in the simple_form code you'll find the :append wrapper which looks to do what we need.  Note that the lack of space between the input_field and the button_tag is important, otherwise you get a bit of whitespace in the resulting page.


  <%= f.input :name, :wrapper => :append do %>
    <%= f.input_field :name %><%= button_tag content_tag(:i, nil, class: 'icon-remove'), type: 'button', class: 'btn btn-danger' %>
  <% end %>

The result looks like: