rendering multiple files - rails - javascript

Suppose I make an ajax a call, from which I want to get some static template (app/views/static/some_template.html.erb), on which I want to act with some javascript stored here app/views/layouts/sign_in.js.erb. Is it possible to render multiple file ? (because I want to keep separate my js files and my html files)
def ajax_call
respond_to do |format|
...
format.js {render 'layouts/sign_in.js.erb'}
end
end
Edit : here's my controller
respond_to do |format|
format.js {render 'devise/sessions/new.html.erb'}
end
In devise/sessions/new.html.erb, I put
<div> test</div>
<%= render "layouts/sign_in.js.erb" %>
and in layouts/sign_in.js.erb, I put console.log('test');

You can put renders inside the partial and segment your files one more level:
def ajax_call
respond_to do |format|
...
format.js {render 'layouts/grouped_sign_in.js.erb'}
end
end
# in _grouped_sign_in.js.erb
<%= render 'layouts/sign_in.js.erb' %>
<%= render 'layouts/create_account.js.erb' %>

What you can do is the following
In your controller
#template = ActionView::Base.new('app/views/static', {}, ActionController::Base.new).render(file: 'new').to_s
respond_to do |format|
format.js {render 'layouts/sign_in.js.erb'}
end
and then get your #template variable back in your sign_in.js.erb, <%= escape_javascript(#template) %>

Related

Rails respond_to throw ActionController::UnknownFormat

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.

Controller not rendering show.js.haml during AJAX

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)}");

ActionController::UnknownFormat / Missing template error

I am getting a "template missing error" on a .js.erb file, everything i've read says to add a respond_to which I did below but it's still not seeing my create.js.erb file, any ideas?
def create
#conversation = Conversation.find(params[:conversation_id])
#message = #conversation.messages.build(message_params)
#message.user_id = current_user.id
#message.save!
#path = conversation_path(#conversation)
respond_to do |format|
format.js
end
end
Seems like you don't have create.js.erb file in app/views/:controller_name/
If not create one at app/views/:controller_name/

Rails - handling an Ajax destroy call on a polymorphic association

I am trying to destroy a comment through Ajax. In my app, my comment model uses a polymorphic association. The comment deletes successfully (in the database) using the code below. However, when I call the destroy.js.erb, it doesn't do anything and I think the problem is that the dom_id doesn't match the HTML id, so it is not updating. I think I am experiencing the same thing that #mu_is_too_short articulated in the answer to this question. I need help with how to solve this though. I do not know if the solution involves a) somehow passing the local variable comment to the destory.js.erb or b) another solution.
routes.rb
resources :feeds do
resources :comments
end
destroy.js.erb
$('#<%= dom_id(#comment) %>')
.fadeOut ->
$(this).remove()
_comment.html.erb
<div id=<%= dom_id(comment) %> class="comment">
<em>on <%= comment.created_at.strftime('%b %d, %Y at %I:%M %p') %></em>
<%= link_to "Remove", [#commentable, comment], :method => :delete, :remote => true %>
<%= simple_format comment.content %>
</div>
feeds/show.html.erb
<div id="comments">
<%= render #comments %>
</div>
Comments controller
class CommentsController < ApplicationController
def create
#comment = #commentable.comments.new(params[:comment])
if #comment.save
respond_to do |format|
format.html { redirect_to #commentable }
format.js
end
else
render :new
end
end
def destroy
#comment = Comment.find(params[:id])
#commentable = #comment.commentable
if #comment.destroy
respond_to do |format|
format.html { redirect_to #commentable }
format.js
end
end
end
end
Feeds controller
class FeedsController < ApplicationController
def show
#feed = Feed.find(params[:id])
#commentable = #feed
#comments = #commentable.comments
#comment = Comment.new
end
end
By the looks of it, #comment will contain a comment when you get to destroy.js.erb, as you set it in the controller immediately before that, so I do not think it has anything to do with the referenced answer. I wonder if this is being caused by the lack of quotes around your id here: <div id=<%= dom_id(comment) %> class="comment">... I suspect if you correct this, and any other relevant HTML validation errors, it will start working.

How do I include HTML in a JS Rails response?

I have a FooController that responds to HTML and JS (AJAX) queries:
# app/controllers/foo_controller.rb:
class FooController < ApplicationController
layout 'foo'
def bar
respond_to do |format|
format.html # foo/bar.html.erb
format.js # foo/bar.js.erb
end
end
end
The templates to support it:
# app/views/layouts/foo.html.erb:
<html>...<%= yield %>...</html>
# app/views/layouts/foo.json.erb:
<%= yield %>
And an AJAX template in which I want to render a partial:
# app/views/foo/bar.js.erb:
dojo.byID('some_div').innerHTML = "<%= escape_javascript(render(:partial => 'some/partial')) %>";
If the JS template just has plain old JS in it (like alert('hi');), it uses my JS template. When I put in the render(:partial), though, it makes the whole response use the HTML template, which means it's no longer valid JS.
A possible solution is to use a function for the layout:
class FooController < ApplicationController
layout :choose_layout
...
private
def choose_layout
return nil if request.xhr?
'foo'
end
end
But my version should work! Why doesn't it?
The most recent Railscast covers this topic (using jQuery).
I'm not quite seeing where you might be going wrong, but here's a snippit from the Railscast that works just fine to render a partial:
// views/reviews/create.js.erb
$("#new_review").before('<div id="flash_notice"><%= escape_javascript(flash.delete(:notice)) %></div>');
$("#reviews_count").html("<%= pluralize(#review.product.reviews.count, 'Review') %>");
$("#reviews").append("<%= escape_javascript(render(:partial => #review)) %>");
$("#new_review")[0].reset();
Where are you storing your Javascript? Do you have an Application.js that you're keeping things in? If so, are you including "dojo" before "application" in your javascript_include_tag?
Try the following;
class FooController < ApplicationController
layout 'foo'
def bar
respond_to do |format|
format.html
format.js { render :layout => false }
end
end
end
Hope that helps.
J.K.

Categories