Styling Devise Forms with Twitter Bootstrap

By:, On:

This tutorial assumes you have already completed:

  1. Adding custom fields to Devise

Our setup is slowly getting some features. We already added some custom fields to Devise and made them work. Still, our forms look quite bad and a little primitive. Thankfully, we have added Twitter Bootstrap 3 to our project. We can leverage that to pimp our forms out.

Step 1: Modify Registration Form

Head to the Twitter Bootstrap page and have a look at the forms. We will use the form-horizontal class in order to make it look nicer:

app/views/users/registrations/new.html.erb


<h2>Sign up</h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: {class: 'form-horizontal'}) do |f| %>
<%= devise_error_messages! %>

<div class="form-group">
    <%= f.label :name, class: "col-sm-2 control-label" %>
    <div class="col-sm-6">
        <%= f.text_field :name, class: "form-control",autofocus: true %>
    </div>
</div>

<div class="form-group">
    <%= f.label :email, class: "col-sm-2 control-label" %>
    <div class="col-sm-6">
        <%= f.email_field :email, class: "form-control" %>
    </div>
</div>

<div class="form-group">
    <%= f.label :password, class: "col-sm-2 control-label" %>
    <div class="col-sm-6">
        <%= f.password_field :password, autocomplete: "off", class: "form-control" %>
    </div>
</div>

<div class="form-group">
    <%= f.label :password_confirmation, class: "col-sm-2 control-label" %>
    <div class="col-sm-6">
        <%= f.password_field :password_confirmation, autocomplete: "off", class: "form-control" %>
    </div>
</div>

<div class="form-group">
    <div class="col-sm-offset-2 col-sm-6">
        <%= f.submit "Sign up", class: "btn btn-primary" %>
    </div>
</div>

<div class="form-group">
    <div class="col-sm-offset-2 col-sm-6">
        <%= render "users/shared/links" %>
    </div>
</div>
<% end %>

Test it out, try to register and see if you page looks any nicer.

Step 2: Modify Session Form

Now, let's fix other pages:

app/views/users/registrations/edit.html.erb


<h2>Edit <%= resource_name.to_s.humanize %></h2>

<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put, class: 'form-horizontal' }) do |f| %>
<%= devise_error_messages! %>

<div class="form-group">
    <%= f.label :name, class: 'col-sm-2 control-label'  %>
    <div class="col-sm-6">
        <%= f.text_field :name, autofocus: true, class: 'form-control'  %>
    </div>
</div>

<div class="form-group">
    <%= f.label :is_female, "Gender", class: 'col-sm-2 control-label'  %>
    <div class="col-sm-6">
        <%= f.radio_button :is_female, true %> <%= f.label :is_female, "Female" %>
        <%= f.radio_button :is_female, false %> <%= f.label :is_female, "Male" %>
    </div>
</div>


<div class="form-group">
    <%= f.label :date_of_birth, class: 'col-sm-2 control-label'  %>
    <div class="col-sm-6">
        <%= f.date_select :date_of_birth, start_year: 1920, end_year: 2000, class: 'form-control'  %>
    </div>
</div>

<div class="form-group">
    <%= f.label :email, class: 'col-sm-2 control-label'  %>
    <div class="col-sm-6">
        <%= f.email_field :email, class: 'form-control'  %>
    </div>
</div>

<div class="form-group">
    <%= f.label :password, class: 'col-sm-2 control-label'  %> <i>(leave blank if you don't want to change it)</i>
    <div class="col-sm-6">
        <%= f.password_field :password, autocomplete: "off", class: 'form-control'  %>
    </div>
</div>


<div class="form-group">
    <%= f.label :password_confirmation, class: 'col-sm-2 control-label' %>
    <div class="col-sm-6">
        <%= f.password_field :password_confirmation, autocomplete: "off", class: 'form-control'  %>
    </div>
</div>

<div class="form-group">
    <%= f.label :current_password, class: 'col-sm-2 control-label' %> <i>(we need your current password to confirm your changes)</i>
    <div class="col-sm-6">
        <%= f.password_field :current_password, autocomplete: "off", class: 'form-control' %>
    </div>
</div>

<div class="form-group">
    <div class="col-sm-offset-2 col-sm-6">
        <%= f.submit "Update", class: "btn btn-primary" %>
    </div>
</div>

<div class="form-group">
    <div class="col-sm-offset-2 col-sm-6">
        <%= render "users/shared/links" %>
    </div>
</div>
<% end %>

<h5>Cancel my account</h5>

<p>Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete, class: 'btn btn-default btn-xs' %></p>

<%= link_to "Back", :back %>

app/views/users/sessions/new.html.erb


<h2>Sign in</h2>

<%= form_for(resource, as: resource_name, url: session_path(resource_name), html: {class: 'form-horizontal'}) do |f| %>
<div class="form-group">
    <%= f.label :email, class: "col-sm-2 control-label" %>
    <div class="col-sm-6">
        <%= f.email_field :email, autofocus: true , class: "form-control" %>
    </div>
</div>

<div class="form-group">
    <%= f.label :password, class: "col-sm-2 control-label" %>
    <div class="col-sm-6">
        <%= f.password_field :password, autocomplete: "off", class: "form-control" %>
    </div>
</div>

<% if devise_mapping.rememberable? -%>
<div class="form-group">
    <div class="col-sm-6 col-sm-offset-2">
        <%= f.check_box :remember_me %> <%= f.label :remember_me %>
    </div>
</div>
<% end -%>

<div class="form-group">
    <div class="col-sm-6 col-sm-offset-2">
        <%= f.submit "Sign in", class: 'btn btn-primary' %>
    </div>
</div>

<div class="form-group">
    <div class="col-sm-6 col-sm-offset-2">
        <%= render "users/shared/links" %>
    </div>
</div>

<% end %>

Step 3: Modify Password Form

app/views/users/passwords/new.html.erb


<h2>Forgot your password?</h2>

<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post, class: 'form-horizontal' }) do |f| %>
<%= devise_error_messages! %>

<div class="form-group">
    <%= f.label :email, class: "col-sm-2 control-label" %>
    <div class="col-sm-6">
        <%= f.email_field :email, autofocus: true, class: "form-control" %>
    </div>
</div>

<div class="form-group">
    <div class="col-sm-6 col-sm-offset-2">
        <%= f.submit "Send me reset password instructions", class: "btn btn-primary" %>
    </div>
</div>
<div class="form-group">
    <div class="col-sm-6 col-sm-offset-2">
        <%= render "users/shared/links" %>
    </div>
</div>
<% end %>

app/views/users/passwords/edit.html.erb


<h2>Change your password</h2>

<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put, class: 'form-horizontal' }) do |f| %>
<%= devise_error_messages! %>
<%= f.hidden_field :reset_password_token %>

<div class="form-group">
    <%= f.label :password, "New password", class: "col-sm-2 control-label" %>
    <div class="col-sm-6">
        <%= f.password_field :password, autocomplete: "off", class: "form-control" %>
    </div>
</div>

<div class="form-group">
    <%= f.label :password_confirmation, "Confirm new password", class: "col-sm-2 control-label" %>
    <div class="col-sm-6">
        <%= f.password_field :password_confirmation, autocomplete: "off", class: "form-control" %>
    </div>
</div>

<div class="form-group">
    <div class="col-sm-6 col-sm-offset-2">
        <%= f.submit "Change my password", class: "btn btn-primary" %>
    </div>
</div>

<div class="form-group">
    <div class="col-sm-6 col-sm-offset-2">
        <%= render "users/shared/links" %>
    </div>
</div>
<% end %>

There are more forms under app/views/users, some of them are not being used by us yet. Feel free to go ahead and practice by changing them as well.

If you login you will be able to mark this tutorial as finished to track your progress



Comment

You can login to comment