Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

Update: The solution above was written back in Rails 1.x and is no longer supported.

like image 963
Jerry Cheung Avatar asked Dec 14 '08 08:12

Jerry Cheung


People also ask

How rails send data using Ajax?

Use rails-ujs (no jQuery) Making an AJAX POST call with rails-ujs looks identical to making it with jQuery: Rails. ajax({ type: "POST", url: "/things", data: mydata, success: function(repsonse){...}, error: function(repsonse){...} })

How do I add AJAX in Rails?

In Rails, submitting an AJAX request can be done as easily as adding remote: true to a link, button, or form. From there you can have any response be some JavaScript code waiting on the server side, and it will execute in the client's browser. Here's the simplest code example of UJS via AJAX in a link.

How do flash messages work rails?

They are stored in the sessions cookie on the user's browser in order to persist for the next request. For the request following that one the flash hash clears itself out. They are not stored in the session cookie. They are merely associated with the session cookie.


2 Answers

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.

like image 197
gudleik Avatar answered Sep 21 '22 15:09

gudleik


And here is my version based on @emzero, with modifications to work with jQuery, tested on Rails 3.2

application_controller.rb

class ApplicationController < ActionController::Base     protect_from_forgery      after_filter :flash_to_headers      def flash_to_headers         return unless request.xhr?         response.headers['X-Message'] = flash_message         response.headers["X-Message-Type"] = flash_type.to_s          flash.discard # don't want the flash to appear when you reload page     end      private      def flash_message         [:error, :warning, :notice].each do |type|             return flash[type] unless flash[type].blank?         end     end      def flash_type         [:error, :warning, :notice].each do |type|             return type unless flash[type].blank?         end     end end 

application.js

// FLASH NOTICE ANIMATION var fade_flash = function() {     $("#flash_notice").delay(5000).fadeOut("slow");     $("#flash_alert").delay(5000).fadeOut("slow");     $("#flash_error").delay(5000).fadeOut("slow"); }; fade_flash();  var show_ajax_message = function(msg, type) {     $("#flash-message").html('<div id="flash_'+type+'">'+msg+'</div>');     fade_flash(); };  $(document).ajaxComplete(function(event, request) {     var msg = request.getResponseHeader('X-Message');     var type = request.getResponseHeader('X-Message-Type');     show_ajax_message(msg, type); //use whatever popup, notification or whatever plugin you want }); 

layout: application.html.haml

        #flash-message             - flash.each do |name, msg|                 = content_tag :div, msg, :id => "flash_#{name}" 
like image 26
Victor S Avatar answered Sep 21 '22 15:09

Victor S