Rails 3.2
jQuery-Rails
I've searched all over and I've only found js ways to update a partial or add a partial via JS. I've had no luck with this one. Here is the issue:
I have a list of referrals on a page, the referrals are posted on the index page as partials. The referral box has a reply button and a count of how many replies per referral. Statically I had it working but I'm getting no luck with updating the referral box with the new count and replacing the reply button with an icon. The is getting to the database but I'm screwing something up with the refresh of the box. Help please!
Do I use locals to render the new variables?
Should I remove my if statements from the partial and just use the js.erb file to determine what to show?
Reply controller:
class RepliesController < ApplicationController
respond_to :html, :js
def new
#referral = Referral.find(params[:referral_id])
#reply = #referral.replies.new(:user_id => params[:user_id], :referral_id => params[:referral_id])
if #reply.save
format.html { notice: 'Replied' }
respond_with(#referral, :location => referrals_path)
end
end
end
_referral partial:
.referralBox.cornerShadow{:id => "Referral#{referral.id}"}
- if current_user == referral.user or current_user.role == 'administrator'
= link_to '<i class="icon-pencil icon-large icon-grey" rel="tooltip" title="Edit"></i>'.html_safe, edit_referral_path(referral), class: "referralEdit"
= link_to '<i class="icon-remove icon-large icon-grey" rel="tooltip" title="Delete"></i>'.html_safe, referral, method: :delete, data: { confirm: 'Are you sure?' }, class: "referralClose"
.referralProfile
= link_to "#{image_tag(referral.user.image.url, :class => "img-circle img-border border-white", :style => "thumb")}".html_safe, referral.user
%ul.unstyled.inline
%li
= referral.description
- unless referral.replies.count == 0
- if referral.user == current_user
%i.icon-comments.icon-large{"rel" => "tooltip", "title" => "Replies"}
= referral.replies.count
- else
%i.icon-comments.icon-large.orange{"rel" => "tooltip", "title" => "Replies"}
= referral.replies.count
- unless current_user == referral.user
- if referral.replies.any?
%i.icon-ok.icon-large.pull-right.orange{"rel" => "tooltip", "title" => "Replied"}
- else
= link_to '<i class="icon-ok icon-large pull-right icon-grey" rel="tooltip" title="Reply"> Reply</i>'.html_safe, new_referral_reply_path(:referral_id => referral.id, :user_id => current_user.id), :id => "ReplySubmit", :remote => true
new.js.erb view
$(".referralBox").html("<%= j(render(:partial => "#referral")) %>");
application.js
jQuery.ajaxSetup({
'beforeSend': function (xhr) {xhr.setRequestHeader("Accept", "text/javascript")}
});
Related
I am trying to call a method of one controller from within a different view.
I saw the following post Rails call destroy method from within another controller, but I am doing something wrong with my implementation.
The method I am trying to call is in an accessor controller.
def remove_permission_from_index
Accessor.find(params[:id]).destroy
respond_to do |format|
format.html { redirect_to tasks_url }
format.json { head :no_content }
end
end
This controller also has the following strong param method
def accessor_params
params.require(:accessor).permit(:accessor_id, :access_rights, :task_id)
end
My view is calling the following code
<%= link_to 'Delete', {:controller => "accessors", :accessor => elem} ,method: :remove_permission_from_index, data: { confirm: "Are you sure?" }%> </p>
where elem an element within a set that is defined in the task controller
#canEdit = Accessor.select(:task_id).where("accessor_id = ? AND access_rights = ?", current_user, true)
#canEdit.each do |p|
p.task = Task.find(p.task_id)
When I am running my code I am getting the following error
param not found: accessor
def accessor_params
params.require(:accessor).permit(:accessor_id, :access_rights, :task_id)
end
end
and I can see that the accessor param is not being passed :
Parameters:
{"_method"=>"remove_permission_from_index"}
a) why is the accessor_params is being called if I am trying to access a different method
b) what am I doing wrong? After all I do set :accessor => elem
Could be a copy paste error but:
<%= link_to 'Delete', {:controller => "accessors", :accessor => elem} ,method: :remove_permission_from_index, data: { confirm: "Are you sure?" }%> </p>
should be more like:
<%= link_to 'Delete', {:controller => "accessors", :action => :remove_permission_from_index, :accessor => elem}, method: :delete, data: { confirm: "Are you sure?" }%> </p>
views/vehicles/_form.html.haml
= link_to "Deactivate", "/vehicles/deactivate"
I want to pass in #vehicle in my link_to above.
How do I do this?
controllers/vehicles_controller.rb
def deactivate
#vehicle = Vehicle.find(params[:id])
#vehicle.active = 0
#vehicle.save
respond_to do |format|
format.html { redirect_to vehicles_url }
format.json { head :no_content }
end
end
To make it easy and in Rails way, you can use Rails resources:
# routes.rb
resources :vehicles do
put 'deactivate', on: :member
end
# view:
= link_to 'Deactivate', deactivate_vehicle_path(#vehicle), method: :put
Best answer already given by Marek Lipka.
There is also a way using ajax
<%= link_to 'Deactivate', javascript::void(0), :class => "deactivate" %>
Put some script:
<script>
$(".deactivate").click(function() {
$.ajax({
type: "post",
url: "/vehicles/deactivate",
data: {id: <%= #vehicle.id %>},
dataType:'script',
beforeSend: function(){
// do whatever you want
},
success: function(response){
// do whatever you want
}
});
});
</script>
This worked for me, I ended up using the Update action in my controller.
= link_to "Deactivate", vehicle_path(#vehicle, :vehicle => {:active => 0}), method: :put, :class=>'btn btn-mini'
I'm still relatively new to Rails so please bear with me. How can I refresh the partial and stay at the page instead of rendering only the partial?
In _interaction.html.haml:
%div.vote_up.pull-left
= link_to('', vote_up_deal_path(deal), :method => :post,
:class => 'icon-thumbs-up interaction_button', :id => "vote_up_#{deal.id}")
In 'votes.js':
$.ajax({
type: 'POST',
url: '/deals/' + id + '/vote_up',
success: function() {
//do stuff
}
});
In my deals_controller.rb:
def vote_up
if user_signed_in?
current_user.vote_exclusively_for(#deal = Deal.find(params[:id]))
render :partial => 'deals/partials/interaction', :locals => {:deal => #deal}
end
end
This will redirect me to the page and render the partial instead of refreshing it like an AJAX request should.
Try
= link_to('', vote_up_deal_path(deal), :method => :post, :remote=>true,
:class => 'icon-thumbs-up interaction_button', :id => "vote_up_#{deal.id}")
because :remote says that it is ajax request
This bug has me perplexed.
I am displaying a Widget with the last 5 data points and a form for a new data_point. When I try to render both the form and the display partial it fails with a routing error. If I comment out either partial it works fine. So with only the form partial it works, or with only the display partial it works fine with the other.
Three relevant models/controllers: Widget, DataSet and DataPoint. DataPoints is STI so I have different partials to display the different types that match the class name.
When both render :partial => ... are uncommented it looks as if the data_point being passed to the second partial is the same as the data_point being passed to the first partial. It is all nil with only a data_set_id. I tried renaming the local from :data_point to :dp in case it was a name collision.
View, both partials and the routing error shown at the bottom.
Is there a limitation on passing :locals to partials when you are trying to render more than one partial in a view?
View: show.html.haml (the show action on the controller is empty)
- title "#{#widget.type.underscore.humanize} for #{#widget.data_set.name.to_s.downcase}"
.row
.span6
= render :partial => 'data_points/form', :locals => { :data_set => #widget.data_set, :data_point => #widget.data_set.data_points.build }
%br
- last_5 = #widget.data_set.data_points.last(5)
- if last_5.count > 0
%h3= "Last #{pluralize( last_5.count, 'Entry' )}"
- last_5.each do |dp|
%pre
= dp.inspect
= render :partial => "data_points/#{#widget.data_set.data_type.underscore}", :locals => { :data_set => #widget.data_set, :data_point => dp }
- else
%h3 No data yet!
= form_tag( push_widget_path #widget, :method => 'POST' ) do
= submit_tag( "Push Data", :class=>"btn btn-primary" )
= link_to "Edit your data", data_set_path( #widget.data_set ), :class=>'btn'
.span6
= image_tag "widgets/#{#widget.type.underscore}.png"
%p
Using the
%b= link_to #widget.data_set.name, #widget.data_set
data set.
= render :partial => "widgets/#{#widget[:type].underscore}", :locals => { :widget => #widget } rescue nil
%p
= link_to 'Edit', edit_widget_path(#widget), :class=>'btn'
Form Partial (data_points/_form.html.haml)
%pre
= data_set.inspect
%pre
= data_point.inspect
= form_for [data_set,data_point], :html=>{:class => 'well form-horizontal'} do |f|
-if data_point.errors.any?
#error_explanation
%h2= "#{pluralize(data_point.errors.count, "error")} prohibited this data_point from being saved:"
%ul
- data_point.errors.full_messages.each do |msg|
%li= msg
= render :partial => "data_points/#{data_set.data_type.underscore}_form", :locals => { :f => f, :data_point => data_point, :data_set => data_set }
= f.text_field :created_at, :type=>'datetime'
.form-actions
= f.submit 'Save'
Display Partial (data_points/_multi_value_data_point.html.haml)
.data-point{ :id=>"data-point-#{data_point.id}"}
%span.value
- data_point.data.map do |k,v|
- label = data_set.properties[:data_series][k][:name]
%span.key= "#{label}: "
= v
.meta
= data_point.created_at
%span.edit
= link_to 'Edit', edit_data_set_data_point_path( data_set, data_point )
%span.delete
= link_to 'Destroy', [data_set, data_point], :method => :delete, :data => {:confirm => 'Are you sure?'}
=# link_to 'Edit', '#', id: "edit-data-point-#{data_point.id}"
:javascript
$("#edit-data-point-#{data_point.id}").click( function(e) {
$("#data-point-#{data_point.id}").html( "#{escape_javascript( render :partial => "data_points/multi_value_data_point_form", :locals => { data_set: data_set, data_point: data_point } )}");
return false;
});
Routing Error
Routing Error
No route matches {:action=>"edit", :controller=>"data_points", :data_set_id=>#<MultiValueDataSet id: 4, ... properties removed ... type: "MultiValueDataSet">, :id=>#<DataPoint id: nil, data: {}, data_set_id: 4, created_at: nil, updated_at: nil>}
Try running rake routes for more information on available routes.
The problem stems from the fact that the form is building a new element that isn't saved, and last is returning that unsaved element.
Simple solution, replace .last(5) with .find( :all, order: 'id desc', limit: 5 )
I have a view which contain multiple links:
<% a.each do |q| %>
<%= link_to "stock it",
{ :action => "stock",
:qid => q.question_id,
:qur => q.question_answers_url,
:qti => q.title } ,
:remote => true %>
<div id="<%= "stock" + q.question_id.to_s %>"></div>
<% end %>
Each link generate AJAX-request. Here is a controller:
def stock
if(!Later.where(:question_id => params[:qid]).exists?)
later = Later.new(:question_id => params[:qid], :name => params[:qti], :url => params[:qur])
later.save
end
respond_to do |format|
format.js { render :layout=>false }
end
end
Now return to the view. Each link has a 'div' with unique id='stock'. When user press the link I need to add text to specific div with corresponding id.
I have a stock.js.erb file:
$("#stock<number>").html("some text");
How can I pass div-id to stock.js.erb and how can I use it ?
Common use is to add object.id to your DOM id. That what you exactly did:
<div id="<%= "stock_#{q.question_id}" %>"></div>
Then in your controller you shoud define your question_id or your exact question:
def stock
if(!Later.where(:question_id => params[:qid]).exists?)
later = Later.new(:question_id => params[:qid], :name => params[:qti], :url => params[:qur])
later.save
end
#question_id = params[:qid]
end
Now it will be shared with your stock.js.erb file:
$("#stock_<%= #question_id %>").html("some text");