This is the line in my new.js.erb that calls the render function
$('.node_container').append("<%= escape_javascript(render(#care_point, :locals => {:care_map => #care_map}))%>");
Gives error message:
ActionView::Template::Error (undefined local variable or method `care_map'
for my partial _care_point.html.erb:
<%= link_to 'Delete', [care_map, care_point], :confirm => "Are you sure?", :method => :delete, :remote => true, :class => 'delete' %>
To pass locals variables, you must use
render :partial => partial_name, :locals => { # all your vars here }
and not the mere:
render #var
See doc here, para 3.4.4.
Related
Sorry for the long title. I don't know how I got stuck this much.
I wanted to have a button (actually a link_to styled as a button) for FOLLOW / UNFOLLOW on remote. That's a Follow model where records are stored for Corporation and User (a User can follow a Corporation). The follow/unfollow links are on the Corporation show page.
<% if user_signed_in? %>
<% if Follow.where(corporation_id: #corporation.id, user_id: current_user.id).first.nil? %>
<%= link_to 'FOLLOW', {:controller => "follows", :action => "create", :user_id => current_user.id, :corporation_id => #corporation.id}, remote: true, :method => "post", class: "btns follow", id: "follow1" %>
<% elsif %>
<%= link_to 'UNFOLLOW', {:controller => "follows", :action => "destroy", :corporation_id => #corporation.id, :user_id => current_user.id }, remote: true, :method => "delete", class: "btns unfollow", id: "unfollow" %>
<% end %>
<% end %>
These are the controller actions:
def create
#corporation_id = params[:corporation_id]
#follow = Follow.new(follow_params)
#follow.save
respond_to do |format|
format.js {render :file => "/corporations/create.js.erb" }
end
end
def destroy
#corporation_id = params[:corporation_id]
attending.destroy
#attending is a method where the follow is defined. This is ok.
respond_to do |format|
format.js {render :file => "/corporations/destroy.js.erb" }
end
end
I'm rendering create.js.erb in corporations, since the change has to happen there. If I leave it as format.js, it'll search in the follows folder which is empty.
The create.js.erb look like this:
$("#unfollow").click(function(){
$("unfollow").replaceWith("<%= escape_javascript(render :partial => "corporations/profile/follow", :locals => {corporation_id: #corporation_id}) %>");
});
Btw, I tried .html instead of replaceWith, but it's not that.
The destroy.js.erb is similar. And the _unfollow.html.erb partial is like this:
<% if !#corporation.nil? %>
<%= link_to 'UNFOLLOW', {:controller => "follows", :action => "destroy", :corporation_id => #corporation.id, :user_id => current_user.id }, :method => "delete", class: "btns unfollow", remote: true, id: "unfollow" %>
<% else %>
<%= Rails.logger.info("First here") %>
<%= Rails.logger.info(corporation_id) %>
<%= link_to 'UNFOLLOW', {:controller => "follows", :action => "destroy", :corporation_id => corporation_id.to_i, :user_id => current_user.id }, :method => "delete", class: "btns unfollow", remote: true, id: "unfollow" %>
<%= Rails.logger.info("Now here...") %>
<% end %>
Without the first condition it just fires up an error the corporation_id (it's same with locales[:corporation_id]) is not defined and similar.
I have no idea what to try now... All the tutorials on the net are quite simple but the remote action is just one action in the controller where it needs to change, this has to go to another controller then back, then again to Follow... I'd really appreciate the help.
I have a Rails app with a controller/view called "calls". Here is the basic controller action for index:
calls_controller.rb
def index
if params[:region].present?
#assigned = Call.where(region_id: params[:region][:area]).assigned_calls.until_end_of_day
#unassigned = Call.where(region_id: params[:region][:area]).unassigned_calls.until_end_of_day
else
#assigned = Call.assigned_calls.until_end_of_day
#unassigned = Call.unassigned_calls.until_end_of_day
end
end
Here are my views:
index.js.erb
$('#active').html("<%= escape_javascript render :partial => 'calls/assigned_calls', :locals => {:assigned_calls => #assigned} %>");
$('#inactive').html("<%= escape_javascript render :partial => 'calls/unassigned_calls', :locals => {:unassigned_calls => #unassigned} %>");
$(".select").select2({
placeholder: "Select One",
allowClear: true
});
index.html.erb
<div id="active">
<%= render "assigned_calls" %>
</div>
<div id="inactive">
<%= render "unassigned_calls" %>
</div>
<script>
$(document).ready(function() {
setInterval(function () {
$.ajax('calls/<%= params[:region][:area] %>');
} , 5000);
});
</script>
_assigned_calls.html.erb (view code omitted)
<%= form_tag calls_path, :method => 'get' do %>
<p>
<%= select_tag "region[area]", options_from_collection_for_select(Region.order(:area), :id, :area, selected: params[:region].try(:[], :area)), prompt: "Choose Region" %>
<%= submit_tag "Select", :name => nil, :class => 'btn' %>
So what's happening is on page load if I do not have the params of :region passed it sets the calls without being scoped by region. If region_id is present then it scopes calls where region_id is "1" or whatever the Region ID is that is passed from the submit_tag.
This works fine in the controller and view, however here's my problem. My index.html.erb I need to refresh the partials WITHOUT disturbing the params passed. So on setInterval I need to figure out how to reload the partials while persisting the params passed in the URL.
I tried to figure this out using a setInterval method but I'm not sure what I'm doing here 100%.
Can someone give me some advice on how to refresh the partials every 5 seconds while persisting the params so my instance variables persist through refresh?
If you need more context and/or code please let me know.
Update
Trying to rework the javascript based off an answer from a user and here's what I have.
<script>
$(document).ready(function() {
setInterval(function () {
$.ajax({
url: 'calls_path',
type: "GET",
data: { "region": '<%= #region.html_safe %>' }
}), 5000);
});
});
</script>
The page will load but when it tried to trigger in the chrome inspector I get:
calls?utf8=✓®ion[area]=3:2901 Uncaught SyntaxError: Unexpected token )
Maybe this is a JS syntax error or I'm not closing the function properly.
If I understood properly, you want to have your parameters somehow pipelined through AJAX call to your controller, back to your js.erb file where it refreshes the partials?
My advice is to set passed parameters as instance variables in your controller like this:
calls_controller.rb
def index
if params[:region].present?
#region = params[:region]
#assigned = Call.where(region_id: params[:region][:area]).assigned_calls.until_end_of_day
#unassigned = Call.where(region_id: params[:region][:area]).unassigned_calls.until_end_of_day
else
#assigned = Call.assigned_calls.until_end_of_day
#unassigned = Call.unassigned_calls.until_end_of_day
end
end
Now your #region instance variable will be available in your index.js.erb
where you can pass it to other partials you are trying to render.
index.js.erb
$('#active').html("<%= escape_javascript render :partial => 'calls/assigned_calls', :locals => { :assigned_calls => #assigned, :region => #region } %>");
$('#inactive').html("<%= escape_javascript render :partial => 'calls/unassigned_calls', :locals => { :unassigned_calls => #unassigned, :region => #region } %>");
_assigned_calls.html.erb
<%= form_tag calls_path, :method => 'get' do %>
<%= select_tag "region[area]", options_from_collection_for_select(Region.order(:area), :id, :area, selected: region.try(:[], :area)), prompt: "Choose Region" %>
<%= submit_tag "Select", :name => nil, :class => 'btn' %>
<% end %>
Also, I think that better practice in your index.html.erb script tag
is to do it like this:
<script>
$(document).ready(function() {
setInterval(function () {
$.ajax({
url: 'calls_path',
type: "GET",
data: { "region": '<%= #region.html_safe %>' }
});
}, 5000);
});
</script>
Please test this out if you're interested and get back to me :)
I'm generating a link with a confirmation message and am having trouble with how the confirmation message is getting included.
I have tried this with both rails 4.0.10 and rails 4.2.2 and it produces the same output.
Here is my link_to code:
<%= link_to 'Destroy Comment', :url => [comment.article, comment], :method => :delete, :remote => true, :confirm => "are you sure?" -%>
And it generates the following link:
<a data-remote="true" href="/articles/4?confirm=are+you+sure%3F&method=delete&url%5B%5D=4&url%5B%5D=5">Destroy Comment</a>
This is obviously doesn't work because it's putting the javascript confirm message right into the url of the link.
I've found that if I remove the :url => from the link_to it seems to work fine.
<%= link_to 'Destroy Comment', [comment.article, comment], :method => :delete, :remote => true, :confirm => "are you sure?" -%>
<a confirm="are you sure?" data-remote="true" rel="nofollow" data-method="delete" href="/articles/4/comments/5">Destroy Comment</a>
Is there a way to fix this and keep the :url => in the link_to? I really like having the :url => in there for specificity purposes. I looked through the api docs but couldn't find a specific answer. There was one comment made that claims something like this should work. http://apidock.com/rails/ActionView/Helpers/UrlHelper/link_to#1227-link-to-with-as-routing
In your first example, you are passing a hash as second parameter, which matches this method signature:
link_to(body, url_options = {}, html_options = {})
causing Rails to interpret it as url_options, which is why you get that link you get.
If you really want to user the :url=>, then you can create your own helper method, say link_to_with_url that that expects hash containing :url key as the second parameter:
def link_to_with_url(body, options={})
url = options.delete(:url);
if url.nil?
raise "Can't link to something that doesn't have a URL"
else
link_to body, url, options
end
end
You can also overload Rails' link_to method, but I would advise against that.
Try this:
<%= link_to 'Destroy Comment', :url => [comment.article, comment], :method => :delete, :remote => true, :data => {:confirm => "are you sure?"} %>
I'm trying to allow users to favorite posts and then it show them sort of of interaction through AJAX, but it's not working.
The error I'm getting in the console is:
ActionView::Template::Error (undefined local variable or method `post_item' for #<#<Class:0x007fecb2a3d5f8>:0x007fecb2a357e0>):
The button is being rendered through a partial:
<%= render "shared/fave_form", post_item: post_item %>
Here's the code for the button (shared/_fave_form.html.erb):
<% if current_user.voted_on?(Post.find(post_item)) %>
<%= link_to "unlike", vote_against_post_path(post_item.id), :remote => true, :method => :post, :class => "btn") %>
<% else %>
<%= link_to "like", vote_up_post_path(post_item.id), :remote => true, :method => :post, :class => "btn") %>
<% end %>
Here's the toggle.js.erb file:
$("#fave").html("<%= escape_javascript render('fave_form') %>");
When you render the partial using toggle.js.erb it is not getting locals value post_item, you have to provide it in also.So, your js code should be something like following
$("#fave").html("<%= escape_javascript(render :partial=>"fave_form", locals: {post_item: post_item}).html_safe %>);
I guess you are using some ajax call and then your toggle.js.erb so in your toggle action you must specify value to post_item, lets make it instance variable #post_item so that we can use it in toggle.js.erb.
$("#fave").html("<%= escape_javascript(render :partial=>"fave_form", locals: {post_item: #post_item}).html_safe %>);
The partial is using a local variable, so pass post_item as a local:
<%= render :partial => "shared/fave_form", :locals => {post_item: post_item} %>
I need to send a class name with my observe_field call so I can update the correct text_field (there are multiples on the same page)
<%= observe_field "songlists_" + section.id.to_s + "_song_name",
:frequency => 0.5, :url => { :controller => :songlists, :action =>
:get_artist }, :update => text_class ,
:with => "'song_name=' +encodeURIComponent(value)+'&songlists_classname='+ xxxxxxxx" %>
Is there a way of inserting a ruby variable into the :with statement where 'xxxxxxxx' is displayed above?
Or any other way?
Sure, why not? You're just passing a string to :with, so insert a variable into like you would any other string, e.g. "...&songlists_classname=#{your_variable}":
<%= observe_field "songlists_#{section.id}_song_name",
:frequency => 0.5,
:url => { :controller => :songlists, :action => :get_artist },
:update => text_class,
:with => "'song_name=' + encodeURIComponent(value) + '&songlists_classname=#{your_variable}'" %>