Jakub Kopyś
Jakub Kopyś

Reputation: 710

Rails AJAX comments clear textarea

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. enter image description here

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

Answers (2)

x6iae
x6iae

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

Jakub Kopyś
Jakub Kopyś

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

Related Questions