Long story short, I have a button. On clicking it, I want an ajax request to be triggered which gets flash[:notice] and displays it in a div in$
Here is my shortened view:
<input type="button" id="search" value="display"/> <div id="notice"> </div>
My ajax request in the view:
$("#search").submit(function(){ $.ajax({ type: "POST", url: //url to my show action success: function(data){ /*$("#notice").html("<%= flash[:notice] %>"); $("#content").html(data);*/ } }); return false; });
My controller:
def HomeController < ActionController::Base def index end def show respond_to do |format| format.js { flash[:notice] = "" + count.to_s + " results found for " + params[:query][:search_key] + "" } end #render :partial => 'search' end end
My show.js.erb
#app/views/dashboard_home/show.js.erb $("#notice").html("<%=j flash[:notice] %>"); $("#content").html("<%=j render partial: "search" %>");
The problem is when I click on button, the notice is displayed fine. But the same notice persists on the next clicks too. The search partial contains the table Please help!
Here is an example that I got working, thanks to Rich Peck's answer. I needed to use flash.now
to make sure the flash notice didn't persist.
AJAX trigger in the view:
<%= link_to "Email report", users_path, remote: true %>
Controller:
# app/controllers/users_controller class UsersController < ApplicationController def index # do some things here respond_to do |format| format.js { flash.now[:notice] = "Here is my flash notice" } end end end
Rendered view:
# app/views/users/index.js.erb $("#flash").html('<%= j render partial: "shared/notice_banner" %>');
where the flash notice is displayed in the layout:
# app/views/layouts/application.html.erb <div id="flash"> <% if notice.present? %> <%= render partial: "shared/notice_banner" %> <% end %> </div> # app/views/shared/_notice_banner.html.erb <div data-alert class="alert-box"> <%= notice %> <a href="#" class="close">×</a> </div>
Sessions
the same notice persists on the next clicks too
This is caused by the flash
being stored in the session
variable of Rails:
The flash is a special part of the session which is cleared with each request. This means that values stored there will only be available in the next request, which is useful for passing error messages etc.
The problem you have is that since I don't think ajax counts as a new request (need reference for this), the data will persist into the next time you request via HTTP.
--
Fix
I would initially try this:
def show respond_to do |format| format.js { flash[:notice] = "my secret number "+rand(0,5)+" !" } end end
The main problem you have is you're processing the flash
variable in your JS using the ERB
preprocessor. This is an issue as it means you won't be able to use asset precompile to help it work.
After looking at this question, why not try using the after_filter
callback, like this:
#app/controllers/home_controller.rb Class Home < ActionController::Base after_filter { flash.discard if request.xhr? }, only: :show def show respond_to do |format| format.js { flash[:notice] = "my secret number "+rand(0,5)+" !" } end end end
--
Update
You should include the success
functionality in your show.js.erb
:
#app/views/home/show.js.erb $("#notice").html("<%= flash[:notice] %>");
This means you can remove the whole ajax
call from the application.js
, and replace with the remote: true
for your search form:
#app/views/search/index.html.erb <%= form_tag home_show_path, remote: true %>
The reason this works is because when you use the format.js
respond block, Rails will load the [action].js.erb
file in your views. Considering this only happens after the action has been completed, it's equivalent to the success
function of your ajax.
By doing this, you'll be able to remove the entire ajax
function from your application.js
, and replace with the UJS version, as described above
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With