Reputation: 710
I am adding AJAX comments on my web app, but I have no idea how to make textarea (where I wrote comment on) clear after adding comment. Additionally I am struggling to display errors when using AJAX.
My comment controller:
def create
@user = User.find(params[:user_id])
@guide = Guide.find(params[:guide_id])
@comment = @guide.comments.build(comment_params)
if @comment.valid?
@comment.user = current_user
@comment.save
respond_to do |format|
format.html {
flash[:notice] = "Comment added!"
redirect_to :back
}
format.js
end
else
flash[:danger] = "Comment must be 4 to 200 letters long"
redirect_to :back
end
end
end
JS file (create.js.erb):
$(".comments").html("<%= escape_javascript(render @guide.comments) %>);
View (guide/show.html.erb):
...
<div class="add_comment">
<%= form_for [@user, @guide, Comment.new], remote: true do |f| %>
<p>
<%= f.text_area :body %>
</p>
<p><%= f.submit "Add comment" %></p>
<% end %>
</div>
<div class="comments">
<%= render @guide.comments %>
</div>
And my comment partial (_comment.html.erb):
<%= div_for comment do %>
<div id="comment">
<%= link_to image_tag(comment.user.avatar(:small)), comment.user %>
<small><%= link_to " #{comment.user.username }", comment.user %> <%= time_ago_in_words(comment.created_at) %> ago.
<% if comment.user == current_user || current_user.admin? %>
<%= link_to "Delete", user_guide_comment_path(comment.user, comment.guide, comment), method: :delete, data: { confirm: "Are you sure?"} %>
<% end %>
</small>
<br/>
<span><%= comment.body %></span>
</div>
<% end %>
To clearify - I want the area of adding new comment "AJAX TEST COMMENT" to clear itself after clicking submit and adding the comment and additionally any sugestions how to display error with AJAX would be appreciated.
EDIT: Yeah - the code does add new comment and renders all comments via ajax without refreshing the whole page.
Started POST "/users/1/guides/103/comments" for 127.0.0.1 at 2015-12-06 11:59:53 +0100
Processing by CommentsController#create as JS
Parameters: {"utf8"=>"✓", "comment"=>{"body"=>"AJAX ANOTHER TEST COMMENT - IT IS WORKING"}, "commit"=>"Add comment", "user_id"=>"1", "guide_id"=>"103"}
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
Guide Load (0.1ms) SELECT "guides".* FROM "guides" WHERE "guides"."id" = ? LIMIT 1 [["id", 103]]
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
(0.1ms) begin transaction
SQL (0.2ms) INSERT INTO "comments" ("body", "guide_id", "user_id", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?) [["body", "AJAX ANOTHER TEST COMMENT - IT IS WORKING"], ["guide_id", 103], ["user_id", 1], ["created_at", "2015-12-06 10:59:53.334245"], ["updated_at", "2015-12-06 10:59:53.334245"]]
(42.3ms) commit transaction
Comment Load (0.1ms) SELECT "comments".* FROM "comments" WHERE "comments"."guide_id" = ? ORDER BY "comments"."created_at" DESC [["guide_id", 103]]
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 2]]
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 4]]
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 4]]
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
Rendered comments/_comment.html.erb (13.8ms)
Rendered comments/create.js.erb (15.8ms)
Completed 200 OK in 65ms (Views: 17.1ms | ActiveRecord: 43.3ms)
Upvotes: 2
Views: 677
Reputation: 4164
Refactor your create
method in your controller as follow:
def create
@user = User.find(params[:user_id])
@guide = Guide.find(params[:guide_id])
@comment = @guide.comments.build(comment_params)
@comment.user = current_user
@comment.save
respond_to do |format|
format.html {
flash[:notice] = "Comment added!"
redirect_to :back
}
format.js
end
end
Here, the error is not being handled in the controller, we will go ahead to do this in the create.js.erb
file, and display the flash as follow:
$(".comments").html("<%= escape_javascript(render @guide.comments) %>");
$('#comment_body').val('');
<% if @comment.errors.empty? %>
$("#notice").html("Comment was successfully posted.");
<% else %>
$("#notice").html("Error! Comment not posted.");
<% end %>
This is assuming that you have the #notice
div on the page - (this is usually present on every rails app page, since it comes from application.html.erb
This same approach can be used to append the errors in @comment
to the page from the create.js.erb
Upvotes: 1
Reputation: 710
Well I managed to clear the textarea by simply adding:
$(".comments").html("<%= escape_javascript(render @guide.comments) %>");
$('#comment_body').val('');
Now there is only second problem left - how to display errors, flash[messages] etc via ajax? I think It is worth mentioning I have partial for error messages (_error_messages.html.erb):
<% if object.errors.any? %>
<div id="error_explanation">
<div class="alert">
The form contains <%= pluralize(object.errors.count, "error") %>.
</div>
<ul>
<% object.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
Upvotes: 0