So, I'm trying to respond to an action with a js file.
def my_schedule
respond_to do |format|
format.js
end
end
In my view, I have 'my_schedule.js.erb' but it's not even executed, rails broke in the controller and throw me an error : ActionController::UnknownFormat, where I have the respond_to.
I tried to add
respond_to :js, :json, :html
at the beginning of my controller out of the actions but still not working.
Need help to debug this and understand how respond_to really works.
format.js will only respond to an xhr request. You can't trigger this response by just navigating to the route that points to this controller and method.
You can test the js.erb execution by changing the respond_to block to
def my_schedule
respond_to do |format|
format.html
format.js
end
end
Then create a my_schedule.html.erb file in the same view folder as the js.erb with the following contents
<%= link_to 'Test', my_schedule_path, data: { remote: true } %>
Note that you may need to adjust that path, I'm just guessing on that.
Then navigate to the same path you were trying to before. You should see a link which, when clicked, will fire the js response.
Related
I have controller Message_Controller and this Controller has method "message" in this method i wanna render .js.erb file i need call js function from rails controller.I need reneder it without html-template(layout) just only js-code in this code i will call js-function with args .How to make it ??
My routes:
post 'chat_bot/message', to: 'chat_bot#message'
My controller:
class ChatBotController < ApplicationController
layout false
def message
#gon.watch.message = params[:text]
#message = params[:text]
puts #message
render partial: 'message.js.erb', layout: false
end
end
my message.js.erb file
alert('<%=#message %>');
With
render partial: 'message.js.erb', layout: false
Rails is going to look for a partial called _message.js.erb right in the folder responding to that controller.
You can use respond_to and there specify the format and what to render:
def message
respond_to do |format|
format.html { render partial: 'message.js.erb' }
end
end
You can skip the instance variable assignation if you prefer, as you have access to the params within the request.
If your idea is to "evaluate" the alert, then it still should be inside a script tag:
<script>
alert("<%= params[:text] %>");
</script>
just update it with
def message
#message = params[:text]
respond_to do |format|
format.js
end
end
I'm making a simple AJAX call from a from_tag (search box) and want to show the results without refreshing page. The issue is that even though I can see in server console that the show action is being processed as JS, it still renders the HTML and not the js.haml file. The only way I'm getting controller to render js is by changing name to show.js . It then works as it should. show.js.erb doesn't work either. I've also tried format.js {render layout: false} without any luck. It seem to be an problem on the controller side but I might be wrong here. Any ideas appreciated!
Edit:
The controller action is working using the render "show.js.haml" option. The other issue is that escape_javascript doesn't do anything in below js.haml file.
show.js.haml
$("#main").html("#{escape_javascript(render 'artists/show', locals: {artist: #artist, updates, #updates, reach: #reach, reach_diff: #reach_diff})}");
controller
class ArtistsController < ApplicationController
def index
if params[:search]
#artist=Artist.find_by(name: params[:search])
redirect_to action: "show", id: #artist.id
else
#artists= Artist.all
end
end
def show
#artist= Artist.find(params[:id])
#updates = #artist.updates.order(created_at: :desc)
#reach = #artist.reachupdates.order(created_at: :desc)
#reach_diff= Reachupdate.last_week_diff(#artist.id)
respond_to do |format|
format.html
format.js {render "show.js.haml", layout: false}
end
end
end
You need to change render layout: false to render 'show.js.haml', layout: false
def show
#artist= Artist.find(params[:id])
#updates = #artist.updates.order(created_at: :desc)
#reach = #artist.reachupdates.order(created_at: :desc)
#reach_diff= Reachupdate.last_week_diff(#artist.id)
respond_to do |format|
format.html
format.js {render 'show.js.haml', layout: false}
end
end
Update:
The next issue I'm having is to insert ruby objects to the js file
If the file 'articles/show' is a partial file then the problem is the locals keyword should be used along with partial keyword in order to work. Try changing this
$("#main").html("#{escape_javascript(render 'artists/show', locals: {artist: #artist, updates, #updates, reach: #reach, reach_diff: #reach_diff})}");
to
$("#main").html("#{escape_javascript(render partial: 'artists/show', locals: {artist: #artist, updates, #updates, reach: #reach, reach_diff: #reach_diff})}");
Or
Just remove locals
$("#main").html("#{escape_javascript(render 'artists/show', artist: #artist, updates, #updates, reach: #reach, reach_diff: #reach_diff)}");
I'm trying to sign up Users using Devise, and render a JS file if a certain parameter is included in the sign-up. I'm getting the following error:
ActionController::UnknownFormat in RegistrationsController#create
ActionController::UnknownFormat
This is my "create" action (I marked the line the error pointed to):
if resource.persisted?
if resource.active_for_authentication?
set_flash_message :notice, :signed_up if is_flashing_format?
sign_up(resource_name, resource)
if !params[:name].nil?
View.create(name: params[:name])
respond_to do |format| #THIS IS THE LINE WITH THE ERROR
format.js
end
else
respond_with resource, location: after_sign_up_path_for(resource)
end
else
respond_with resource, location: inactive_path_for(resource)
end
else
respond_with resource
end
The action is "create", in app/controllers/registrations_controller.rb. The JS file I'm trying to render is app/views/devise/registrations/create.js.erb.
My suspicion is that there's a problem with finding the file, but I can't figure out how to point it to the right route, or if that's even the right problem. Anyone have any thoughts?
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 %>
×
</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
So this is my controller function.
def fb_close
current_user.update_user_points(SHARE_POINT_ONE, message, current_user.id, 0) if params[:post_id].present?
respond_to do |format|
format.js { render :js => "my_function();" }
end
end
and im trying to go back a js function called my_function inside script tag on the same page. I'm getting an error like ActionController::UnknownFormat
I want to know where i was wrong. Please correct me.
I have a file named fb_close.html.erb i can get the call to that file.. Is there any way i can link it with a js function
You should be better putting the code of my_function in a separate file of format js and call it like format.js { render 'your_file_name' }
respond_to do |format|
format.js { render 'your_file_name' }
end
You have to create a file like fb_close.js.erb and put the code of my_function in it and call it like this
respond_to do |format|
format.js { render 'fb_close' }
end