Mel
Mel

Reputation: 2685

Simple Form Error Notification

I am trying to figure out how to use Simple Form with Rails, Devise, Omniauth and Bootstrap. I have several problems, but one of them is error notifications.

I have a devise sign in and sign up form inside Bootstrap modals. The registration form is as follows. Note that I removed the required: true function from the form because I don't like the asterisk being appended to the label (but I did try putting it back to see if the error notifications would work).

<% if user_signed_in? %>
  <li>
    <%= link_to('Edit registration', edit_user_registration_path) %>
  </li>
<% else %>
  <li>
    <%= link_to 'Register', new_user_registration_path, :remote => true, 'data-toggle' => "modal", 'data-target' => "#myRModal", :method => 'get' %>
  </li>

  <div class="modal fade" id="myRModal" tabindex="-1" role="dialog" aria-labelledby="myRModalLabel" aria-hidden="true">
    <div class="modal-dialog">
      <div class="modal-content">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
          <h4 class="modal-title" id="myModalLabel" style="color:black">Register</h4>
        </div>

        <div class="modal-body">
          <%- if devise_mapping.omniauthable? %>
            <div class="facebookauth"> <%= link_to "Register with Facebook", user_omniauth_authorize_path(:facebook) %></div>
            <br />
          <% end -%>
          <%- if devise_mapping.omniauthable? %>
            <div class="linkedinauth"> <%= link_to "Register with LinkedIn", user_omniauth_authorize_path(:linkedin) %></div>
            <br />
          <% end -%>
        </div>

        <div class="modal-footer">



  <%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
     <%= f.error_notification %>

     <div class="form-inputs" style="padding-left:20%; text-align:left; color:black;">

       <%= f.input :first_name, placeholder: 'Enter your first name', autofocus: true, :input_html => {:maxlength => 15, :size => 40} %>
       <%= f.input :last_name, placeholder: 'Enter your surname', autofocus: true, :input_html => {:maxlength => 15, :size => 40} %>
       <%= f.input :email, placeholder: 'Enter email',  autofocus: true, :input_html => {:maxlength => 25, :size => 40} %>
       <%= f.input :password, placeholder: 'At least 8 characters', :input_html => {:maxlength => 15, :size => 40} %>
       <%= f.input :password_confirmation, placeholder: 'Confirm your password',  :input_html => {:maxlength => 15, :size => 40} %>
     </div>

     <div class="form-actions" style="padding-left:20%; padding-top:5%; text-align:left; color:black;">
       <%= f.button :submit, "Register" %><% end %>

I have a user modal which has validations for the presence of an email address and password.

I have a user/registration_controller with the following create function:

def create
  @user = User.new(user_params)#(params[:user])

  respond_to do |format|
    if @user.save
      # Tell the UserMailer to send a welcome email after save
      # AdminMailer.new_user_waiting_for_approval.deliver

      format.html { redirect_to(root_path, notice: 'Registration received.') }
      format.json { render json: root_path, status: :created, location: @user }
    else
      format.html { redirect_to(root_path, alert: 'Sorry! There was a problem with your registration. Please contact us to sort it out.') }
       # format.html { render action: 'new' }
       format.json { render json: @user.errors, status: :unprocessable_entity }
    end
  end
end

I have devise helpers in both my application helper and devise helper as follows:

def resource_name
  :user
end

def resource
  @resource ||= User.new
end

def devise_mapping
  @devise_mapping ||= Devise.mappings[:user]
end

My initializers file has two simple form files. One is simple_form.rb. The other is simple_form_bootstrap.rb

No errors display inline in the form. When I complete the form without an email address, I get the error that appears in the create function of my registration_controller.

I'd really like the error to appear inline, in the form, when the user clicks submit.

Does anyone know how to address this problem?

Thank you.

Upvotes: 3

Views: 7722

Answers (4)

waqar mirza
waqar mirza

Reputation: 555

Make sure you have similar line in ur initializer's wrapper

b.use :error, wrap_with: { tag: 'span', class: 'help-block' }

as you mentioned in ur question, please remove required: false, and to remove the '*' for required, change it in config/locale/simple_form.en.yml

required:
  text: 'required'
  mark: ''

Upvotes: 2

Mel
Mel

Reputation: 2685

The problem with error validation is resolved if:

  1. remove: f.error_nofication from the simple_form call; and
  2. insert: <%= devise_error_messages! %> inside the form-inputs field.

If you have validations on your user model and also use devise validatable, the error list at the top of the form will duplicate the errors. Remove one or the other of the validations and you will have the errors working.

I cannot figure out why simple form does not render the errors - but this is a solution.

I have decided to remove simple form from my application - I can't read the documentation and so many questions posted on Stack Overflow relating to using it with devise do not get answered. I cannot see its benefits.

As for the modal - I am going to try using this. http://bootstrapvalidator.com (fingers crossed). I hope this answer helps someone. I have been trying to set up devise for 3 months - with 3 weeks solid daily effort in trying to understand the docs.

Upvotes: 2

nathanvda
nathanvda

Reputation: 50057

You say you are using modals? But you do not post ajax (no remote: true on your form). So I will describe what I think happens now. You do not post ajax, so you post html, so it chooses the format.html path, and on error your controller redirects to root-path, with an error message. Instead it should re-render the form.

So uncommenting the commented line in your create action should work :) (and deleting the current format.html line obviously).

Ofcourse the re-render will not be a modal. When using modals, and you want the form to remain open, you will have to use ajax and replace the form with a re-rendered version in case of error.

Simple-form, when given an object with validation-errors, will automatically show the errors inline.

Upvotes: 1

Richard Peck
Richard Peck

Reputation: 76774

Does anyone know how to address this problem?

Because you're able to use an object in the registration form, it means you have some liberty over how you display the errors. It would be a different story if you were trying to achieve the same with login (as login does not use a form)

--

Form

We've done this before (you can see here - click "Register" at top):

#app/views/devise/registrations/new.html.erb
<%= f.email_field :email, :placeholder => "email" %>
<div class="error"><%= devise_resource.errors[:email].first if devise_resource.errors[:email].present? %></div>

Considering the form uses devise_resource in the form_for object - this should allow you to display the errors inline

Upvotes: 2

Related Questions