How do you handle Rail's flash with Ajax requests?
You can also store the flash messages in the response headers using a after_filter block and display them using javascript:
class ApplicationController < ActionController::Baseafter_filter :flash_to_headersdef 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 pageend
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.
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 endend
application.js
// FLASH NOTICE ANIMATIONvar 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}"
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)) %>');