How to use ajax on rails 4? - ruby-on-rails

I am trying to create a comment area in rails 4 using ajax. My target is to create comment and its output in same page without page loading. I have added some code. When i click on "add comment" button the data entered to DB, but does not reflect in same page.Please share with me if any one have any idea, thank u.
My codes are below:
In comment controller:
def create
#article = Article.find(params[:article_id])
#comment = #article.comments.create
#comment.body = params[:comment]["body"]
respond_to do |format|
#comment.save
format.html { redirect_to #article }
format.js
end
end
In show.html.erb under views/articles
<div class="col-xs-12 col-sm-12">
<h2 class="text-center"><%= #article.title.html_safe %></h2>
<p><%= #article.body.html_safe %></p>
<h2>Comments</h2>
<div id="comments">
<!-- <p><%= render :partial => #article.comments %></p> -->
<%= render :partial => 'comments/comment', :collection => #article.comments %>
</div>
<%= form_for([#article, Comment.new], :remote => true) do |f| %>
<p>
<%= f.label :body, "New comment" %><br/>
<%= f.text_area :body, type:"text", tabindex: "6", class: "form-control", placeholder: 'your comment', rows: "4", required: true %>
</p>
<p><%= f.submit "Add comment" %></p>
<% end %>
</div>
_comment.html.erb under view/comments
<%= div_for comment do %>
<p>
<b>
Posted <%= time_ago_in_words(comment.created_at) %> ago
</b>
<br/>
<%= comment.body %>
<%= link_to 'Delete', article_comment_path(comment.article_id, comment.id), method: :Delete, :class => 'btn btn-sm btn-warning', tabindex: "3" %>
<%= link_to 'Edit', article_path(comment.article_id, comment.id), :class => 'btn btn-sm btn-warning', tabindex: "3" %>
</p>
<% end %>
create.js.erb under views/comments
page.insert_html :bottom, :comments, :partial => 'comment', :object => #comment
page[:new_comment].reset
config/application.rb
config.action_view.JavaScript_expansions[:defaults] = %w(jquery rails application)

the proper way to handle this case in rails is using a remote form, this way you can interactively insert and remove objects from db.
Here are two explained blog posts about remote forms in rails detailed guide about remote forms and how to partials ajax rails. This way you can submit the form without refresh an then have an handler to generate the created element after the callback from the controller.
Hope this fits your question.

Added something like:
create.js.erb under views/comments
$("#comments").append("<%= escape_javascript(render(:partial => #comment)) %>");
$("#new_comment")[0].reset();
And It works for me.

Related

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

blank comment entry with rails

I'm trying to add ability to add comments to projects within a "todo" type app and have run into a problem.
I've created a project with comments before and never run into this problem, but basically rails is drawing an empty comment on the project page.
I've tried a few if statements without any luck, does anyone see my problem ?
<% #project.comments.each do |comment| %>
<div class="commentBlock"><strong><%= comment.posted_by %> says:</strong>
<%=raw comment.comment %>
<small><i class="icon-remove"></i> <%= link_to 'Delete', [comment.project, comment],:confirm => 'Are you sure?',:method => :delete %></small></div>
<% end %>
<h3>Leave a comment</h3>
<%= form_for([#project, #project.comments.build]) do |f| %>
<div class="field">
<%= f.hidden_field :posted_by, :value => current_user.username %>
</div>
<div class="field">
<%= f.label :comment %><br />
<%= f.text_area :comment, :class => "tinymce" %><%= tinymce %>
</div>
<p><%= f.submit :class => 'btn' %></p>
<% end %>
Answer was an error in my controller for Projects, referenced #comment like so:
#comment = #project.comments.build(params[:comment]) by accident!!
Changed to:
#comment = #project.comments
And all works as it should :P
thanks for your help, bad "end of the day" error right there :P

How to render a "Edit" form partial in the "Show" page of another model in Rails

I want to display an "Edit" form in the "Show" view of a parent object.
My model looks like this:
A Trip has many Days which has many Activities.
Trip accepts nested attributes for Days. Days accepts nested Attributes for Activities.
When I am in the "Show" view for a Trip, how do I render an "Edit" form partial for an "Activity"?
I know I need to somehow specify to the Edit Form partial which Activity ID that I want to edit but I'm not sure how to pass along that information from the "Show" view of a "Trip".
<% #trip.days.each do |day| %>
<div id="daydiv_<%= day.id %>">
<b><%= day.summary %></b>
<%= content_tag_for :ol, day do %>
<% day.activities.each do |activity| %>
<li id="activity_<%= activity.id %>"><%= link_to activity.address, edit_activity_path(activity) %></li>
<% end %>
<% end %>
</div>
<% end %>
<div id="activity_form">
<%= render :partial => "/activities/form", :activity => #activity %>
</div>
my /activities/form partial looks like this:
<%= form_for(#activity) do |f| %>
<div class="field">
<%= f.label :title %><br />
<%= f.text_field :title %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
This is what I ended up doing and it works.
In my show.html.erb for my "Trip".
show.html.erb
<div id="activity_form">
<h2>Activities</h2>
</div>
link to "Edit' an Activity. Notice the :remote => true which tells the Rails controller that this will be an AJAX request so to render edit.js.erb
<%= link_to activity.location[0, 20], edit_day_activity_path(day, activity), :class=>"btn btn-info fixedwidthbtn", method: :get, :remote => true
_form.html.erb This form partial is under the Activities View directory (../views/activities/_form.html.erb).
<%= form_for([#day, #activity], :remote => true) do |f| %>
<fieldset>
<%= f.label :title, "Activity" %>
<%= f.text_field :title, :rows => 1 %>
</fieldset>
<div class="actions">
<%= f.submit %>
</div>
</form>
<%= link_to 'Delete', [#day, #activity], method: :delete, data: { confirm: 'Are you sure?' } %>
<% end %>
edit.js.erb This is a file under the Activities view directory (../views/activities/edit.js.erb). Says to grab the DOM element with ID of "activity_form" and render the partial "form"
$("#activity_form").html("<%= escape_javascript(render(:partial => "form"))%>");
update.js.erb I included this javascript after hitting update on the Edit form to render an updated partial of the Activities List. So that I don't have to reload the page to see an update.
$("#activities_list").html("<%= escape_javascript( render(:partial => "/trips/activities") ) %>");
routes.rb This is how I nest my routes. Only doing it 1 level following best practices.
resources :trips do
resources :days
end
resources :days do
resources :activities
end

No route matches when trying to edit

Here's the scoop: I've created a test app that allows users to create ideas and then add "bubbles" to these ideas. Currently, a bubble is just text. I've successfully linked bubbles to ideas. Furthermore, when a user goes to view an idea it lists all of the bubbles attached to that idea. The user can even delete the bubble for a given idea.
My problem lies in editing bubbles. When a user views an idea, he sees the idea's content as well as any bubbles for that idea. As a result, I've set all my bubble controls (editing and deleting) inside the ideas "show" view. My code for editing a bubble for an idea is <%= link_to 'Edit Bubble', edit_idea_bubble_path %>. I ran rake routes to find the correct path for editing bubbles and that is what was listed.
Here's my error: No route matches {:action=>"edit", :controller=>"bubbles"}
In my bubbles controller I have:
def edit
#idea = Idea.find(params[:idea_id])
#bubble = #idea.bubbles.find(params[:id])
end
def update
#idea = Idea.find(params[:idea_id])
#bubble = #idea.bubbles.find(params[:id])
respond_to do |format|
if #bubble.update_attributes(params[:bubble])
format.html { redirect_to(#bubble,
:notice => 'Bubble was successfully updated.') }
format.xml { head :ok }
else
format.html { render :action => "Edit" }
format.xml { render :xml => #bubble.errors,
:status => :unprocessable_entity }
end
end
end
To go a step further, I have the following in my routes.rb file
resources :ideas do
resources :bubbles
end
So far everything seems to function except when I try to edit a bubble.
I'd love some guidance.
Thanks!
Here's my show.html.erb file for Ideas:
<h2>Bubbles</h2>
<% #idea.bubbles.each do |bubble| %>
<p>
<b>Bubble:</b>
<%= bubble.description %>
</p>
<p>
<%= link_to 'Edit Bubble', edit_idea_bubble_path (#idea) %>
</p>
<tb />
<p>
<%= link_to 'Delete Bubble', [bubble.idea, bubble],
:confirm => 'Are you sure you want to delete this bubble?',
:method => :delete %>
</p>
<% end %>
<h2>Add a bubble:</h2>
<%= form_for([#idea, #idea.bubbles.build]) do |f| %>
<div class="field">
<%= f.label :description %><br />
<%= f.text_area :description %>
</div>
<div class="actions">
<%= f.submit %> </div><% end %>
Following edit_idea_bubble_path (#idea), here is the edit.html.erb file for Bubbles:
<%= render 'form' %>
<%= link_to 'Back to Ideas', ideas_path %>
And finally, my _form.html.erb file for Bubbles: this is where the problem lies, I believe
<% form_for([#idea, #idea.bubbles.build]) do |f| %>
<%= f.error_messages %>
<div class="field">
<%= f.label :description %><br />
<%= f.text_area :description %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
First build the route in your show.html.erb file
<%= link_to 'Edit Bubble', edit_idea_bubble_path(#idea, bubble) %>
Then, your controller should have 2 objects for both #idea and #bubble
when action is new
#idea = Idea.find_by_id(:params[:idea_id])
#bubble = #idea.bubbles.build
when action is edit
#idea = Idea.find_by_id(:params[:idea_id])
#bubble = #idea.bubbles.find_by_id(:params[:bubble_id])
In your _form.html.erb
<% form_for([#idea, #bubble]) do |f| %>
You have to provide the idea and the bubble objects:
<%= link_to 'Edit Bubble', edit_idea_bubble_path(#idea,#bubble) %>
Update:
Edit the _form.html.erb file
<% form_for([#idea, #bubble]) do |f| %>

Ajax Question - Ruby on Rails - Error: Couldn't Find Post without an ID

Ok, I am new to rails so I hope I explain this well. I seem to have a problem with a form collecting the proper information. Work in one spot and not another. Here is the situation.
I have created a blog with three tables, posts, comments, and votes. I have comments working correctly and votes working partially. Here is what I mean.
The /posts/show.html.erb file basically shows the post, the associated comments and it shows how many votes that post has. I am working the votes but using a form with a hidden field that delivers a value of '1' along with the post_id to the table. I am then using AJAX to return the #post.votes.count. This all works great.
I am trying to use this same vote/return mentioned above but on the /posts/index.html.erb page. In the index page I have the <% #post.each do |post| %> doing two things. First render :partial => post %> and then I have the same code that I am using on the show.html.erb page. The error that I am getting from the terminal is
ActiveRecord::RecordNotFound (Couldn't find Post without an ID):
app/controllers/votes_controller.rb:4:in `create'
I am guessing this has to do with it being part of the index record set which doesn't have a unique post param associated with the page. I am hoping there is a simple fix. Here is the code:
This is the /posts/show.html.erb code that is working correctly:
<div id="backto"<%= link_to 'Back to all BattleCries', posts_path %>
</div>
<%= render :partial => #post %>
<div id="beltcomments">
<div id="beltcommenttext">
<div id="vote">
<div id="votes">
<%= #post.votes.count %> People liked this BattleCry.
</div>
</div>
<div id="votebutton">
<% remote_form_for [#post, Vote.new] do |f| %>
<%= f.hidden_field :vote, :value => '1' %>
<%= f.submit "Like" %>
<% end %>
</div>
</div>
</div>
<div id="beltcommentsbottom">
</div><br/><br/>
<div id="belt">
<div id="belttext">
<p5>Add a Comment</p5>
<% remote_form_for [#post, Comment.new] do |f| %>
<p>
<%= f.text_area ( :body, :class => "commentarea") %>
</p>
<%= f.submit "Add Comment"%>
<% end %>
</div>
<div id="beltbottom">
</div>
</div><br/>
<div id="comments">
<%= render :partial => #post.comments %>
</div>
<br/>
<div id="commenttime">
Copyright 2009, My Life BattleCry, LLC.
</div>
<br/>
<br/>
<br/>
Here is where it is in the index page:
<% #posts.each do |post| %>
<%= render :partial => post %>
<%= render :partial => #post %>
<div id="beltcomments">
<div id="beltcommenttext">
<div id="vote">
<div id="votes">
<%= post.votes.count %> People liked this BattleCry.
</div>
<%= link_to "Comments (#{post.comments.count})", post %>
</div>
<div id="votebutton">
<% remote_form_for [#post, Vote.new] do |f| %>
<%= f.hidden_field :vote, :value => '1' %>
<%= f.submit "Like" %>
<% end %>
</div>
</div>
</div>
<br/>
<br/>
<br/>
<% end %>
<div id="commenttime">
Copyright 2009, My Life BattleCry, LLC.
</div>
<br/>
<br/>
<br/>
Here is the votes_controller.rb
class VotesController < ApplicationController
def create
#post = Post.find(params[:post_id])
#vote = #post.votes.create!(params[:vote])
respond_to do |format|
format.html { redirect_to #post}
format.js
end
end
end
Here is the /votes/create.js
page.replace_html :votes, :partial => #vote
page[#vote].visual_effect :highlight
Lastly, here is the partial, /_vote.html.erb:
page.replace_html :votes, :partial => #vote
page[#vote].visual_effect :highlight
I hope this makes sense. Let me know if I need to clarify anything.
I imagine this is causing problems. You didn't post your posts controller, but does the index action set #post?:
<%= render :partial => #post %>
Looks like I just needed to change the following in the <% #posts.each do |post| %> section of the index.html.erb file.
<% remote_form_for [#post, Vote.new] do |f| %>
<%= f.hidden_field :vote, :value => '1' %>
<%= f.submit "Like" %>
to
<% remote_form_for [post, Vote.new] do |f| %>
<%= f.hidden_field :vote, :value => '1' %>
<%= f.submit "Like" %>

Resources