Slick23
Slick23

Reputation: 5897

Controller and jquery problem on redirect

I have a coming_soon_controller that displays a form for users to subscribe to an email list. It passes an email address to this:

  def create
    @subscriber = Subscriber.new(params[:subscriber])
    @email = params[:subscriber][:email]
    @ip = request.ip

      respond_to do |format|
        if @subscriber.save
          ComingSoonMailer.thanks_email(@email).deliver
          format.js 
          format.html {redirect_to comingsoon_path(:success => 'hooray'), :notice => "Got it. Thanks! (and remember, you can unsubscribe at any time)"}
        else
          format.html {redirect_to comingsoon_path, :alert => "Shucks. There was a problem. Mind trying again?"}
        end
      end
  end

When the button is click, I have some jquery that takes away the button and shows a loading gif:

<script>
 $(function() {
    $( ".subscriberSubmit" ).click(function () {
        $(this).fadeOut();
        $('.loadingImage').fadeIn();
    });
});
</script>

And a create.js.erb file that's called by the controller if the subscriber object is saved:

$('.loadingImage').fadeOut();
$('#new_subscriber').fadeOut(function () {
    $(this).after("<div id=\"email_sign_up_success\"><p class=\"emphasis\">Success! A confirmation should arrive shortly.</p></div>");
});

The trouble I'm having is when the save fails -- such as it doesn't pass the validation in the model. Here's what happens:

Started POST "/subscribers" for 127.0.0.1 at 2011-07-16 13:36:07 -0400
13:36:07 web.1     |   Processing by SubscribersController#create as JS
13:36:07 web.1     |   Parameters: {"utf8"=>"✓", "authenticity_token"=>"S99c2kgEnc9w6x61oJNL5399snImRJoVgAxXZTf8umsDg=", "subscriber"=>{"email"=>""}, "commit"=>""}
13:36:07 web.1     | Redirected to http://localhost:5000/comingsoon
13:36:07 web.1     | Completed 302 Found in 7ms

It says it redirects properly, but the flash is never displayed and the loading gif is still there ... basically, though rails has done a redirect, the app appears to hang. I thought the redirect in the controller, since it's only HTML, would actually reload the page and reset everything -- but apparently I'm wrong. Anyway I can fix this, so it redirects and shows the flash properly?

clarification

In this situation -- I want it to redirect to /comingsoon and NOT render the JS. It seems to be redirecting, according to the log -- but the browser isn't reloading the page, so the form isn't being reset.

Upvotes: 0

Views: 463

Answers (1)

vinceh
vinceh

Reputation: 3510

Now that I understand your question, I can answer it more easily.

It's not refreshing because of the type of request you have. When you set :remote => true it will send a js request to the server. Once the server is done handling your request, it sends information back, and part of this information is the mimeType. Then in your controller, you will handle the information that comes back from the server. Which is the code that you have.

 respond_to do |format|
    if @subscriber.save
      ComingSoonMailer.thanks_email(@email).deliver
      format.js 
      format.html {redirect_to comingsoon_path(:success => 'hooray'), :notice => "Got it. Thanks! (and remember, you can unsubscribe at any time)"}
    else
      format.html {redirect_to comingsoon_path, :alert => "Shucks. There was a problem. Mind trying again?"}
    end
  end

In this case, your format will always be a js because you're always expecting a js type back from the server, which means you need to render it correctly, or else your controller will do some default stuff (which in this case is an async redirect back to your comingsoon).

This means that in your else clause you need to also have a format.js. A good plan would just be to render 2 different partials depending on whether your record saved properly or not. In your else clause you can render a js that removes your form and renders a new one, and displays the appropriate message telling users that it has failed. Yon can also try to have

else
    format.js {redirect_to comingsoon_path, :alert => "Shucks. There was a problem. Mind trying again?"}
end

Although I'm not sure how your controller would handle that.

Check this out for a nice article on UJS in Rails3.

Good luck.

Upvotes: 1

Related Questions