Rails remote javascript - javascript

In my views I have recently started implementing remote javascript updates of only parts of my pages using commands such as:
$("#flash_messages").html("<%= escape_javascript(render 'shared/flash_messages') %>");
I now have a scenario where I have a list of items, each one within tags with a unique id and when the user clicks on a link within an item I want to only replace the contents of the corresponding
i.e.
<span id="article-123">
html here
</span>
create.js.erb
$("#???????").html("<%= escape_javascript(render 'shared/article') %>");
My question is how to I pass the span id "article-123" through to my create.js.erb file and include it as a variable in the above command.

Try with locals variable in render response, in YourController#method
respond_to do |format|
format.js { render "create", :locals => {:article_id => article_id} }
end
now you can use article_id in create.js.erb file.

Related

Passing variable from Rails to js.erb file

This is the code for my side bar. When a user clicks on one of the links, the js.erb file is called, but I don't know how to make the js.erb file be able to differentiate which link the user clicked on. My idea is to use an id, so basically pass the instance variable to the js.erb file. This is how I think it might be done, but I'm not sure at all.
<li>
<%= link_to 'User Details', '/dashboard', :id => 'User Details', remote: true %>
</li>
<li>
<%= link_to 'Projects', '/dashboard', :id => 'Projects', remote: true %>
</li>
There's the js.erb file that's run with this code:
<% if :id == 'User Details' %>
$('#ajax').html("<%= escape_javascript(render :partial => 'users/edit', :locals => { :user => #user } ) %>");
<% elsif :id == 'Projects' %>
$('#ajax').html("<%= escape_javascript(render :partial => 'projects/index', :locals => { :projects => #projects } ) %>");
<% end %>
What am I doing wrong or how should I pass some sort of flag or id to the js.erb file so that I can show the correct information?
I'm not sure if you understand how websites work. Ruby is a server-side language, it is executed and html + js are sent to the web browser. JS files are (in most cases) executed just once on asset compilation/first run and never get updated again.
So there's no way to refer to Ruby code from js on the runtime as you are doing.
Also you're using illegal characters in id attributes, see What characters are allowed in DOM IDs?
Back to ruby/js thing.
You may want to request a partial via ajax, passing an id attribute
$('#ajax').load('<%= here_put_helper_method_to_some_path %>');
And then in ProjectsController#index render what you wish (based on current user for example).
Also - a good rule is to first make things work without ajax and then add ajax calls.

The right place for the Js to render a partial in Rails

My plan was to update a partial via a klick-event where I fetch some data via ajax.
So i opened my assets/javascripts directory and put the code in the js file of the module I planed to call it on. I managed to fetch the data and to call some "html() or text()" on the div. But as soon as I tried to call
.html("<%= escape_javascript( render( :partial => 'job') ) %>")
my controller told me unknown method "render". So I red in many other Threats that the assets directory was not build for static content.
But now comes the question where to put it if not in assets?
I tried to put it in the view/model folder (with the same name as the aktion 'show'). But it wouldn't load. Yes I told the Controller in the show action to respond_to format.js.
So where should I put the js-File and how to call it? Or is there even a method to let it in the assets-directory and beeing able to call render?
Thanks for your answer! Sadly I do exactly that but I doesnt work. So here is my Code:
/app/views/events/show.js.erb.coffee:
$(document).ready ->
url = window.location
url = String(url).split('/')
event_id = url[$.inArray( "events" , url) + 1]
$('.position').click ->
position_id = $(this).attr("id")
$.ajax '/events/'+event_id+'/eventpositions/'+position_id+'/eventjobs'
dataType: 'json'
success: (result)->
$( '#'+position_id ).find('.jobs').html("<%= escape_javascript( render( :partial => 'job') ) %>")
alert result[1].job_id
/app/views/events/show.html.haml:
%p#notice{:xmlns => "http://www.w3.org/1999/html"}= notice
%p
%b Name:
= #event.name
\ 
%b Plz:
= #event.plz
%p
%b Personal:
- #eventpositions.each do |p|
.position{:id => "#{p.id}"}
%b
Position: #{Position.find(p.position_id).name} Anzahl: #{p.quantity} Aufträge: #{p.eventjobs.all.count}
.jobs
= link_to 'Neuer Auftrag', new_event_eventposition_eventjob_path(#event.id,p.id)
%br
%br
= link_to 'Neue Position', new_event_eventposition_path(#event.id)
= link_to 'Edit', edit_event_path(#event)
|
\#{link_to 'Back', events_path}
/app/views/events/_job.html.haml:
.jobs
- eventjobs.each do |j|
User: #{User.find(Job.find(j.job_id).user_id).email}
%br
/app/controllers/events_controller.rb:
def show
#agency = Agency.find(current_agent.agency_id)
#event = #agency.events.find(params[:id])
#eventpositions = #event.eventpositions.all
respond_to do |format|
format.html # show.html.erb
format.json { render json: #event }
format.js
end
end
So the Code does work without Javascript. All renders and is fine. But my main Problem now is that it wont even react to a click event if I place it in the app/views/events Folder. As soon as I place it in the assets directory I works like a charm, but wont render.
So what am I missing? Why does my js Code does not get loaded?
Thanks a lot for your help!
Generally for this kind of thing, I'll name it the same as a particular action, such as show.js.erb, and then use the format.js as you have in the controller. If you're using coffeescript, it will need to be named show.js.coffee.erb. If this does not work, can you post the code of your view where this onclick event is setup?
Edit for using the show javascript code
Because you're using the show action, should just be able to do this:
= link_to "Show", #event, :remote => true, :format => :js
Adjust the event variable there as you need to, but it should work

rails jquery ajax request not executing

I am implementing an up-voting system on an app I am building very similar to the one here on stackoverflow. When a user clicks upvote or downvote, an ajax request is sent to one of my controllers which them updates a couple of tables. Once that is done, I use the respond_to to routes to a js.erb file that executes jquery to update the user display. However, the jquery is not being executed. When I lick upvote/downvote, the controller code executes properly (I can see it in the rails console), but the user display is not updated. Upon refresh the user display is updated, however, not asynchronously. I know the jquery is not being executed b/c in the fire bug console I can see my jquery code - it just is not being applied. Here is my upvote controller code:
def upvote
#post = Post.find(params[:id])
#user_vote = current_user.votes.where(post_id: #post.id).first
if #user_vote.blank?
Vote.create(user_id: current_user.id, post_id: #post.id, vote: 1)
#post.upvotes += 1
elsif #user_vote.vote.to_i == 0
#user_vote.vote = 1
#post.upvotes += 1
elsif #user_vote.vote.to_i == 1
return redirect_to :back, :alert => 'You have already upvoted the post'
elsif #user_vote.vote.to_i == 2
#user_vote.vote = 1
#post.downvotes -= 1
#post.upvotes += 1
end
respond_to do |format|
if #post.save and #user_vote.save
format.js { }
else
format.html { redirect_to :back, :alert => 'There was an error in upvoting the post' }
end
end
end
This is my upvote.js.erb file:
$('#post-action-<%= #post.id %>').html("upvote");
// this normally renders a partial (below), but I am rendering "upvote" until I can fix this
// escape_javascript(<%= render :partial => 'post_voting', :locals => { post: #post, user_vote: #user_vote } %>)
Here is my html:
<div class="post_actions" id='post-action-<%= "#{post.id}" %>' >
<%= render :partial => 'post_voting', :locals => { post: post, user_vote: current_user.votes.where( post_id: post.id ).first } %>
</div>
Here is my firebug console output: http://i.imgur.com/H6zXJ.png
EDIT
I noticed I am getting an error in on my server:
Started GET "/assets/bootstrap.js?body=1" for 127.0.0.1 at 2012-08-09 06:33:42 -0700
Served asset /bootstrap.js - 304 Not Modified (0ms)
Your code seems OK and should execute. You might do an additional check to update a fixed id instead of the calculated id.
$('#updateme').html("upvote");
and add this id in your html somewhere. If this works, you are certain the ajax-call executes completely, and the problem is just the id you are referencing.
Have you checked your html-source that there is an id "post-action-2"?
After messing around with the jquery, I noticed some things. Firstly, I needed to minify my code (taking out all comments and unused spaces). I took this:
$('#post-action-<%= #post.id %>').html("upvote");
// this normally renders a partial (below), but I am rendering "upvote" until I can fix this
// escape_javascript(<%= render :partial => 'post_voting', :locals => { post: #post, user_vote: #user_vote } %>)
and changed it to this:
$('#post-action-<%= #post.id %>').html("upvote");
The code was then working and the user display was updating to show "upvote." Perfect. So then I replaced the above code with this:
$('#post-action-<%= "#{#post.id}" %>').html("<%= escape_javascript(render :partial => 'post_voting', :locals => { :post => #post, :user_vote => #user_vote }) %>");
and KAPOW! It works. So happy to have solved this! MINIFY YOUR JQUERY PEOPLE!

Cucumber Testing js.erb functions when no html.erb exists

My rails application is using js.erb views instead of html.erb views for specific windows. This works fine in practice, but when I'm using cucumber tests with capybara it gives me an error of
Missing template admin/groups with {:handlers=>[:erb, :rjs, :builder, :rhtml, :rxml], :formats=>[:html], :locale=>[:en, :en]} in view paths
When I click the button pertaining to this particular view. There is no groups.html.erb but there is a groups.js.erb. I want to somehow tell cucumber/capybara to not try to render the groups.html.erb but still render the groups.js.erb. I would prefer not to generate an unnecessary html file to render the same thing the escape javascript below is doing.
groups.js.erb:
$("#admin_content").html("<%= escape_javascript(render :partial => 'groups') %>");
Relevant admin controller method:
def groups
#groups = Group.all
end
You should use proper MIME type handling for your responses. Try this:
def groups
#groups = Group.all
respond_to do |format|
format.js
end
end
eventually you can be more specific about how to respond :
format.js { render layout: false }
more info on respond_to here.
note: if your controller only manages js responses, you can add respond_to :js at the top of the class, and then use respond_with #object in your actions.

undefined method `formats' when rendering html.erb file

Im using Rails 3.0.3 and ruby 1.8.7
I want to render /materials/change_prize.html.erb in materials/change_prize.js.erb file.
change_prize.js.erb:
$("#content").html("<%= escape_javascript(render(:action => 'materials/change_prize.html.erb')) %>");
Materials Controller:
def change_prize
#material = Material.find(params[:id])
respond_to do |format|
format.js
format.html
end
end
routes.rb:
resources :materials do
member do
get 'change_prize'
post 'change_prize'
end
end
but when i load the js file i get this error:
undefined method `formats' for nil:NilClass
what am i doing wrong?
You need to use :partial not :action
<%= escape_javascript(render :partial => "materials/change_prize", :locals => { :xxxx => #xxxx }) %>
n.b. xxxx is if you need to pass your object to the partial
Partials have to begin with underscore. So rename your filename to "materials/change_prize.html.erb" to "materials/_change_prize.html.erb". Do note however that when calling it thru the render call you refer to the file WITHOUT the underscore.
$("#content").html("<%= escape_javascript(render(:action => 'materials/change_prize.html.erb')) %>");
Filename : app/views/materials/_change_prize.html.erb

Categories