Wednesday, April 13, 2011

How do you handle Rail's flash with Ajax requests?

I'm pretty happy with the solution that I came up with. Basically, I have a helper method that reloads the flash inline, and then I have an after_filter that clear out the flash if the request is xhr. Does anyone have a simpler solution than that?

From stackoverflow
  • The only improvement I can think of is making the page.reload_flash default (not having to put it on every rjs file, and make it expicit if you don't want to reload the flash, something like page.keep_flash.

    I wouldn't know where to start but knowing some rails I'm sure it's not that hard.

  • Looks like what you need is flash.now[:notice], which is only available in the current action and not in the next. You can take a look at the documentation here: http://api.rubyonrails.com/classes/ActionController/Flash/FlashHash.html#M000327

  • This is needed in the js response

    If you are using RSJ:

    page.replace_html :notice, flash[:notice]
    flash.discard
    

    If you are using jQuery:

    $("#flash_notice").html(<%=escape_javascript(flash.delete(:notice)) %>');
    
  • Another way would be update/display the "notice" div with the message from the your Ajax requests "OnFailure" handler. It gives you the ability to show these flash messages with required effect. I used this

     render :text => "Some error happened", :status => 444
    

    in the Javascript

     new AjaxRequest(...
    
      ,
       OnFailure:function(transport) {
          $("#notice").update(transport.responseText);
         // show the message  
       }
    
    );
    
    

    HTH

  • You can also store the flash messages in the response headers using a after_filter block and display them using javascript:

    class ApplicationController < ActionController::Base
    after_filter :flash_to_headers
    
    def flash_to_headers
      return unless request.xhr?
      response.headers['X-Message'] = flash[:error]  unless flash[:error].blank?
      # repeat for other flash types...
    
      flash.discard  # don't want the flash to appear when you reload page
    end
    

    And in application.js add a global ajax handler. For jquery do something like this:

    $(document).ajaxError(function(event, request) {
      var msg = request.getResponseHeader('X-Message');
      if (msg) alert(msg);
    });
    

    Replace alert() with your own javascript flash function or try jGrowl.

0 comments:

Post a Comment

Note: Only a member of this blog may post a comment.