Produce complex Bootstrapped forms with inline errors with minimal typing
View Project on GitHub.comView Gem on RubyGems.orgA simplistic "new post" form:
Never manually render a <label> again!
<% # Uses the TBFB helper to include the form-horizontal class %>
<%= form_for @post do |f| %>
<% # Generates a control group with both "text_field" and "email" classes %>
<%= f.text_field :email %>
<% # Show both the left and right labels %>
<%= f.check_box :hide_email, :text => "Don't show my email address in my posts" %>
<% # Show a helpful message %>
<%= f.text_area :body, :help_block => "Simple HTML tags are allowed", :rows => 3 %>
<% # Show only the right ":text" label %>
<%= f.check_box :terms_of_service, :label => nil, :text => "I have read and agreed to the terms of service" %>
<div class="form-actions">
<%= f.submit "Create", :primary => true %>
<a href="/" class="btn">Cancel</a>
</div>
<% end %>
The labels and control group markup are generated automatically by a single call
<form accept-charset="UTF-8" action="/posts" class="form-horizontal " id="new_post" method="post">
<!-- Rails plumbing omitted -->
<div class=" text_field control-group name">
<label class="control-label" for="post_name">Name</label>
<div class="controls">
<input id="post_name" name="post[name]" size="30" type="text" />
</div>
</div>
<div class=" text_field control-group email">
<label class="control-label" for="post_email">Email</label>
<div class="controls">
<input id="post_email" name="post[email]" size="30" type="text" />
</div>
</div>
<div class="control-group hide_email">
<label class="control-label" for="post_hide_email">Hide email</label>
<div class="controls">
<label class="checkbox" for="post_hide_email">
<input name="post[hide_email]" type="hidden" value="0" />
<input id="post_hide_email" name="post[hide_email]" type="checkbox" value="1" />
Don't show my email address in my posts</label>
</div>
</div>
<div class=" text_field control-group topic">
<label class="control-label" for="post_topic">Topic</label>
<div class="controls">
<input id="post_topic" name="post[topic]" size="30" type="text" />
</div>
</div>
<div class=" text_area control-group body">
<label class="control-label" for="post_body">Body</label>
<div class="controls">
<textarea cols="40" id="post_body" name="post[body]" rows="3">
</textarea>
<p class="help-block">Simple HTML tags are allowed</p>
</div>
</div>
<div class="control-group terms_of_service">
<div class="controls">
<label class="checkbox" for="post_terms_of_service">
<input name="post[terms_of_service]" type="hidden" value="0" />
<input id="post_terms_of_service" name="post[terms_of_service]" type="checkbox" value="1" />I have read and agreed to the terms of service</label>
</div>
</div>
<div class="form-actions">
<input class=" btn btn-primary" name="commit" type="submit" value="Create" />
<a href="/" class="btn">Cancel</a>
</div>
</form>
By default TBFB renders inline error messages and adds error classes to your markup
The labels and control group markup are generated automatically by a single call.
Note that no attempt has been made to strip out Rails' field_with_error divs that wrap the individual form elements.
<form accept-charset="UTF-8" action="/posts" class="form-horizontal " id="new_post" method="post">
<!-- Rails plumbing omitted -->
<div class=" text_field control-group name error">
<div class="field_with_errors">
<label class="control-label" for="post_name">Name</label>
</div>
<div class="controls">
<div class="field_with_errors">
<input id="post_name" name="post[name]" size="30" type="text" value="" />
</div>
<span class="help-inline">Name can't be blank</span>
</div>
</div>
<div class=" text_field control-group email error">
<div class="field_with_errors">
<label class="control-label" for="post_email">Email</label>
</div>
<div class="controls">
<div class="field_with_errors">
<input id="post_email" name="post[email]" size="30" type="text" value="" />
</div>
<span class="help-inline">Email can't be blank</span>
</div>
</div>
<div class="control-group hide_email">
<label class="control-label" for="post_hide_email">Hide email</label>
<div class="controls">
<label class="checkbox" for="post_hide_email">
<input name="post[hide_email]" type="hidden" value="0" />
<input id="post_hide_email" name="post[hide_email]" type="checkbox" value="1" /> Don't show my email address in my posts</label>
</div>
</div>
<div class=" text_field control-group topic error">
<div class="field_with_errors">
<label class="control-label" for="post_topic">Topic</label>
</div>
<div class="controls">
<div class="field_with_errors">
<input id="post_topic" name="post[topic]" size="30" type="text" value="" />
</div>
<span class="help-inline">Topic can't be blank</span>
</div>
</div>
<div class=" text_area control-group body error">
<div class="field_with_errors">
<label class="control-label" for="post_body">Body</label>
</div>
<div class="controls">
<div class="field_with_errors">
<textarea cols="40" id="post_body" name="post[body]" rows="3">
</textarea>
</div>
<p class="help-block">Simple HTML tags are allowed</p>
<span class="help-inline">Body can't be blank</span>
</div>
</div>
<div class="control-group terms_of_service error">
<div class="controls">
<label class="checkbox" for="post_terms_of_service">
<input name="post[terms_of_service]" type="hidden" value="0" />
<div class="field_with_errors">
<input id="post_terms_of_service" name="post[terms_of_service]" type="checkbox" value="1" />
</div> I have read and agreed to the terms of service</label>
<span class="help-inline">Terms of service must be accepted</span>
</div>
</div>
<div class="form-actions">
<input class=" btn btn-primary" name="commit" type="submit" value="Create" />
<a href="/" class="btn">Cancel</a>
</div>
</form>
Add the Gem to your Gemfile:
gem twitter-bootstrap-form-builder
or install it manually:
gem install twitter-bootstrap-form-builder
The Gem includes a helper which overrides form_for, automatically setting the :builder option and adding Twitter Bootstrap's clases to your <form> tag.
Include MNE::TwitterBootstrapFormBuilder::Helper in your ApplicationHelper module:
# app/helpers/application_helper.rb
module ApplicationHelper
include MNE::TwitterBootstrapFormBuilder::Helper
# Your helpers here...
end
Assuming you've added the helper, use form_for to begin rendering your form, excluding label tags.
<%= form_for @post do |f| %> <%= f.text_field :topic %> <% end %>
A couple of nice things have been done for us based on this one line:
text_field) and attribute name (topic)<label> tags<form accept-charset="UTF-8" action="/posts" class="form-horizontal " id="new_post" method="post">
<!-- Rails plumbing omitted -->
<div class="text_field control-group topic">
<label class="control-label" for="post_topic">Topic</label>
<div class="controls">
<input id="post_topic" name="post[topic]" size="30" type="text" />
</div>
</div>
</form>
Use a string for a custom label:
<%= f.text_field :topic, :label => "Subject" %>
<div class="text_field control-group topic">
<label class="control-label" for="post_topic">Subject</label>
<div class="controls">
<input id="post_topic" name="post[topic]" size="30" type="text" />
</div>
</div>
Use an array to fully override the arguments to label_tag:
<%= f.text_field :topic, :label => ["My Label", { :class => "extra-bold control-label" }] %>
<div class="text_field control-group topic">
<label class="extra-bold control-label" for="post_topic">My Label</label>
<div class="controls">
<input id="post_topic" name="post[topic]" size="30" type="text" />
</div>
</div>
If you have some crazy field that requires a ton of markup, use :label => false:
<%= f.text_field :topic, :label => false %>
Exactly like calling regular FormBuilder#text_field:
<input id="post_topic" name="post[topic]" size="30" type="text" />
See the README for documentation, examples and known issues.