CSC/ECE 517 Spring 2015/ch1b 22 SF: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
 
(19 intermediate revisions by 2 users not shown)
Line 1: Line 1:
<font size="6"><b>Simple Form</b></font><br>
<font size="6"><b>Simple Form</b></font><br>


[[File:Omniauth.jpg|frame|Source: https://raw.githubusercontent.com/plataformatec/simple_form/master/simple_form.png/|right]]
'''Simple Form <ref>https://github.com/plataformatec/simple_form</ref>'''is a Rails gem used for easily creating Rails forms.
'''Simple Form''' is a Ruby authentication framework aimed to integrated with various types of authentication providers. It can be hooked up to any system, from social network to enterprise systems to simple username and password authentication <ref>https://github.com/intridea/omniauth/wiki</ref>. OmniAuth is designed to be a black box to which you can send users' requests in order to get authentication information back from the providers. For example, you can use OmniAuth Facebook strategies and send user's email and password to Facebook service, and then get information back to authenticate that user in your application. OmniAuth has the advantages of super simplicity and security. <br>


The topic writeup for this page can be found [https://docs.google.com/document/d/1Ay5OOUkcLMC-FH61fAm3cNvB3Uyk2hJ09vHnRgqwL-k/edit?pli=1 here].
The topic write up for this page can be found [https://docs.google.com/a/ncsu.edu/document/d/1Ay5OOUkcLMC-FH61fAm3cNvB3Uyk2hJ09vHnRgqwL-k/edit here].


== Background ==
== Introduction ==
=== Why Simple Form ===
With web application booming.....
Simple form has following advantages:
* Simple
* Powerful
* Flexible
* Secure
In order to use Omniauth for authentication, developers can create and leverage one or more [https://github.com/intridea/omniauth/wiki/List-of-Strategies strategies] released individually as RubyGems from different providers for OmniAuth. Each strategy is a Rack Middleware.


=== Rack Middleware ===
=== Background ===
Rack provides a standard interface for developing web applications supporting Ruby and Ruby framework. And Rack middleware is a way to filter a request and response coming into your application<ref>http://railscasts.com/episodes/151-rack-middleware</ref>. Rack has quite simple architecture:
 
* An object that responds to the <code>call</code> method
Many web applications would contain forms and these forms are made of some basic elements, like text input, button, checkbox, etc. To generate forms with different layouts but similar elements, designers/developers would sometimes write duplicate codes. Simple Form provides a flexible way for designers/developers to define the markup that works better for each application by providing some powerful components to create your own forms. Simple Form let you to define your form better with similar or no extra markup, so that you could transfer to desigy using Simple Form almost seamlessly. Most of the DSL <ref>https://http://en.wikipedia.org/wiki/Domain-specific_language</ref> was inherited from '''Formtastic<ref>https://github.com/justinfrench/formtastic</ref>'''.
* Taking the environment hash as a parameter
 
* Returning an Array with three elements: status code, environment hash and response body
== Getting Started ==
We can install Rack with following command:
=== Installation ===
<pre>$ gem install rack</pre>
 
Then we're going to create a Rack configuration file with extension .ru in your Rails application's root directory. That tells <code>Rack::Builder</code> what middleware does it use and in which order. Or to say how to combine various internal and external middlewares to form a complete Rails Rack application<ref>http://guides.rubyonrails.org/rails_on_rack.html</ref>. <code>Rack::Builder</code> is Rails equivalent of <code>ActionDispatch::MiddlewareStack</code>
You can use the following code to install simple_form:
<pre>
 
#Rails.root/config.ru
<code class="language-ruby"><pre>gem install simple_form</pre></code>
require 'rack'
 
</pre>
But I recommend you to use the following way: <br /> Add the following code to your Gemfile:
To use <code>rackup</code> to start up your created app, you can put the following code inside config.ru<ref>http://guides.rubyonrails.org/rails_on_rack.html</ref>. And then run <code>rackup</code> command:
 
<div class="md-section-divider"></div>
 
<code class="language-ruby"><pre>gem 'simple_form'</pre></code>
And in your Rails application root directory, run the following command:
 
<div class="md-section-divider"></div>


<pre>require ::File.expand_path('../config/environment', __FILE__)
<code class="language-ruby"><pre>bundle install</pre></code>
   
   
use Rails::Rack::Debugger
Run the following code to generate the simple_form into your app:
use Rack::ContentLength
 
run Rails.application
<code class="language-ruby"><pre>rails generate simple_form install</pre></code>
</pre>
<pre>$ rackup config.ru</pre>
Creating a Middleware filter is just creating a Ruby class. Here is an simplest example:
<pre># ResponseTimer.rb
class ResponseTimer
  def initialize(app)
    @app = app     
  end               


  def call(env)     
=== Work with Bootstrap ===
    @app.call(env) 
  end               
end                 
</pre>
By binding HTTP requests and responses together in the simplest way, it unifies the API for web servers, web frameworks, and software into a single method <code>call</code>.


Rails also provides some simple configuration interface <code>config.middleware</code> for adding, modifying and removing middlewares in the middleware stack via application.rb or the environment configuration file <code>environments/<environment>.rb. </code>You can check out these methods by view Configuring Middleware Stack part of <ref>http://guides.rubyonrails.org/rails_on_rack.html</ref>.
Similar to '''H5BP<ref>http://html5boilerplate.com</ref>''' and  '''Grid System 960<ref>http://960.gs</ref>''', Bootstrap is a simple and very popular front-end framework.


===Supported Ruby Versions===
With the following code while installing Simple Form, you can integrate Simple Form to Bootstrap
OmniAuth is tested under 1.8.7, 1.9.3, 2.0.0, 2.1.0, JRuby, and Rubinius.
<code class="language-ruby"><pre>rails generate simple_form:install --bootstrap</pre></code>
You have to be sure that you added a copy of the Bootstrap assets on your application.


== Getting Start ==
For more information see the generator output, out example application code and the live example app.
Because each OmniAuth strategy is a Rack Middleware, this means it can be used the same way as other Rack middleware. Here we introduce some simple steps in order to illustrate how to use Twitter strategy for OmniAuth<ref>https://github.com/intridea/omniauth</ref>.  
=== Installing ===
First start by adding this gem into your Gemfile:
<pre>gem 'omniauth-twitter'</pre>
If you need to use the latest HEAD version, you can do it with:
<pre>gem 'omniauth-twitter', :github => 'arunagw/omniauth-twitter'</pre>


=== Usage ===
==Usage and Examples==
Because OmniAuth is built for multi-provider authentication, you need to build multiple strategies. For this, the Rack middleware  <code>OmniAuth::Builder</code> class gives an easy way to build up your list of OmniAuth strategies for use in your application.  
===A Simple Form and Bootstrap Sample===
A simple form and bootstrap sample application <ref>A simple form example http://simple-form-bootstrap.plataformatec.com.br/documentation</ref> gives some insight into how to build a decent form with the help of simple form and bootstrap.
The code to create a form is listed below.


Below is an example that you can put into a Rails initializer at <code> config/initializers/omniauth.rb </code> or add it to your middleware:
<pre>
<pre>
Rails.application.config.middleware.use OmniAuth::Builder do
<%= simple_form_for @user_basic, url: create_basic_examples_url, as: 'user_basic'  do |f| %>
   provider :developer unless Rails.env.production?
 
  provider :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET']
   <%= f.input :email, placeholder: 'Enter email' %>
end
</pre>
You can create your twitter application [https://apps.twitter.com/ here], after that, you can obtain <code>TWITTER_KEY</code> and <code>TWITTER_SECRET</code> as shown below:
[[File: twitter.png|center]]


=== Integrating OmniAuth into Rails Application ===
  <%= f.input :password, placeholder: 'Password' %>
To use OmniAuth, you need to redirect users to <code>/auth/:provider</code> , where <code>:provider</code> is the name of the strategy (for example, <code>facebook</code> or <code>twitter</code> ). From there, OmniAuth will take over and take the user through the necessary steps to authenticate them with the chosen strategy.


Once the user has authenticated, OmniAuth simply set a special hash called Authentication Hash on Rack environment of a request to <code>/auth/:provider/callback</code>. This hash includes information about the user that OmniAuth collects from the utilized strategy. You should set up an endpoint in your application that matches to the callback URL and then performs whatever steps are necessary for your application.
  <%= f.input :file, as: :file, wrapper: :vertical_file_input %>


For example, in a Rails app you can add a line in <code>routes.rb</code> file like this:
  <%= f.input :active, wrapper: :vertical_boolean %>
<pre>get '/auth/:provider/callback', to: 'sessions#create'</pre>
Then you can add code in <code>SessionsController</code> with something like this:
<pre>class SessionsController < ApplicationController
  def create
    @user = User.find_or_create_from_auth_hash(auth_hash)
    self.current_user = @user
    redirect_to '/'
  end


   protected
   <%= f.input :choices, as: :check_boxes,
    collection: [
      'Option one is this and that—be sure to include why it\'s great',
      'Option two can be something else and selecting it will deselect option one'],
      wrapper: :vertical_radio_and_checkboxes %>


   def auth_hash
   <%= f.input :sex, as: :radio_buttons,
     request.env['omniauth.auth']
     collection: ['Male', 'Female'], wrapper: :vertical_radio_and_checkboxes %>
  end
end</pre>
The <code>omniauth.auth</code> key in the environment hash gives you the Authentication Hash which will contain information about the just authenticated user. The information includes a unique id, the strategy used for authentication, and personal details such as name and email address.


Note that OmniAuth does not perform any actions beyond setting some environment information on the callback request. It depends on how you want to implement the particulars of your application's authentication flow.
  <%= f.button :submit %>
<% end %>
</pre>


=== Logging ===
In the code
OmniAuth supports a configurable logger. By default, OmniAuth will log to <code>STDOUT</code> but you can configure this using <code> OmniAuth.config.logger</code>:
<pre>
<pre># Rails application example
<%= f.input :email, placeholder: 'Enter email' %>
OmniAuth.config.logger = Rails.logger</pre>
</pre>
a placeholder is created by passing it to the input method.


== Other Examples ==
In the code
=== OmniAuth Facebook ===
<pre>
==== Installing ====
<%= f.input :file, as: :file, wrapper: :vertical_file_input %>
To use Facebook OmniAuth Strateges<ref>https://github.com/mkdynamic/omniauth-facebook</ref>, first, add this gem into your Gemfile, and then run <code>bundle install</code>:
</pre>
<pre>gem 'omniauth-facebook'</pre>
a wrapper is used to define the file format.
==== Usage====
Adding the middleware to a Rails app in <code>config/initializers/omniauth.rb</code>:
<pre>Rails.application.config.middleware.use OmniAuth::Builder do
  provider :facebook, ENV['FACEBOOK_KEY'], ENV['FACEBOOK_SECRET']
end</pre>
==== Configuring ====
You can configure several options, which you pass in to the <code>provider</code> method via a <code>Hash</code>:
{| class="wikitable"  style="font-size: 100%; text-align: left; width: auto;"


|-
We could also find that
! Option name
<pre>
! Default
wrapper: :vertical_radio_and_checkboxes
! Explanation
</pre>
goes twice in the code. To get rid of the duplicate wrappers, the <code>wrapper_mapping</code> method could be used to define customized wrapper definition, as is shown below.


|-
<pre>
| <code>scope</code>
<%= simple_form_for @user_basic, url: create_basic_examples_url, as: 'user_basic',
| <code>email</code>          
  wrapper_mappings: {
| A comma-separated list of permissions you want to request from the user. See the [https://developers.facebook.com/docs/reference/login/ Facebook docs] for a full list of available permissions
    check_boxes: :vertical_radio_and_checkboxes,
    radio_buttons: :vertical_radio_and_checkboxes,
    file: :vertical_file_input,
    boolean: :vertical_boolean
  } do |f| %>


|-
  <%= f.input :email, placeholder: 'Enter email' %>
| <code>display</code>
| <code>page</code>
| The display context to show the authentication page. Options are: <code>page</code>, <code>popup</code> and <code>touch</code>. Read the [https://developers.facebook.com/docs/reference/dialogs/oauth/ Facebook docs] for more details


|-
  <%= f.input :password, placeholder: 'Password' %>
| <code>image_size</code>
| <code>square</code>
| Set the size for the returned image url in the auth hash. Valid options include <code>square</code> (50x50), <code>small</code> (50 pixels wide, variable height), <code>normal</code> (100 pixels wide, variable height), or <code>large</code> (about 200 pixels wide, variable height). Additionally, you can request a picture of a specific size by setting this option to a hash with <code>:width</code> and <code>:height</code> as keys. This will return an available profile picture closest to the requested size and requested aspect ratio. If only <code>:width</code> or <code>:height</code> is specified, we will return a picture whose width or height is closest to the requested size, respectively.


|-
  <%= f.input :file, as: :file %>
| <code>info_fields</code>
|
| Specify exactly which fields should be returned when getting the user's info. Value should be a comma-separated string as per <ref>https://developers.facebook.com/docs/graph-api/reference/user/</ref>


|-
  <%= f.input :active %>
| <code>locale</code>
|
| Specify locale which should be used when getting the user's info. Value should be locale string as per <ref>https://developers.facebook.com/docs/reference/api/locale/</ref>


|-
  <%= f.input :choices, as: :check_boxes,
| <code>auth_type</code>
    collection: [
|
      'Option one is this and that—be sure to include why it\'s great',
| Optionally specifies the requested authentication features as a comma-separated list <ref>https://developers.facebook.com/docs/facebook-login/reauthentication/</ref>. Valid values are <code>https</code> (checks for the presence of the secure cookie and asks for re-authentication if it is not present), and <code>reauthenticate</code> (asks the user to re-authenticate unconditionally). Default is <code>nil</code>.
      'Option two can be something else and selecting it will deselect option one'] %>


|-
  <%= f.input :sex, as: :radio_buttons,
| <code>secure_image_url</code>
    collection: ['Male', 'Female'] %>
| <code>false</code>
| Set to <code>true</code> to use https for the avatar image url returned in the auth hash


|-
  <%= f.button :submit %>
| <code>callback_url /
<% end %>
callback_path</code>
</pre>
|
| Specify a custom callback URL used during the server-side flow. Note this must be allowed by your app configuration on Facebook
|}
For example, to request <code>email</code>, <code>user_birthday</code> and <code>read_stream</code> permissions:
<pre>Rails.application.config.middleware.use OmniAuth::Builder do
  provider :facebook, ENV['FACEBOOK_KEY'], ENV['FACEBOOK_SECRET'],
          :scope => 'email,user_birthday,read_stream'
end</pre>


=== OmniAuth GitHub ===
Then the code would become more DRY<ref>http://en.wikibooks.org/wiki/Ruby_on_Rails/Getting_Started/Don%C2%B4t_repeat_yourself</ref>.
==== Install ====
Finally the form generated by this Simple Form code and bootstrap looks like
To use GitHub OmniAuth Strateges<ref>https://github.com/intridea/omniauth-github</ref>, first, add this gem into your Gemfile, and then run <code>bundle install</code>:
<div class="center" style="width: auto; margin-left: auto; margin-right: auto;"> [[File:basic_form_example.png]]</div>
<pre>gem 'omniauth-github'</pre>
==== Usage ====
Adding the middleware to a Rails app in <code>config/initializers/omniauth.rb</code>:
<pre>Rails.application.config.middleware.use OmniAuth::Builder do
  provider :github, ENV['GITHUB_KEY'], ENV['GITHUB_SECRET']
end</pre>
==== Scopes ====
GitHub API v3 lets you set scopes to provide granular access to different types of data:
<pre>use OmniAuth::Builder do
  provider :github, ENV['GITHUB_KEY'], ENV['GITHUB_SECRET'], scope: "user,repo,gist"
end</pre>
More scope info is shown below:
{| class="wikitable" style="font-size: 100%; text-align: left; width: auto;"


|-
<div class="center" style="width: auto; margin-left: auto; margin-right: auto;">Figure 1 The resulting form generated by Simple Form.<ref>http://simple-form-bootstrap.plataformatec.com.br/documentation</ref></div>
! Name
! Description


|-
===A Comparison between Simple Form and Bootstrap===
| <code>(no scope)</code>     
Using Simple Form to generate forms costs less time and codes than Bootstrap, and here is a comparison<ref>Simple Form and Bootstrap http://simple-form-bootstrap.plataformatec.com.br/?optionsRadios=option1&optionsRadios=option1</ref>. The Simple Form code and Bootstrap codes generate almost the same forms, as are shown below.
| Grants read-only access to public information (includes public user profile info, public repository info, and gists)


|-
<div class="center" style="width: auto; margin-left: auto; margin-right: auto;"> [[File:SFexample2.png]]</div>
| <code>user</code>
| Grants read/write access to profile info only. Note that this scope includes <code>user:email</code> and <code>user:follow</code>


|-
<div class="center" style="width: auto; margin-left: auto; margin-right: auto;">Figure 2 Forms generated by Simple Form and Bootstrap.<ref>http://simple-form-bootstrap.plataformatec.com.br/documentation</ref></div>
| <code>user:email</code>
| Grants read access to a user’s email addresses


|-
The code to generate the form with Simple Form is
| <code>user:follow</code>
| Grants access to follow or unfollow other users


|-
<pre>
| <code>public_repo</code>
<%= simple_form_for @user_basic, url: create_basic_examples_url, as: 'user_basic' do |f| %>
| Grants read/write access to code, commit statuses, and deployment statuses for public repositories and organizations
  <%= f.error_notification %>


|-
  <%= f.input :email, placeholder: 'Enter email' %>
| <code>repo</code>
| Grants read/write access to code, commit statuses, and deployment statuses for public and private repositories and organizations


|-
  <%= f.input :password, placeholder: 'Password' %>
| <code>repo_deployment</code>
| Grants access to deployment statuses for public and private repositories. This scope is only necessary to grant other users or services access to deployment statuses, without granting access to the code


|-
  <%= f.input :file, as: :file %>
| <code>repo:status</code>
| Grants read/write access to public and private repository commit statuses. This scope is only necessary to grant other users or services access to private repository commit statuses without granting access to the code


|-
  <%= f.input :active %>
| <code>delete_repo</code>
| Grants access to delete adminable repositories


|-
  <%= f.input :choices, as: :check_boxes,
| <code>notifications</code>
    collection: ["Option one is this and that—be sure to include why it's great", "Option two can be something else and selecting it will deselect option one"] %>
| Grants read access to a user’s notifications. repo also provides this access


|-
  <%= f.input :sex, as: :radio_buttons,
| <code>gist</code>
    collection: ["Male", "Female"] %>
| Grants write access to gists


|-
  <%= f.button :submit %>
| <code>read:repo_hook</code>
<% end %>
| Grants read and ping access to hooks in public or private repositories
</pre>


|-
And the code to generate the form with Bootstrap is
| <code>write:repo_hook</code>
| Grants read, write, and ping access to hooks in public or private repositories


|-
<pre>
| <code>admin:repo_hook</code>
<form role="form">
| Grants read, write, ping, and delete access to hooks in public or private repositories
  <div class="form-group">
    <label class="control-label" for="exampleInputEmail1">Email</label>
    <input type="email" class="form-control" id="exampleInputEmail1" placeholder="Enter email">
    <p class="help-block">Lorem ipsum dolor sit amet</p>
  </div>


|-
  <div class="form-group">
| <code>admin:org_hook</code>
    <label class="control-label" for="exampleInputPassword1">Password</label>
| Grants read, write, ping, and delete access to organization hooks. Note: OAuth tokens will only be able to perform these actions on organization hooks which were created by the OAuth application. Personal access tokens will only be able to perform these actions on organization hooks created by a user
    <input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password">
    <p class="help-block">Lorem ipsum dolor sit amet</p>
  </div>


|-
  <div class="form-group">
| <code>read:org</code>
    <label class="control-label" for="exampleInputFile">File</label>
| Read-only access to organization, teams, and membership
    <input type="file" id="exampleInputFile">
    <p class="help-block">Example block-level help text here.</p>
  </div>


|-
  <div class="form-group">
| <code>write:org</code>
    <div class="checkbox">
| Publicize and unpublicize organization membership
      <label>
        <input type="checkbox"> Active
      </label>
    </div>
    <p class="help-block">Lorem ipsum dolor sit amet</p>
  </div>


|-
  <div class="form-group">
| <code>admin:org</code>
    <label class="control-label">Choices</label>
| Fully manage organization, teams, and memberships
    <div class="checkbox">
      <label>
        <input type="checkbox" name="optionsRadios" id="optionsCheckbox1" value="option1" checked>
        Option one is this and that&mdash;be sure to include why it's great
      </label>
    </div>
    <div class="checkbox">
      <label>
        <input type="checkbox" name="optionsRadios" id="optionsCheckbox2" value="option2">
        Option two can be something else and selecting it will deselect option one
      </label>
    </div>
  </div>


|-
  <div class="form-group">
| <code>read:public_key</code>
    <label class="control-label">Sex</label>
| List and view details for public keys
    <div class="radio">
      <label>
        <input type="radio" name="optionsRadios" id="optionsRadios1" value="option1" checked>
        Male
      </label>
    </div>
    <div class="radio">
      <label>
        <input type="radio" name="optionsRadios" id="optionsRadios2" value="option2">
        Female
      </label>
    </div>
    <p class="help-block">Lorem ipsum dolor sit amet</p>
  </div>


|-
  <button type="submit" class="btn btn-default">Create User</button>
| <code>write:public_key</code>
</form>
| Create, list, and view details for public keys
 
</pre>


|-
As can be seen from above codes, it is easier to to implement the form with Simple Form than the Bootstrap.
| <code>admin:public_key</code>
| Fully manage public keys
|}


=== More Examples ===
==Conclusion==
* [https://github.com/arunagw/omniauth-foursquare OmniAuth Foursquare ]
Simple Form provides a simple and flexible way for developers to generate forms. These forms could then work seamlessly with other CMV components to deliver, process and display data.  
* [https://github.com/geoloqi/omniauth-geoloqi OmniAuth Geoloqi]
Compared with Bootstrap, Simple Forms provides an easier way to generate the same form. It costs less codes and time, and the codes are more concise and readable.
* [https://github.com/intridea/omniauth-identity OmniAuth Identity]
* [https://github.com/skorks/omniauth-linkedin OmniAuth Linkedin]
* [https://github.com/arunagw/omniauth-picplz OmniAuth Picplz]
* [https://github.com/intridea/omniauth-openid OmniAuth Openid]


== References ==
== References ==
<references/>
<references/>

Latest revision as of 01:27, 24 February 2015

Simple Form

Simple Form <ref>https://github.com/plataformatec/simple_form</ref>is a Rails gem used for easily creating Rails forms.

The topic write up for this page can be found here.

Introduction

Background

Many web applications would contain forms and these forms are made of some basic elements, like text input, button, checkbox, etc. To generate forms with different layouts but similar elements, designers/developers would sometimes write duplicate codes. Simple Form provides a flexible way for designers/developers to define the markup that works better for each application by providing some powerful components to create your own forms. Simple Form let you to define your form better with similar or no extra markup, so that you could transfer to desigy using Simple Form almost seamlessly. Most of the DSL <ref>https://http://en.wikipedia.org/wiki/Domain-specific_language</ref> was inherited from Formtastic<ref>https://github.com/justinfrench/formtastic</ref>.

Getting Started

Installation

You can use the following code to install simple_form:

gem install simple_form

But I recommend you to use the following way:
Add the following code to your Gemfile:

gem 'simple_form'

And in your Rails application root directory, run the following command:

bundle install

Run the following code to generate the simple_form into your app:

rails generate simple_form install

Work with Bootstrap

Similar to H5BP<ref>http://html5boilerplate.com</ref> and Grid System 960<ref>http://960.gs</ref>, Bootstrap is a simple and very popular front-end framework.

With the following code while installing Simple Form, you can integrate Simple Form to Bootstrap

rails generate simple_form:install --bootstrap

You have to be sure that you added a copy of the Bootstrap assets on your application.

For more information see the generator output, out example application code and the live example app.

Usage and Examples

A Simple Form and Bootstrap Sample

A simple form and bootstrap sample application <ref>A simple form example http://simple-form-bootstrap.plataformatec.com.br/documentation</ref> gives some insight into how to build a decent form with the help of simple form and bootstrap. The code to create a form is listed below.

<%= simple_form_for @user_basic, url: create_basic_examples_url, as: 'user_basic'  do |f| %>

  <%= f.input :email, placeholder: 'Enter email' %>

  <%= f.input :password, placeholder: 'Password' %>

  <%= f.input :file, as: :file, wrapper: :vertical_file_input %>

  <%= f.input :active, wrapper: :vertical_boolean %>

  <%= f.input :choices, as: :check_boxes,
    collection: [
      'Option one is this and that—be sure to include why it\'s great',
      'Option two can be something else and selecting it will deselect option one'],
      wrapper: :vertical_radio_and_checkboxes %>

  <%= f.input :sex, as: :radio_buttons,
    collection: ['Male', 'Female'], wrapper: :vertical_radio_and_checkboxes %>

  <%= f.button :submit %>
<% end %>

In the code

<%= f.input :email, placeholder: 'Enter email' %>

a placeholder is created by passing it to the input method.

In the code

<%= f.input :file, as: :file, wrapper: :vertical_file_input %>

a wrapper is used to define the file format.

We could also find that

wrapper: :vertical_radio_and_checkboxes

goes twice in the code. To get rid of the duplicate wrappers, the wrapper_mapping method could be used to define customized wrapper definition, as is shown below.

<%= simple_form_for @user_basic, url: create_basic_examples_url, as: 'user_basic',
  wrapper_mappings: {
    check_boxes: :vertical_radio_and_checkboxes,
    radio_buttons: :vertical_radio_and_checkboxes,
    file: :vertical_file_input,
    boolean: :vertical_boolean
  } do |f| %>

  <%= f.input :email, placeholder: 'Enter email' %>

  <%= f.input :password, placeholder: 'Password' %>

  <%= f.input :file, as: :file %>

  <%= f.input :active %>

  <%= f.input :choices, as: :check_boxes,
    collection: [
      'Option one is this and that—be sure to include why it\'s great',
      'Option two can be something else and selecting it will deselect option one'] %>

  <%= f.input :sex, as: :radio_buttons,
    collection: ['Male', 'Female'] %>

  <%= f.button :submit %>
<% end %>

Then the code would become more DRY<ref>http://en.wikibooks.org/wiki/Ruby_on_Rails/Getting_Started/Don%C2%B4t_repeat_yourself</ref>. Finally the form generated by this Simple Form code and bootstrap looks like

Figure 1 The resulting form generated by Simple Form.<ref>http://simple-form-bootstrap.plataformatec.com.br/documentation</ref>

A Comparison between Simple Form and Bootstrap

Using Simple Form to generate forms costs less time and codes than Bootstrap, and here is a comparison<ref>Simple Form and Bootstrap http://simple-form-bootstrap.plataformatec.com.br/?optionsRadios=option1&optionsRadios=option1</ref>. The Simple Form code and Bootstrap codes generate almost the same forms, as are shown below.

Figure 2 Forms generated by Simple Form and Bootstrap.<ref>http://simple-form-bootstrap.plataformatec.com.br/documentation</ref>

The code to generate the form with Simple Form is

<%= simple_form_for @user_basic, url: create_basic_examples_url, as: 'user_basic' do |f| %>
  <%= f.error_notification %>

  <%= f.input :email, placeholder: 'Enter email' %>

  <%= f.input :password, placeholder: 'Password' %>

  <%= f.input :file, as: :file %>

  <%= f.input :active %>

  <%= f.input :choices, as: :check_boxes,
    collection: ["Option one is this and that—be sure to include why it's great", "Option two can be something else and selecting it will deselect option one"] %>

  <%= f.input :sex, as: :radio_buttons,
    collection: ["Male", "Female"] %>

  <%= f.button :submit %>
<% end %>

And the code to generate the form with Bootstrap is

<form role="form">
  <div class="form-group">
    <label class="control-label" for="exampleInputEmail1">Email</label>
    <input type="email" class="form-control" id="exampleInputEmail1" placeholder="Enter email">
    <p class="help-block">Lorem ipsum dolor sit amet</p>
  </div>

  <div class="form-group">
    <label class="control-label" for="exampleInputPassword1">Password</label>
    <input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password">
    <p class="help-block">Lorem ipsum dolor sit amet</p>
  </div>

  <div class="form-group">
    <label class="control-label" for="exampleInputFile">File</label>
    <input type="file" id="exampleInputFile">
    <p class="help-block">Example block-level help text here.</p>
  </div>

  <div class="form-group">
    <div class="checkbox">
      <label>
        <input type="checkbox"> Active
      </label>
    </div>
    <p class="help-block">Lorem ipsum dolor sit amet</p>
  </div>

  <div class="form-group">
    <label class="control-label">Choices</label>
    <div class="checkbox">
      <label>
        <input type="checkbox" name="optionsRadios" id="optionsCheckbox1" value="option1" checked>
        Option one is this and that—be sure to include why it's great
      </label>
    </div>
    <div class="checkbox">
      <label>
        <input type="checkbox" name="optionsRadios" id="optionsCheckbox2" value="option2">
        Option two can be something else and selecting it will deselect option one
      </label>
    </div>
  </div>

  <div class="form-group">
    <label class="control-label">Sex</label>
    <div class="radio">
      <label>
        <input type="radio" name="optionsRadios" id="optionsRadios1" value="option1" checked>
        Male
      </label>
    </div>
    <div class="radio">
      <label>
        <input type="radio" name="optionsRadios" id="optionsRadios2" value="option2">
        Female
      </label>
    </div>
    <p class="help-block">Lorem ipsum dolor sit amet</p>
  </div>

  <button type="submit" class="btn btn-default">Create User</button>
</form>

As can be seen from above codes, it is easier to to implement the form with Simple Form than the Bootstrap.

Conclusion

Simple Form provides a simple and flexible way for developers to generate forms. These forms could then work seamlessly with other CMV components to deliver, process and display data. Compared with Bootstrap, Simple Forms provides an easier way to generate the same form. It costs less codes and time, and the codes are more concise and readable.

References

<references/>