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.