Rails partial not rendering through ajax call - ruby-on-rails

I am trying to render a partial through ajax when a user clicks on button destroying a relationship between two products. The destroy action works, but I can not get the rendering of the partial to work.
The partial is rendered on the edit page for a product:
edit.html.erb
<div id="relationship_form">
<%= render "relationships", product: #product %>
</div>
_relationships.html.erb
<%= render "unrelate", relationship: relationship %>
_unrelate.html.erb
<%= form_for(relationship,html: { method: :delete },remote: true) do |f| %>
<%= f.submit "Remove", class: "btn btn-small" %>
<% end %>
relationships_controller.html.erb
def destroy
...
respond_to do |format|
format.html { redirect_to edit_product_path }
format.js
end
end
destroy.js.erb
$("#relationship_form").html("<%= escape_javascript(render :partial => 'products/relationships', :locals => {:product => #product}) %>");
I have checked that the ajax call goes through to the destroy.js.erb, by inserting an alert, so there must be an error in the javascript?
Update:
I got it to work by moving the form in the _unrelate partial to the _relationship partial. Still not really clear why it made it work.
_relationships.html.erb
<%= form_for(relationship,html: { method: :delete },remote: true) do |f| %>
<%= f.submit "Remove", class: "btn btn-small" %>
<% end %>

Related

Edit a comment in its association show

I have a Concert model and Comment model
The user directly write his comments in the concert show, but for any reasons he may want to edit it...
What is the easiest way to do this? I don't want to go to the edit view, but I'd rather prefer to edit it in the show page...
How or can I use the same form that I have in that show?
I was thinking of a modal but I am not sure it's friendy user...
Any help would be very welcome
concerts/show.html.erb
<h1><%= #concert.kountry%> - <%= #concert.city %> - <%= #concert.venue %> </h1>
<% #concert.comments.each do |c| %>
<%= c.user.email %>
<%= l(c.created_at, format: '%d/%m/%y - %H:%M:%S') %> - <%= link_to "Modifier", edit_concert_comment_path(c) %>
<%= simple_format(c.content) %>
<% end %>
<%= simple_form_for([#concert, #comment]) do |f| %>
<%= f.input :content, as: :text, placeholder: "your comment", label: false, input_html: { rows: 3 } %>
<%= f.submit "Send", class: "btn btn-success" %>
<% end %>
You can try using the Best In Place gem, hasn't been updated in a while but should still work.
modify form
<% #concert.comments.each do |comment| %>
<%= comment.user.email %>
<%= l(comment.created_at, format: '%d/%m/%y - %H:%M:%S') %>
<%= best_in_place(comment, :content, as: :textarea) %>
<% end %>
then modify controller
def update
#comment = Comment.find params[:id]
respond_to do |format|
if #comment.update(update_comment_params)
format.html { redirect_to(#comment, notice: 'Comment was successfully updated.') }
format.json { respond_with_bip(#comment) }
else
format.html { render action: "edit" }
format.json { respond_with_bip(#comment) }
end
end
end

How can I make follow form work with a list

I have a relationship model that follow users back n forth
now it works very well when I use it in users#show in my view just like this screenshot
now this works good but what I have is a list of users.. and with that list I want to render similar type of follow form next to every item in list
here is the screenshot for reference
but of course this doesn't work because in my relationship controller I am finding user/amitian to follow with their id in params[:id] as in show page i have it but in my list page i don't
here is the code in controller for reference
def create
#amitian = Amitian.find(params[:followed_id])
current_amitian.follow(#amitian)
respond_to do |format|
format.html { redirect_to #amitian }
format.js
end
end
def destroy
#amitian = Relationship.find(params[:id]).followed
current_amitian.unfollow(#amitian)
respond_to do |format|
format.html { redirect_to #amitian }
format.js
end
end
is there any solution for this so that I can render a follow_form in my listpage
it doesn't matter even if i have to render a new follow_form.. it just i want follow mechanism to work even from list page rather than only from show page of every user.
here is the show form in my show page..
show_form
<%if amitian_signed_in?%>
<% if #amitian != current_amitian %>
<div id="follow_form">
<% if current_amitian.following?(#amitian) %>
<%= render 'unfollow' %>
<% else %>
<%= render 'follow' %>
<% end %>
</div>
<% end %>
<%end%>
follow_form
<%if amitian_signed_in?%>
<%= form_for(current_amitian.active_relationships.build , remote: true ) do |f| %>
<div><%= hidden_field_tag :followed_id, #amitian.id %></div>
<%= f.submit "Follow", class: "btn btn-primary form-control" %>
<% end %>
<%end%>
unfollow form
<%if amitian_signed_in?%>
<%= form_for(current_amitian.active_relationships.find_by(followed_id: #amitian.id), remote: true,
html: { method: :delete }) do |f| %>
<%= f.submit "Unfollow", class: "btn btn-danger form-control" %>
<% end %>
<%end %>

Updating partial after submit

On my comments show page I am loading a partial called '_links' and the form to add a new link like this.
comments/show.html.erb
<%= render :partial => 'comments/newlink', locals: {question:question} %>
<%= render :partial => 'links/form', locals: {question:question} %>
comments/_newlink
<% question.links.each do |link| %>
<%= link.body %>
<% end %>
The form looks like this.
links/_form.html.erb
<%= simple_form_for [question, Link.new] do |f| %>
<%= f.input :body %>
<%= f.button :submit, class: "button" %>
<% end %>
I then have a file 'link.js.erb':
comments/link.js.erb
$('.button').append('<%= j (render :partial => 'comments/newlink') %>');
What I am trying to do is update the _links partial using jquery after someone clicks the submit button but it's not quite working. I believe the jquery is correct and it's a rails issue with where I placed the partials.
There are couple of things which you are missing
a. You need to submit your form by ajax so use remote: true option. Your form should be like this:
<%= simple_form_for [question, Link.new], remote: true do |f| %>
<%= f.input :body %>
<%= f.button :submit, class: "button" %>
<% end %>
b. Your form will send a request to create method in your links controller so your method should be like this:
def create
#link = Link.new(link_params)
#question = Question.find(params[:question_id])
respond_to do |format|
if #link.save
format.js # this will look for a file names create.js.erb in views/links directory
else
render "new"
end
end
c. Render your partial and pass locals to it in create.js.erb:
$('.button').append("<%= j (render :partial => 'comments/newlink', locals: {question: #question}) %>"); #notice using double qoutes not single
For details you should checkout Working with Javascript in Rails
Update:
<div id="link">
<%= render :partial => 'comments/newlink', locals: {question:question} %>
</div>
<div id="link-form">
<%= render :partial => 'links/form', locals: {question:question} %>
</div>
and then to update your partials use this js in create.js.erb
$('#link').html("<%= j (render :partial => 'comments/newlink', locals: {question: #question}) %>"); #notice using double qoutes not single
$('#link-form').html("<%= j (render :partial => 'links/form', locals: {question: #question}) %>"); #notice using double qoutes not single

Rails - AJAX/JQuery not working

For my application, I have projects where users can make comment (class Newcomments) postings. Right now it posts great but on page refresh. I am trying to use AJAX/JQUERY so that it will post with no page refresh. I am following this railscasts tutorial.
So right now, the posts are made to my database and the page does not refresh. But when I refresh, the posts shows up. The page that I render my comments for a specific project is on the projects/_comments.html.erb.
Question: How would I adjust it so that it the new comment made renders?
newcomments_controller.rb
def create
#newcomment = #commentable.newcomments.new(params[:newcomment])
if #newcomment.save
respond_to do |format|
format.html { redirect_to comments_project_path(#commentable) }
format.js
end
else
render :new
end
end
view/newcomments/_form.html.erb
<span class="comment">
<%= form_for [#commentable, #newcomment], remote: true do |f| %>
<%= f.text_area :content, rows: 3, :class => "span8" %>
<%= f.hidden_field :user_id, :value => current_user.id %>
<%= f.submit "Add Comment", :class => "btn btn-header" %>
<% end %>
</span>
view/newcomments/create.js.erb
$('#newcomment').append('<%= j render(#newcomments) %>');
projects_controller.rb
def comments
#commentable = #project
#newcomments = #commentable.newcomments.newest.page(params[:comments_page]).per_page(10)
#newcomment = Newcomment.new
respond_to do |format|
format.html # show.html.erb
format.json { render json: #project.comments }
end
end
projects/comments.html.erb
<%= render 'comments' %>
projects/_comments.html.erb
<%= render #newcomments %>
view/newcomments/_newcomment.html.erb
<div class="comments">
<%= link_to newcomment.user.name %></strong>
Posted <%= time_ago_in_words(newcomment.created_at) %> ago
<%= newcomment.content %>
</div>
<span class="comment">
<%= form_for [#commentable, #newcomment] do |f| %>
<div class="field">
<%= f.text_area :content, rows: 3, :class => "span8" %>
</div>
<%= f.hidden_field :user_id, :value => current_user.id %>
<div class="actions">
<%= f.submit "Add Comment", :class => "btn btn-header" %>
</div>
<% end %>
<% unless newcomment.newcomments.empty? %>
<%= render #newcomments %>
<% end %>
</span>
Try binding AJAX actions as described here:
http://www.alfajango.com/blog/rails-3-remote-links-and-forms/
Also, consider returning a render comments partial html instead of json comment object, to do so you need to tell in form after :remote directive that :'data-type'=>'html', so that returned html will hit function binded on AJAX success, and then swap html of container div with, for example, jQuery

retrieving multiple model objects from rails partial form

I have the below form working as a partial, i'm trying to do a partial call for a Contractors models and i want to also pass the current page's model id which is a quote id.
Its failing on this line <%= hidden_field_tag :quote_id, #quote.id %> 'called id for nil'
I've tried creating a manual route and putting the search on a seperate method, but then i get a template error so i'm just leaving it in the index method for now.
Form in show.html.erb:
<%= form_tag quotes_path, :method => 'get', :id => "contractors_search" do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", :name => nil %>
</p>
<br><br><br>
<div id="contractors"><%= render 'contractors' %></div>
<% end %>
_contractors.html.erb
<table>
<% #contractors.each do | contractor | %>
<tr>
<td><%= contractor.firstname %></td>
<td>
<%= form_tag (quote_add_contractor_path) do %>
<%= hidden_field_tag :quote_id, #quote.id %>
<%= hidden_field_tag :contractor_id, contractor.id %>
<%= submit_tag "Add" %>
<% end %>
</td>
</tr>
<% end %>
</table>
Index.js.erb
$("#contractors").html("<%= escape_javascript(render :partial => "contractors") %>");
Controller:
def index
#quotes = Quote.all
#contractors = Contractor.search(params[:search])
end
def add_contractor
#quote = Quote.find(params[:quote_id])
#contractor = Contractor.find(params[:contractor_id])
#quote.contractors << #contractor
if #quote.save
redirect_to #quote, notice: "contractor was added"
else
render :show, notice: "Sorry, something went aweful"
end
end
In index.js.erb you render the partial contractors but you do not set the #quote instance variable in your index action of the controller. That is why you are getting this failure. Try to add #quote = # Some logic here to your index action.

Resources