Search code examples
ruby-on-railsajaxformsdevisepartial

AJAX for rendering a partial or showing form errors


I am having difficulties in solving a form processing in an AJAX way with Rails. I am going to try to explain the different parts I have, and where I do have doubts:

Here is how my new.html.erb looks like:

<%= simple_form_for(resource, :as => resource_name, :url => registration_path(resource_name), :remote => true) do |f| %>
  <%= f.input :email, :label => false, :placeholder => 'Enter Email' %>
  <%= f.submit "Step inside", :id => 'invitation_button' %>
<% end %>

<div id="request_invite">
</div>

As you can see, I have a :remote => true, so the submit is done via AJAX. Also, I have an empty container (#request_invite) which will be filled with a partial just in case the submit is successful.

Here is how my registrations_controller.rb (create method) looks like:

def create
    build_resource

    if resource.save
      if resource.active_for_authentication?
        sign_in(resource_name, resource)
        respond_with resource, :location => after_sign_up_path_for(resource)
      else
        expire_session_data_after_sign_in!
        respond_with resource, :location => after_inactive_sign_up_path_for(resource)
      end
    else
      clean_up_passwords resource
      respond_with resource
    end
  end

My doubt is here. What should I write in order to be able to let the JS know that the submission was successful or not. If it was successful, I want to render a partial called _thank_you.html.erb into the #request_invite container. If it was not successful, I want to show the errors in the form.

Here it comes my Javascript file that deals with the AJAX response:

$('document').ready(function() {
  $("#new_user").on('ajax:success', function(data, status, xhr)
  {
    alert("test");
  })
});

Right now the alert("test") always shows up as I don't have any way to know if there is a success or not.

Thanks a lot, I hope I explained myself well enough.


Solution

  • What if you made a manual ajax call, with a success and failure callback on submission of the form (instead of using remote: true). I'm tired, and not sure I'm following exactly what you're trying to do with your controller action.

      $('#form_name').submit (e) ->
        e.preventDefault()
        $.ajax
          type: "POST"
          url: "/whatever_the_path_is"
          data: { 'email': $(@).val() }
          success: (result) ->
            $('#request_invite').html(result)
          failure: ->
            $('#request_invite').html("<h1>Request Failed</h1>")
    

    And your controller might look like:

    def create
          build_resource
    
          if resource.save
            if resource.active_for_authentication?
              sign_in(resource_name, resource)
              # respond_with resource, :location => after_sign_up_path_for(resource)
              render partial: '/partials_folder/thank_you'
            else
              expire_session_data_after_sign_in!
              # respond_with resource, :location => after_inactive_sign_up_path_for(resource)
              render partial: '/partials_folder/there_was_an_error'
            end
          else
            clean_up_passwords resource
            respond_with resource
          end
        end
    

    Hopefully this gets you started on the right path.